Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Enable EIP-3855 PUSH0 instruction #578

Closed
yanghang8612 opened this issue Jul 18, 2023 · 22 comments
Closed

Proposal: Enable EIP-3855 PUSH0 instruction #578

yanghang8612 opened this issue Jul 18, 2023 · 22 comments

Comments

@yanghang8612
Copy link
Contributor

Introduction

As part of the Ethereum Shanghai upgrade, EIP-3855: PUSH0 Instruction is already implemented to TRON. To improve compatibility with EVM, it is proposed that PUSH0 instruction will be enabled.

Motivation

The Ethereum Shanghai Upgrade has already been activated on its mainnet on April 12, 2023. As a EVM-compatible implementation for TRON network, TVM has implemented PUSH0 instruction in GreatVoyage-v4.7.2(Periander), but this change have not been activated yet.

Once the PUSH0 instruction is enabled, the following benefits are realized:

  1. Reducing contract code size.
  2. Reducing the risk of contracts (mis)using various instructions as an optimisation measure. Repricing/changing those instructions can be more risky.
  3. Reduce the need to use DUP instructions for duplicating zeroes.

For more details, please refer to: TIP-543.

Timeline

Any opinions or discussions about this proposal are welcomed in the next two weeks.

The estimated timeline

  • Creation time of the voting request: 1st August 2023
  • The effective time of voting request: 14:00, 3rd August 2023

How to Initialize the Voting Request

This is the command of initiating the voting request

  • CreateProposal 76 1

Technical Specs

The instruction PUSH0 is introduced at 0x5f. It has no immediate data, pops no items from the stack, and places a single item with the value 0 onto the stack. The cost of this instruction is 2 energy (aka base).

Welcome to discuss.

@jernganl
Copy link

How about backward compatibility? Will there be any changes to the deployment contract in the future?

@ikirudoughnuts
Copy link

ikirudoughnuts commented Jul 19, 2023

Finally comes to the implementation phase. I believe this proposal of implementing the PUSH0 instruction can bring many benefits. PUSH0 can reduce contract code size, which means reducing the byte fees on the network, thereby lowering transaction fees for users. I advocate enabling PUSH0 on the TRON mainnet as soon as possible to improve compatibility with Ethereum and benefit users.

@MannGates
Copy link

Good, so basically this will decrease the transaction fee of triggering smart contracts on TRON by decreasing the amount of energy, right?

@yanghang8612
Copy link
Contributor Author

How about backward compatibility? Will there be any changes to the deployment contract in the future?

This proposal introduces a new opcode which did not exists previously. Already deployed contracts using this opcode could change their behaviour if this proposal is enabled.

Contracts deployed in the future will be shorter and consume less energy for execution.

@laurenceja
Copy link

@yanghang8612 Could we know how many contracts have used this opcode value? In fact, I want to know whether my contracts use this value or not.

@yanghang8612
Copy link
Contributor Author

Good, so basically this will decrease the transaction fee of triggering smart contracts on TRON by decreasing the amount of energy, right?

This does not affect the energy consumption of deployed contracts. But contracts deployed in the future will benefit from it.

@yanghang8612
Copy link
Contributor Author

@yanghang8612 Could we know how many contracts have used this opcode value? In fact, I want to know whether my contracts use this value or not.

In fact the bytecode of deployed contracts compiled by the solidity compiler will not contain this opcode.

This opcode will be supported in a future release of the compiler.

@MannGates
Copy link

MannGates commented Jul 20, 2023

Good, so basically this will decrease the transaction fee of triggering smart contracts on TRON by decreasing the amount of energy, right?

This does not affect the energy consumption of deployed contracts. But contracts deployed in the future will benefit from it.

Oh, then it is really different from my expectation, users will benefit little then, because most smart contracts have been deployed already in TRON ecosystem so far. So do you have any approach to refine the situation except for letting developers redeploy the smart contracts again (which involves too plenty of work and users may be misled by the new and old contracts)?

Is it the same situation with the smart contracts on Ethereum and do they have some ideas?

@yanghang8612
Copy link
Contributor Author

Good, so basically this will decrease the transaction fee of triggering smart contracts on TRON by decreasing the amount of energy, right?

This does not affect the energy consumption of deployed contracts. But contracts deployed in the future will benefit from it.

Oh, then it is really different from my expectation, users will benefit little then, because most smart contracts have been deployed already in TRON ecosystem so far. So do you have any approach to refine the situation except for letting developers redeploy the smart contracts again (which involves too plenty of work and users may be misled by the new and old contracts)?

Is it the same situation with the smart contracts on Ethereum and do they have some ideas?

If a contract is implemented as a proxy, then the users can benefit from it by upgrading the contract implementation.

As far as we know, most of the old contracts deployed on Ethereum will not benefit from this either. At the same time, the transaction fee consists of the energy and the unit price of the energy, and lowering either of these reduces the transaction fee.

