diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index 8256832fb6ddac4574c5f04ce0a755aa02a97e6a..b74aa51513cfdfac243ae048a72a889e9c176723 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -1477,6 +1477,8 @@ module Contract : sig | Implicit of Signature.Public_key_hash.t | Originated of Contract_hash.t + type error += Non_existing_contract of t + include BASIC_DATA with type t := t val originated_encoding : Contract_hash.t Data_encoding.t diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index cb7a1cd95d455e24ce4938ba70c7c24b36c88b2c..32df61a1941ba5cfab5409eee6891a59ae8a267c 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -855,8 +855,7 @@ let apply_transaction_to_implicit ~ctxt ~contract ~parameter ~entrypoint let apply_transaction_to_smart_contract ~ctxt ~source ~contract ~amount ~entrypoint ~before_operation ~payer ~chain_id ~mode ~internal ~script_ir - ~script ~parameter ~cache_key ~balance_updates - ~allocated_destination_contract = + ~script ~parameter ~cache_key ~balance_updates = (* Token.transfer which is being called before already loads this value into the Irmin cache, so no need to burn gas for it. *) Contract.get_balance ctxt contract >>=? fun balance -> @@ -931,35 +930,52 @@ let apply_transaction_to_smart_contract ~ctxt ~source ~contract ~amount storage_size = new_size; paid_storage_size_diff = Z.add contract_paid_storage_size_diff ticket_paid_storage_diff; - allocated_destination_contract; + allocated_destination_contract = false; }) in (ctxt, result, operations) ) let apply_transaction ~ctxt ~parameter ~source ~(contract : Contract.t) ~amount ~entrypoint ~before_operation ~payer ~chain_id ~mode ~internal = - (match contract with - | Originated _ -> - (if Tez.(amount = zero) then - (* Detect potential call to non existent contract. *) - Contract.must_exist ctxt contract - else return_unit) - >>=? fun () -> + match contract with + | Originated _ -> ( (* Since the contract is originated, nothing will be allocated - or the next transfer of tokens will fail. *) - return_false + or this transfer of tokens will fail. + Calls to non-existing contracts are detected by [Script_cache.find] + returning [None] because [Token.transfer] will succeed on non-existing + contracts if the amount is zero. + *) + Token.transfer ctxt (`Contract source) (`Contract contract) amount + >>=? fun (ctxt, balance_updates) -> + Script_cache.find ctxt contract >>=? fun (ctxt, cache_key, script) -> + match script with + | None -> fail (Contract.Non_existing_contract contract) + | Some (script, script_ir) -> + apply_transaction_to_smart_contract + ~ctxt + ~source + ~contract + ~amount + ~entrypoint + ~before_operation + ~payer + ~chain_id + ~mode + ~internal + ~script_ir + ~script + ~parameter + ~cache_key + ~balance_updates) | Implicit _ -> (* Transfers of zero to implicit accounts are forbidden. *) error_when Tez.(amount = zero) (Empty_transaction contract) >>?= fun () -> (* If the implicit contract is not yet allocated at this point then the next transfer of tokens will allocate it. *) - Contract.allocated ctxt contract >|= ok >|=? not) - >>=? fun allocated_destination_contract -> - Token.transfer ctxt (`Contract source) (`Contract contract) amount - >>=? fun (ctxt, balance_updates) -> - Script_cache.find ctxt contract >>=? fun (ctxt, cache_key, script) -> - match script with - | None -> + Contract.allocated ctxt contract >>= fun already_allocated -> + Token.transfer ctxt (`Contract source) (`Contract contract) amount + >>=? fun (ctxt, balance_updates) -> + let allocated_destination_contract = not already_allocated in apply_transaction_to_implicit ~ctxt ~contract @@ -969,24 +985,6 @@ let apply_transaction ~ctxt ~parameter ~source ~(contract : Contract.t) ~amount ~balance_updates ~allocated_destination_contract >>?= fun (ctxt, result) -> return (ctxt, result, []) - | Some (script, script_ir) -> - apply_transaction_to_smart_contract - ~ctxt - ~source - ~contract - ~amount - ~entrypoint - ~before_operation - ~payer - ~chain_id - ~mode - ~internal - ~script_ir - ~script - ~parameter - ~cache_key - ~balance_updates - ~allocated_destination_contract let ex_ticket_size : context -> Ticket_scanner.ex_ticket -> (context * int) tzresult Lwt.t = @@ -1157,18 +1155,17 @@ let apply_internal_manager_operation_content : payer:public_key_hash -> source:Contract.t -> chain_id:Chain_id.t -> - gas_consumed_in_precheck:Gas.cost option -> kind Script_typed_ir.manager_operation -> (context * kind successful_manager_operation_result * Script_typed_ir.packed_internal_operation list) tzresult Lwt.t = - fun ctxt mode ~payer ~source ~chain_id ~gas_consumed_in_precheck operation -> + fun ctxt mode ~payer ~source ~chain_id operation -> prepare_apply_manager_operation_content ~ctxt ~source - ~gas_consumed_in_precheck + ~gas_consumed_in_precheck:None >>=? fun (ctxt, before_operation, consume_deserialization_gas) -> match operation with | Transaction_to_contract @@ -1181,22 +1178,19 @@ let apply_internal_manager_operation_content : parameters_ty; parameters = typed_parameters; } -> - apply_transaction - ~ctxt - ~parameter:(Typed_arg (location, parameters_ty, typed_parameters)) - ~source - ~contract:destination - ~amount - ~entrypoint - ~before_operation - ~payer - ~chain_id - ~mode - ~internal:true - >|=? fun (ctxt, manager_result, operations) -> - ( ctxt, - (manager_result : kind successful_manager_operation_result), - operations ) + (apply_transaction + ~ctxt + ~parameter:(Typed_arg (location, parameters_ty, typed_parameters)) + ~source + ~contract:destination + ~amount + ~entrypoint + ~before_operation + ~payer + ~chain_id + ~mode + ~internal:true + : (_ * kind successful_manager_operation_result * _) tzresult Lwt.t) | Transaction_to_tx_rollup {destination; unparsed_parameters = _; parameters_ty; parameters} -> apply_transaction_to_tx_rollup @@ -1797,7 +1791,6 @@ let apply_internal_manager_operations ctxt mode ~payer ~chain_id ops = ~source ~payer ~chain_id - ~gas_consumed_in_precheck:None operation) >>= function | Error errors -> diff --git a/tests_python/tests_alpha/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_success[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b.7da5c9014e.out b/tests_python/tests_alpha/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_success[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b.7da5c9014e.out index 5d58854866cc7223e2ea771df8c2490f177a8f09..61bb45fd388bb0f6f94362c0754c7fb9c14a8fc9 100644 --- a/tests_python/tests_alpha/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_success[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b.7da5c9014e.out +++ b/tests_python/tests_alpha/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_slice_success[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b.7da5c9014e.out @@ -1,7 +1,7 @@ tests_alpha/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_slice_success[(Pair 0xe009ab79e8b84ef0e55c43a9a857214d8761e67b75ba63500a5694fb2ffe174acc2de22d01ccb7259342437f05e1987949f0ad82e9f32e9a0b79cb252d7f7b8236ad728893f4e7150742eefdbeda254970f9fcd92c6228c178e1a923e5600758eb83f2a05edd0be7625657901f2ba81eaf145d003dbef78e33f43a32a3788bdf0501000000085341554349535345 "spsig1PPUFZucuAQybs5wsqsNQ68QNgFaBnVKMFaoZZfi1BtNnuCAWnmL9wVy5HfHkR6AeodjVGxpBVVSYcJKyMURn6K1yknYLm")] Node is bootstrapped. -Estimated gas: 4049.458 units (will add 100 for safety) +Estimated gas: 3599.458 units (will add 100 for safety) Estimated storage: 257 bytes added (will add 20 for safety) Operation successfully injected in the node. Operation hash is '[BLOCK_HASH]' @@ -12,13 +12,13 @@ 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.000922 + Fee to the baker: ꜩ0.000877 Expected counter: [EXPECTED_COUNTER] - Gas limit: 4150 + Gas limit: 3700 Storage limit: 277 bytes Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000922 - payload fees(the block proposer) ....... +ꜩ0.000922 + [CONTRACT_HASH] ... -ꜩ0.000877 + payload fees(the block proposer) ....... +ꜩ0.000877 Transaction: Amount: ꜩ0 From: [CONTRACT_HASH] @@ -36,7 +36,7 @@ This sequence of operations was run: From: [CONTRACT_HASH] To: [CONTRACT_HASH] This transaction was successfully applied - Consumed gas: 1450 + Consumed gas: 1000 Balance updates: [CONTRACT_HASH] ... -ꜩ1000 [CONTRACT_HASH] ... +ꜩ1000 diff --git a/tests_python/tests_alpha/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_store_input.out b/tests_python/tests_alpha/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_store_input.out index 7a2d10175ba3642330738d90a4e1f171c8027d54..a9e861c6a2892d558e544f8a7c4d3e5c4d46a1e1 100644 --- a/tests_python/tests_alpha/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_store_input.out +++ b/tests_python/tests_alpha/_regtest_outputs/test_contract_onchain_opcodes.TestContractOnchainOpcodes::test_store_input.out @@ -1,7 +1,7 @@ tests_alpha/test_contract_onchain_opcodes.py::TestContractOnchainOpcodes::test_store_input Node is bootstrapped. -Estimated gas: 1450.040 units (will add 0 for safety) +Estimated gas: 1000.040 units (will add 0 for safety) Estimated storage: 257 bytes added (will add 20 for safety) Operation successfully injected in the node. Operation hash is '[BLOCK_HASH]' @@ -12,19 +12,19 @@ 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.000399 + Fee to the baker: ꜩ0.000354 Expected counter: [EXPECTED_COUNTER] - Gas limit: 1451 + Gas limit: 1001 Storage limit: 277 bytes Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000399 - payload fees(the block proposer) ....... +ꜩ0.000399 + [CONTRACT_HASH] ... -ꜩ0.000354 + payload fees(the block proposer) ....... +ꜩ0.000354 Transaction: Amount: ꜩ1000 From: [CONTRACT_HASH] To: [CONTRACT_HASH] This transaction was successfully applied - Consumed gas: 1450.040 + Consumed gas: 1000.040 Balance updates: [CONTRACT_HASH] ... -ꜩ1000 [CONTRACT_HASH] ... +ꜩ1000 @@ -33,7 +33,7 @@ This sequence of operations was run: Injected block at minimal timestamp Node is bootstrapped. -Estimated gas: 1450.040 units (will add 0 for safety) +Estimated gas: 1000.040 units (will add 0 for safety) Estimated storage: 257 bytes added (will add 20 for safety) Operation successfully injected in the node. Operation hash is '[BLOCK_HASH]' @@ -44,19 +44,19 @@ 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.000399 + Fee to the baker: ꜩ0.000354 Expected counter: [EXPECTED_COUNTER] - Gas limit: 1451 + Gas limit: 1001 Storage limit: 277 bytes Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000399 - payload fees(the block proposer) ....... +ꜩ0.000399 + [CONTRACT_HASH] ... -ꜩ0.000354 + payload fees(the block proposer) ....... +ꜩ0.000354 Transaction: Amount: ꜩ2000 From: [CONTRACT_HASH] To: [CONTRACT_HASH] This transaction was successfully applied - Consumed gas: 1450.040 + Consumed gas: 1000.040 Balance updates: [CONTRACT_HASH] ... -ꜩ2000 [CONTRACT_HASH] ... +ꜩ2000 diff --git a/tests_python/tests_alpha/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_remove_liquidity.out b/tests_python/tests_alpha/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_remove_liquidity.out index eb871abe59cba49c3bdf85da6c792ce091359cf9..8a533d9b9dfa9518281c434c610142b16c6f1683 100644 --- a/tests_python/tests_alpha/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_remove_liquidity.out +++ b/tests_python/tests_alpha/_regtest_outputs/test_liquidity_baking.TestAddApproveTransferRemove::test_remove_liquidity.out @@ -1,7 +1,7 @@ tests_alpha/test_liquidity_baking.py::TestAddApproveTransferRemove::test_remove_liquidity Node is bootstrapped. -Estimated gas: 7972.902 units (will add 100 for safety) +Estimated gas: 7522.902 units (will add 100 for safety) Estimated storage: 67 bytes added (will add 20 for safety) Operation successfully injected in the node. Operation hash is '[BLOCK_HASH]' @@ -12,13 +12,13 @@ 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.00116 + Fee to the baker: ꜩ0.001115 Expected counter: [EXPECTED_COUNTER] - Gas limit: 8073 + Gas limit: 7623 Storage limit: 87 bytes Balance updates: - [CONTRACT_HASH] ... -ꜩ0.00116 - payload fees(the block proposer) ....... +ꜩ0.00116 + [CONTRACT_HASH] ... -ꜩ0.001115 + payload fees(the block proposer) ....... +ꜩ0.001115 Transaction: Amount: ꜩ0 From: [CONTRACT_HASH] @@ -72,7 +72,7 @@ This sequence of operations was run: From: [CONTRACT_HASH] To: [CONTRACT_HASH] This transaction was successfully applied - Consumed gas: 1450 + Consumed gas: 1000 Balance updates: [CONTRACT_HASH] ... -ꜩ125.105747 [CONTRACT_HASH] ... +ꜩ125.105747 diff --git a/tests_python/tests_alpha/_regtest_outputs/test_liquidity_baking.TestTrades::test_buy_tok.out b/tests_python/tests_alpha/_regtest_outputs/test_liquidity_baking.TestTrades::test_buy_tok.out index 4072b33b4984326bf03ff61d8fa5de38d79008d2..1989244985c0f2d1711e6ec7966ba3447e710be5 100644 --- a/tests_python/tests_alpha/_regtest_outputs/test_liquidity_baking.TestTrades::test_buy_tok.out +++ b/tests_python/tests_alpha/_regtest_outputs/test_liquidity_baking.TestTrades::test_buy_tok.out @@ -1,7 +1,7 @@ tests_alpha/test_liquidity_baking.py::TestTrades::test_buy_tok Node is bootstrapped. -Estimated gas: 5568.103 units (will add 100 for safety) +Estimated gas: 5118.103 units (will add 100 for safety) Estimated storage: 326 bytes added (will add 20 for safety) Operation successfully injected in the node. Operation hash is '[BLOCK_HASH]' @@ -12,13 +12,13 @@ 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.000914 + Fee to the baker: ꜩ0.000869 Expected counter: [EXPECTED_COUNTER] - Gas limit: 5669 + Gas limit: 5219 Storage limit: 346 bytes Balance updates: - [CONTRACT_HASH] ... -ꜩ0.000914 - payload fees(the block proposer) ....... +ꜩ0.000914 + [CONTRACT_HASH] ... -ꜩ0.000869 + payload fees(the block proposer) ....... +ꜩ0.000869 Transaction: Amount: ꜩ9001 From: [CONTRACT_HASH] @@ -65,7 +65,7 @@ This sequence of operations was run: From: [CONTRACT_HASH] To: [CONTRACT_HASH] This transaction was successfully applied - Consumed gas: 1450 + Consumed gas: 1000 Balance updates: [CONTRACT_HASH] ... -ꜩ9.001 [CONTRACT_HASH] ... +ꜩ9.001 diff --git a/tests_python/tests_alpha/_regtest_outputs/test_liquidity_baking.TestTrades::test_sell_tok.out b/tests_python/tests_alpha/_regtest_outputs/test_liquidity_baking.TestTrades::test_sell_tok.out index e4463c8b023c556b4810f07e85f05466bf067262..5e885f17fc4f139639faa21880ed7108c6b5f31b 100644 --- a/tests_python/tests_alpha/_regtest_outputs/test_liquidity_baking.TestTrades::test_sell_tok.out +++ b/tests_python/tests_alpha/_regtest_outputs/test_liquidity_baking.TestTrades::test_sell_tok.out @@ -1,7 +1,7 @@ tests_alpha/test_liquidity_baking.py::TestTrades::test_sell_tok Node is bootstrapped. -Estimated gas: 7916.814 units (will add 100 for safety) +Estimated gas: 7016.814 units (will add 100 for safety) Estimated storage: no bytes added Operation successfully injected in the node. Operation hash is '[BLOCK_HASH]' @@ -12,13 +12,13 @@ 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.001147 + Fee to the baker: ꜩ0.001057 Expected counter: [EXPECTED_COUNTER] - Gas limit: 8017 + Gas limit: 7117 Storage limit: 0 bytes Balance updates: - [CONTRACT_HASH] ... -ꜩ0.001147 - payload fees(the block proposer) ....... +ꜩ0.001147 + [CONTRACT_HASH] ... -ꜩ0.001057 + payload fees(the block proposer) ....... +ꜩ0.001057 Transaction: Amount: ꜩ0 From: [CONTRACT_HASH] @@ -57,7 +57,7 @@ This sequence of operations was run: From: [CONTRACT_HASH] To: [CONTRACT_HASH] This transaction was successfully applied - Consumed gas: 1450 + Consumed gas: 1000 Balance updates: [CONTRACT_HASH] ... -ꜩ3891.966034 [CONTRACT_HASH] ... +ꜩ3891.966034 @@ -66,7 +66,7 @@ This sequence of operations was run: From: [CONTRACT_HASH] To: [CONTRACT_HASH] This transaction was successfully applied - Consumed gas: 1450 + Consumed gas: 1000 Balance updates: [CONTRACT_HASH] ... -ꜩ3.895862 [CONTRACT_HASH] ... +ꜩ3.895862 diff --git a/tests_python/tests_alpha/test_contract.py b/tests_python/tests_alpha/test_contract.py index 7fff2787e8255551a474afff2658225b18b0524c..6dbec261d24aa60e3c25cb0736bc74cc7437d42a 100644 --- a/tests_python/tests_alpha/test_contract.py +++ b/tests_python/tests_alpha/test_contract.py @@ -156,7 +156,7 @@ class TestManager: utils.bake(client, bake_for='bootstrap5') new_balance = client.get_mutez_balance('manager') new_balance_bootstrap = client.get_mutez_balance('bootstrap2') - fee = 0.000587 + fee = 0.000542 fee_mutez = utils.mutez_of_tez(fee) assert balance - amount_mutez == new_balance assert ( diff --git a/tests_python/tests_alpha/test_multiple_transfers.py b/tests_python/tests_alpha/test_multiple_transfers.py index 39c1fad2b2e61a260e6be03dfb4f7d15cd5d98c6..3044fcb3d3330d9ac37c91566d9c4c2d10f1ce2f 100644 --- a/tests_python/tests_alpha/test_multiple_transfers.py +++ b/tests_python/tests_alpha/test_multiple_transfers.py @@ -119,8 +119,8 @@ class TestMultipleTransfers: new_balance_bootstrap3 = client.get_mutez_balance('bootstrap3') if payer == source: - fee_first_transfer = 397 - fee_second_transfer = 301 + fee_first_transfer = 352 + fee_second_transfer = 256 source_fee_mutez = fee_first_transfer + fee_second_transfer else: source_fee_mutez = 0