{"action":"created","issue":{"url":"https://api.github.com/repos/ethereum/py-evm/issues/371","repository_url":"https://api.github.com/repos/ethereum/py-evm","labels_url":"https://api.github.com/repos/ethereum/py-evm/issues/371/labels{/name}","comments_url":"https://api.github.com/repos/ethereum/py-evm/issues/371/comments","events_url":"https://api.github.com/repos/ethereum/py-evm/issues/371/events","html_url":"https://github.com/ethereum/py-evm/issues/371","id":297118395,"number":371,"title":"Add probe_PAYGAS_mode utility function","user":{"login":"NIC619","id":17670147,"avatar_url":"https://avatars0.githubusercontent.com/u/17670147?v=4","gravatar_id":"","url":"https://api.github.com/users/NIC619","html_url":"https://github.com/NIC619","followers_url":"https://api.github.com/users/NIC619/followers","following_url":"https://api.github.com/users/NIC619/following{/other_user}","gists_url":"https://api.github.com/users/NIC619/gists{/gist_id}","starred_url":"https://api.github.com/users/NIC619/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/NIC619/subscriptions","organizations_url":"https://api.github.com/users/NIC619/orgs","repos_url":"https://api.github.com/users/NIC619/repos","events_url":"https://api.github.com/users/NIC619/events{/privacy}","received_events_url":"https://api.github.com/users/NIC619/received_events","type":"User","site_admin":false},"labels":[{"id":769749869,"url":"https://api.github.com/repos/ethereum/py-evm/labels/Sharding","name":"Sharding","color":"f2e346","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-02-14T14:37:27Z","updated_at":"2018-02-14T18:38:48Z","closed_at":null,"author_association":"CONTRIBUTOR","body":"### What is wrong?\r\nAfter `gas_price` is abstracted away and `PAYGAS` is introduced, miner SHOULD(but not mandatory) check if `PAYGAS` is triggered before fully executing a transaction.\r\n\r\n### How can it be fixed\r\nAdd a `probe_PAYGAS_mode` utility function which executes a transaction with a rather small amount of gas. If miner wants to make sure they will be paid, they should call this function before applying a transaction.\r\n\r\nNote: This should be a function that exists in a layer on top of py-evm(or maybe Trinity).\r\n\r\nThis function computationally normally execute a transaction. Normally this execution terminates with `OutOfGas` error. After the execution terminates, check if `PAYGAS` is triggered and return result.\r\n\r\nThere is one adjustable system parameter `probe_PAYGAS_mode_gas` that specifies how much gas is provisioned for the execution. Miner should be able to adjust this value depending on how much gas(computation resource) they are willing to risk.\r\n\r\nPossible extensions:\r\n- This function returns `True` of `False` indicating if miner will get paid. Additionally we can also return the value of gas price set by `PAYGAS`, to help prioritizing transactions in transaction pool.\r\n- modify `PAYGAS`: If `PAYGAS` is triggered in `probe_PAYGAS_mode`, terminates immediately. This helps saving some computation otherwise it terminates only when gas has run out.\r\n- Should probably check if it terminates in ways that we are expecting, e.g, `OutOfGas` or `PAYGAS` triggered. "},"comment":{"url":"https://api.github.com/repos/ethereum/py-evm/issues/comments/365703415","html_url":"https://github.com/ethereum/py-evm/issues/371#issuecomment-365703415","issue_url":"https://api.github.com/repos/ethereum/py-evm/issues/371","id":365703415,"user":{"login":"pipermerriam","id":824194,"avatar_url":"https://avatars3.githubusercontent.com/u/824194?v=4","gravatar_id":"","url":"https://api.github.com/users/pipermerriam","html_url":"https://github.com/pipermerriam","followers_url":"https://api.github.com/users/pipermerriam/followers","following_url":"https://api.github.com/users/pipermerriam/following{/other_user}","gists_url":"https://api.github.com/users/pipermerriam/gists{/gist_id}","starred_url":"https://api.github.com/users/pipermerriam/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pipermerriam/subscriptions","organizations_url":"https://api.github.com/users/pipermerriam/orgs","repos_url":"https://api.github.com/users/pipermerriam/repos","events_url":"https://api.github.com/users/pipermerriam/events{/privacy}","received_events_url":"https://api.github.com/users/pipermerriam/received_events","type":"User","site_admin":false},"created_at":"2018-02-14T18:38:48Z","updated_at":"2018-02-14T18:38:48Z","author_association":"MEMBER","body":"I had the following thought.  Modifying the gas limit could have the unfortunate side effect of invalidating certain transactions that would normally succeed *if* the contract code has any logic switches based on the amount of gas provided.\r\n\r\nTo fix this, we'd need to inject the *check* all the way down into the `Computation.apply_computation` method.  This has the side-benefit of not needing to double execute every transaction.\r\n\r\n```python\r\n# in `computation.py`\r\nclass PAYGASFriendlyComputationMixin:\r\n    @classmethod\r\n    def apply_computation(cls, vm_state, message):\r\n        \"\"\"\r\n        Perform the computation that would be triggered by the VM message.\r\n        \"\"\"\r\n        with cls(vm_state, message) as computation:\r\n            # Early exit on pre-compiles\r\n            if message.code_address in computation.precompiles:\r\n                computation.precompiles[message.code_address](computation)\r\n                return computation\r\n\r\n            for opcode in computation.code:\r\n                #\r\n                # inject check for whether PAYGAS has been called and abort with special \r\n                # exception if it has not and we've exceeded the gas requirements.\r\n                #\r\n                opcode_fn = computation.get_opcode_fn(computation.opcodes, opcode)\r\n\r\n                computation.logger.trace(\r\n                    \"OPCODE: 0x%x (%s) | pc: %s\",\r\n                    opcode,\r\n                    opcode_fn.mnemonic,\r\n                    max(0, computation.code.pc - 1),\r\n                )\r\n\r\n                try:\r\n                    opcode_fn(computation=computation)\r\n                except Halt:\r\n                    break\r\n        return computation\r\n\r\n# in miner script\r\ntry:\r\n    chain.apply_transaction(transaction)\r\nexcept SomeCustomPAYGASError:\r\n    # discard transaction and continue\r\n    ...\r\n```"}}
{"actor":{"display_login":"pipermerriam"}}