@CryptoRhinoGH
Copy link

CryptoRhinoGH commented Jul 24, 2023

Good, so basically this will decrease the transaction fee of triggering smart contracts on TRON by decreasing the amount of energy, right?

This does not affect the energy consumption of deployed contracts. But contracts deployed in the future will benefit from it.

Oh, then it is really different from my expectation, users will benefit little then, because most smart contracts have been deployed already in TRON ecosystem so far. So do you have any approach to refine the situation except for letting developers redeploy the smart contracts again (which involves too plenty of work and users may be misled by the new and old contracts)?

Is it the same situation with the smart contracts on Ethereum and do they have some ideas?

I'm not sure of this answer, but from what I understand, It's not going to benefit older contracts as they already have a compiled bytecode which use certain OPCODES, or operation codes. Before this, OPCODES 0x5C to 0x5F were unused in EVM, but now when the new contracts are compiled, they will start using this new OPCODE, 0x5F. I'm not sure if 0x5F was being used for anything in TVM or not... To explain in a little more detail, currently PUSH1 is linked to opcode 0x60, PUSH2 at 0x61 and so on till PUSH32 for pushing 32 bytes to stack. When you write PUSH1 0x5, the bytecode comes out to be 6005 (opcode + index which they mention above), if you write PUSH2 0x5, then bytecode is 610005, i.e. 2 bytes used for the 0x5. Now they have chosen 0x5F as the OPCODE for PUSH0, which was earlier written as PUSH1 0x0. So instead of bytecode coming out to be 6000 (PUSH1 0x0), it will just be 5F (or PUSH0), removing 2 redundant bytes. Additionally, they were using DUP commands, which means duplicate from stack. Not sure of the implementation in the compiler, but it would either be storing 0 in some stack position always and then using DUP to push to any other stack, or pushing to stack once, then DUP later, which also took 3 gas. Correct me if I'm wrong anywhere

Additionally, in response to @yanghang8612, even while using a proxy contract, the final execution will be of the older OPCODEs which will continue using PUSH1 00 right? So even while using a proxy contract, it won't benefit the user for old contracts, and the extra cost will be there for the call to and from the proxy contract?

@yanghang8612
Copy link
Contributor Author

@CryptoRhinoGH 0x5f is likewise not used in TVM, and this is consistent with EVM. What you describe for the benefits of the PUSH0 instruction to contract gas consumption is exactly right.

For proxy contracts, you simply replace the old implementation of the proxy contract with the newly compiled bytecode when PUSH0 is enabled. This is actually equivalent to upgrading the proxy contract.

@MannGates
Copy link

Good, so basically this will decrease the transaction fee of triggering smart contracts on TRON by decreasing the amount of energy, right?

This does not affect the energy consumption of deployed contracts. But contracts deployed in the future will benefit from it.

Oh, then it is really different from my expectation, users will benefit little then, because most smart contracts have been deployed already in TRON ecosystem so far. So do you have any approach to refine the situation except for letting developers redeploy the smart contracts again (which involves too plenty of work and users may be misled by the new and old contracts)?
Is it the same situation with the smart contracts on Ethereum and do they have some ideas?

I'm not sure of this answer, but from what I understand, It's not going to benefit older contracts as they already have a compiled bytecode which use certain OPCODES, or operation codes. Before this, OPCODES 0x5C to 0x5F were unused in EVM, but now when the new contracts are compiled, they will start using this new OPCODE, 0x5F. I'm not sure if 0x5F was being used for anything in TVM or not... To explain in a little more detail, currently PUSH1 is linked to opcode 0x60, PUSH2 at 0x61 and so on till PUSH32 for pushing 32 bytes to stack. When you write PUSH1 0x5, the bytecode comes out to be 6005 (opcode + index which they mention above), if you write PUSH2 0x5, then bytecode is 610005, i.e. 2 bytes used for the 0x5. Now they have chosen 0x5F as the OPCODE for PUSH0, which was earlier written as PUSH1 0x0. So instead of bytecode coming out to be 6000 (PUSH1 0x0), it will just be 5F (or PUSH0), removing 2 redundant bytes. Additionally, they were using DUP commands, which means duplicate from stack. Not sure of the implementation in the compiler, but it would either be storing 0 in some stack position always and then using DUP to push to any other stack, or pushing to stack once, then DUP later, which also took 3 gas. Correct me if I'm wrong anywhere

Additionally, in response to @yanghang8612, even while using a proxy contract, the final execution will be of the older OPCODEs which will continue using PUSH1 00 right? So even while using a proxy contract, it won't benefit the user for old contracts, and the extra cost will be there for the call to and from the proxy contract?

Thank you for explaining the mechanism in details, very helpful.

@WalterBrooks
Copy link

My intuition is that saving a 1 byte is a very marginal improvement, how much portion of energy can be saved on average?

