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

Move mappings key to constants #261

Merged
merged 33 commits into from Aug 5, 2019
Merged

Move mappings key to constants #261

merged 33 commits into from Aug 5, 2019

Conversation

patitonar
Copy link
Contributor

Moved mappings key to constant. This helps prevent issues caused by typos or erroneous copy-pastes, this also improves readability. Also some repeated code related to the constant was extracted to base contracts. I think the easiest way to review this PR is by reviewing commit per commit.

@patitonar patitonar requested a review from akolotov August 2, 2019 19:10
@patitonar patitonar self-assigned this Aug 2, 2019
// Before store the contract we need to make sure that it is the block reward contract in actual fact,
// call a specific method from the contract that should return a specific value
bool isBlockRewardContract = false;
if (_blockReward.call(abi.encodeWithSignature("blockRewardContractId()"))) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The compiler could prepare the method descriptor on the compilation time and store just 4 bytes in the code now but I am not sure. Could you investigate if it is so or it is worth (from the gas consumption point of view) to store abi.encodeWithSignature("blockRewardContractId()") in a constant as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From docs about Constant State Variables:
The compiler does not reserve a storage slot for these variables, and every occurrence is replaced by the respective constant expression (which might be computed to a single value by the optimizer).

I tried 2 options:

Test 1

Defined:

bytes internal constant BLOCK_REWARD_CONTRACT_ID = abi.encodeWithSignature("blockRewardContractId()");

And then using it as:

if (_blockReward.call(BLOCK_REWARD_CONTRACT_ID)) {

Gas consumption results:

Contract Before After Diff
HomeBridgeErcToNative 6110869 6110869 0
FeeManagerErcToErcPOSDAO 894232 894168 -64
HomeBridgeErcToNative.setBlockRewardContract 34362 34362 0

Test 2

Defined the selector hash directly in the constant

bytes4 internal constant BLOCK_REWARD_CONTRACT_ID = 0x2ee57f8d; // blockRewardContractId() selector

Gas consumption results:

Contract Before After Diff
HomeBridgeErcToNative 6110869 6082606 -28263
FeeManagerErcToErcPOSDAO 894232 860151 -34081
HomeBridgeErcToNative.setBlockRewardContract 34362 34160 -202

From test 1, it seems that it is not worth to extract the signature to a constant from gas perspective. However, it looks like if we define the constant as in test 2 we can save some considerable gas. We can apply this to similar other cases on the other contracts too. If we do this, I think we should have a comment on each constant to know the selector it is referring to

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice research!
Can the line

bytes internal constant BLOCK_REWARD_CONTRACT_ID = abi.encodeWithSignature("blockRewardContractId()");

consume more gas since there is no exact size of data?

I agree with putting just hexadecimal value of the method selector to optimize gas usage.

// Before store the contract we need to make sure that it is the block reward contract in actual fact,
// call a specific method from the contract that should return a specific value
bool isBlockRewardContract = false;
if (_blockReward.call(abi.encodeWithSignature("blockRewardContractId()"))) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice research!
Can the line

bytes internal constant BLOCK_REWARD_CONTRACT_ID = abi.encodeWithSignature("blockRewardContractId()");

consume more gas since there is no exact size of data?

I agree with putting just hexadecimal value of the method selector to optimize gas usage.

@akolotov akolotov self-requested a review August 5, 2019 16:07
@patitonar
Copy link
Contributor Author

Added the selector hexadecimal values as constants. Here are the main gas consumption changes

Contract Develop Current Branch Diff
FeeManagerErcToNative 1175450 1175386 -64
FeeManagerErcToErcPOSDAO 891814 826663 −65151
HomeBridgeErcToErc 5788764 5713926 −74838
HomeBridgeErcToErcPOSDAO 5953366 5878208 −75158
HomeBridgeErcToNative 6105969 5979713 −126256
HomeBridgeNativeToErc 4973809 4898591 −75218
ForeignBridgeNativeToErc 4012906 3937875 −75031

@akolotov akolotov merged commit 3a1d4d8 into develop Aug 5, 2019
@akolotov akolotov deleted the storage-key-constants branch August 5, 2019 20:11
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

Successfully merging this pull request may close these issues.

None yet

2 participants