@Jamestepfoward
Copy link

My intuition is that saving a 1 byte is a very marginal improvement, how much portion of energy can be saved on average?

It is not only about saving 1 byte. The main motivation is runtime cost and avoiding that contracts use weird optimizations because they have no better option, and that optimization limiting us in introducing other features.

@WalterBrooks
Copy link

My intuition is that saving a 1 byte is a very marginal improvement, how much portion of energy can be saved on average?

It is not only about saving 1 byte. The main motivation is runtime cost and avoiding that contracts use weird optimizations because they have no better option, and that optimization limiting us in introducing other features.

Yeah, thanks, it helps me better understand:

  1. Reducing the risk of contracts (mis)using various instructions as an optimisation measure. Repricing/changing those instructions can be more risky.

and I have checked some data report on Ethereum, saying that in the sample, PUSH1 opcode accounts for about 50% of the all PUSH opcode. Then this proposal is meaningful to some degree.

@Bellgin
Copy link

Bellgin commented Jul 28, 2023

Some other instructions are used to save gas before but do not work quite well, sometimes not just a single byte long. PUSH0 could perfectly solve this and always cost two gas.

@brooklynn1212
Copy link

Good, so basically this will decrease the transaction fee of triggering smart contracts on TRON by decreasing the amount of energy, right?

This does not affect the energy consumption of deployed contracts. But contracts deployed in the future will benefit from it.

Oh, then it is really different from my expectation, users will benefit little then, because most smart contracts have been deployed already in TRON ecosystem so far. So do you have any approach to refine the situation except for letting developers redeploy the smart contracts again (which involves too plenty of work and users may be misled by the new and old contracts)?
Is it the same situation with the smart contracts on Ethereum and do they have some ideas?

I'm not sure of this answer, but from what I understand, It's not going to benefit older contracts as they already have a compiled bytecode which use certain OPCODES, or operation codes. Before this, OPCODES 0x5C to 0x5F were unused in EVM, but now when the new contracts are compiled, they will start using this new OPCODE, 0x5F. I'm not sure if 0x5F was being used for anything in TVM or not... To explain in a little more detail, currently PUSH1 is linked to opcode 0x60, PUSH2 at 0x61 and so on till PUSH32 for pushing 32 bytes to stack. When you write PUSH1 0x5, the bytecode comes out to be 6005 (opcode + index which they mention above), if you write PUSH2 0x5, then bytecode is 610005, i.e. 2 bytes used for the 0x5. Now they have chosen 0x5F as the OPCODE for PUSH0, which was earlier written as PUSH1 0x0. So instead of bytecode coming out to be 6000 (PUSH1 0x0), it will just be 5F (or PUSH0), removing 2 redundant bytes. Additionally, they were using DUP commands, which means duplicate from stack. Not sure of the implementation in the compiler, but it would either be storing 0 in some stack position always and then using DUP to push to any other stack, or pushing to stack once, then DUP later, which also took 3 gas. Correct me if I'm wrong anywhere

Additionally, in response to @yanghang8612, even while using a proxy contract, the final execution will be of the older OPCODEs which will continue using PUSH1 00 right? So even while using a proxy contract, it won't benefit the user for old contracts, and the extra cost will be there for the call to and from the proxy contract?

@CryptoRhinoGH very nice introduction, and as to the proxy contract, I want to add some words to make it clearer. In general, the proxy contract consists of a gateway smart contract and a terminal smart contract. The gateway smart contract is used for storing data, and an method to point to the terminal smart contract. And the terminal smart contract is used to actually execute features. So after PUSH0 is enabled, for proxy contract, the developer could deploy a new terminal smart contract with PUSH0 instruction, and let the gateway smart contract point to this new one. This is @yanghang8612 means actually equivalent to upgrading the proxy contract.

@txoh1603
Copy link

A considerable percentage of PUSH* instructions executed were pushing 0 value before on chain, while the PUSH0 comes, never too late.

@souppopnix
Copy link

This change makes sense, although it's not beneficial for implemented contracts, still worth it for future dApp creators and users.

@sunflower-sun
Copy link

Beside the triggering a contract, this proposal may also reduce the energy consumption when deploying a contract, but not absolute, it depends on the implementation of the contract. In my opinion, more complete instruction is a big step forward of TVM.

And when will the new version of solidity be released?

@yanghang8612
Copy link
Contributor Author

Beside the triggering a contract, this proposal may also reduce the energy consumption when deploying a contract, but not absolute, it depends on the implementation of the contract. In my opinion, more complete instruction is a big step forward of TVM.

And when will the new version of solidity be released?

Yes, the solidity compiler will be available soon, so stay tuned.

@yanghang8612
Copy link
Contributor Author

Thanks to all your discussion on this proposal.
This issue will be closed as it has already taken effect, please check it here: https://tronscan.org/#/proposal/89

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

15 participants