Skip to content

Commit

Permalink
feat(protocol): optimize gas for processMessage & retryMessage (#13181)
Browse files Browse the repository at this point in the history
Co-authored-by: Daniel Wang <dan@taiko.xyz>
Co-authored-by: Daniel Wang <99078276+dantaik@users.noreply.github.com>
Co-authored-by: Keszey Dániel <keszeyd@MacBook-Pro.local>
Co-authored-by: David <david@taiko.xyz>
  • Loading branch information
5 people committed Mar 9, 2023
1 parent 2e34634 commit 178e382
Show file tree
Hide file tree
Showing 16 changed files with 103 additions and 258 deletions.
50 changes: 23 additions & 27 deletions packages/protocol/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,42 @@

## [0.4.0](https://github.com/taikoxyz/taiko-mono/compare/protocol-v0.3.0...protocol-v0.4.0) (2023-03-01)


### Features

* **protocol:** add isEtherReleased to Bridge ([#13204](https://github.com/taikoxyz/taiko-mono/issues/13204)) ([f39e65d](https://github.com/taikoxyz/taiko-mono/commit/f39e65da022b6af6a3f573843743aae9337c0077))
* **protocol:** Additional integration tests, solidity bump, reduce TokenVault contract size ([#13155](https://github.com/taikoxyz/taiko-mono/issues/13155)) ([ffdf5db](https://github.com/taikoxyz/taiko-mono/commit/ffdf5db675404d463850fca0b97d37c23cde61a1))
* **protocol:** Change require to custom err in bridge contracts ([#13220](https://github.com/taikoxyz/taiko-mono/issues/13220)) ([6e8cb82](https://github.com/taikoxyz/taiko-mono/commit/6e8cb82b477fa1a3ebf842dc4bf0dd0820d19e07))
* **protocol:** Deploy a FreeMintERC20 and a MayFailFreeMintERC20 on deploy of L1 ([#13222](https://github.com/taikoxyz/taiko-mono/issues/13222)) ([0d3e769](https://github.com/taikoxyz/taiko-mono/commit/0d3e7692489c4ed5eadafae7aebde49000c03a7f))
* **protocol:** disable contracts as msg.sender ([#13206](https://github.com/taikoxyz/taiko-mono/issues/13206)) ([66316e9](https://github.com/taikoxyz/taiko-mono/commit/66316e9cb74a167e1ce437616e47afec95458c6f))
* **protocol:** make custom errors in L1 libs a part of the `TaikoL1.sol`'s ABI ([#13166](https://github.com/taikoxyz/taiko-mono/issues/13166)) ([2943e3e](https://github.com/taikoxyz/taiko-mono/commit/2943e3eeb18c12e5489c8974df6556caadfcb099))
* **protocol:** partially randomize prover reward ([#13184](https://github.com/taikoxyz/taiko-mono/issues/13184)) ([16993cd](https://github.com/taikoxyz/taiko-mono/commit/16993cdb081b831420c7e86d981afd11726197d1))
* **protocol:** update `PlonkVerifier` to accept new public inputs ([#13208](https://github.com/taikoxyz/taiko-mono/issues/13208)) ([9804099](https://github.com/taikoxyz/taiko-mono/commit/9804099ac477d320b3c2019f6565d3caadefdcfb))

- **protocol:** add isEtherReleased to Bridge ([#13204](https://github.com/taikoxyz/taiko-mono/issues/13204)) ([f39e65d](https://github.com/taikoxyz/taiko-mono/commit/f39e65da022b6af6a3f573843743aae9337c0077))
- **protocol:** Additional integration tests, solidity bump, reduce TokenVault contract size ([#13155](https://github.com/taikoxyz/taiko-mono/issues/13155)) ([ffdf5db](https://github.com/taikoxyz/taiko-mono/commit/ffdf5db675404d463850fca0b97d37c23cde61a1))
- **protocol:** Change require to custom err in bridge contracts ([#13220](https://github.com/taikoxyz/taiko-mono/issues/13220)) ([6e8cb82](https://github.com/taikoxyz/taiko-mono/commit/6e8cb82b477fa1a3ebf842dc4bf0dd0820d19e07))
- **protocol:** Deploy a FreeMintERC20 and a MayFailFreeMintERC20 on deploy of L1 ([#13222](https://github.com/taikoxyz/taiko-mono/issues/13222)) ([0d3e769](https://github.com/taikoxyz/taiko-mono/commit/0d3e7692489c4ed5eadafae7aebde49000c03a7f))
- **protocol:** disable contracts as msg.sender ([#13206](https://github.com/taikoxyz/taiko-mono/issues/13206)) ([66316e9](https://github.com/taikoxyz/taiko-mono/commit/66316e9cb74a167e1ce437616e47afec95458c6f))
- **protocol:** make custom errors in L1 libs a part of the `TaikoL1.sol`'s ABI ([#13166](https://github.com/taikoxyz/taiko-mono/issues/13166)) ([2943e3e](https://github.com/taikoxyz/taiko-mono/commit/2943e3eeb18c12e5489c8974df6556caadfcb099))
- **protocol:** partially randomize prover reward ([#13184](https://github.com/taikoxyz/taiko-mono/issues/13184)) ([16993cd](https://github.com/taikoxyz/taiko-mono/commit/16993cdb081b831420c7e86d981afd11726197d1))
- **protocol:** update `PlonkVerifier` to accept new public inputs ([#13208](https://github.com/taikoxyz/taiko-mono/issues/13208)) ([9804099](https://github.com/taikoxyz/taiko-mono/commit/9804099ac477d320b3c2019f6565d3caadefdcfb))

### Bug Fixes

* **protocol:** fix `PlonkVerifier`'s name in `AddressManager` ([#13229](https://github.com/taikoxyz/taiko-mono/issues/13229)) ([7170bd9](https://github.com/taikoxyz/taiko-mono/commit/7170bd966b02d986b26baf5991f47015a46cca64))
* **protocol:** fix occasional test failure ([#13173](https://github.com/taikoxyz/taiko-mono/issues/13173)) ([3aaf5dd](https://github.com/taikoxyz/taiko-mono/commit/3aaf5dde644c8069050fcee52f1a9134144a746b))
* **protocol:** use prevrandao for L2 mixHash ([#13157](https://github.com/taikoxyz/taiko-mono/issues/13157)) ([93daca4](https://github.com/taikoxyz/taiko-mono/commit/93daca47e11c31192aaa7f6db93d399a215164ad))
- **protocol:** fix `PlonkVerifier`'s name in `AddressManager` ([#13229](https://github.com/taikoxyz/taiko-mono/issues/13229)) ([7170bd9](https://github.com/taikoxyz/taiko-mono/commit/7170bd966b02d986b26baf5991f47015a46cca64))
- **protocol:** fix occasional test failure ([#13173](https://github.com/taikoxyz/taiko-mono/issues/13173)) ([3aaf5dd](https://github.com/taikoxyz/taiko-mono/commit/3aaf5dde644c8069050fcee52f1a9134144a746b))
- **protocol:** use prevrandao for L2 mixHash ([#13157](https://github.com/taikoxyz/taiko-mono/issues/13157)) ([93daca4](https://github.com/taikoxyz/taiko-mono/commit/93daca47e11c31192aaa7f6db93d399a215164ad))

## [0.3.0](https://github.com/taikoxyz/taiko-mono/compare/protocol-v0.2.0...protocol-v0.3.0) (2023-02-15)


### Features

* **protocol:** add a script to calculate `slotSmoothingFactor` ([#13109](https://github.com/taikoxyz/taiko-mono/issues/13109)) ([61dbc23](https://github.com/taikoxyz/taiko-mono/commit/61dbc2304227b8e844fd19a8b7c5f1cf46f79379))
* **protocol:** add more protocol/tokenomics tests ([#12988](https://github.com/taikoxyz/taiko-mono/issues/12988)) ([3a7523f](https://github.com/taikoxyz/taiko-mono/commit/3a7523f0008d58bee3e839bed37d62161aa39b36))
* **protocol:** change statevariables to return a struct ([#13113](https://github.com/taikoxyz/taiko-mono/issues/13113)) ([0bffeb0](https://github.com/taikoxyz/taiko-mono/commit/0bffeb0f3d17938bf2146772962719ae21ce22fa))
* **protocol:** check message.to on source chain as well ([#13107](https://github.com/taikoxyz/taiko-mono/issues/13107)) ([b55a646](https://github.com/taikoxyz/taiko-mono/commit/b55a6461f7bc665254825b7627cf0e2fb91c716f))
* **protocol:** deploy a test ERC-20 token to test bridge ([#13132](https://github.com/taikoxyz/taiko-mono/issues/13132)) ([95596e4](https://github.com/taikoxyz/taiko-mono/commit/95596e4e2bf3506d94d83e85494ddade1f35dc70))
* **protocol:** improve precision for slot-availability multipliers ([#13108](https://github.com/taikoxyz/taiko-mono/issues/13108)) ([3ed5138](https://github.com/taikoxyz/taiko-mono/commit/3ed513850eba361a5ee45fc7143e4dd30c4ed025))
* **protocol:** no longer delete commit records ([#13152](https://github.com/taikoxyz/taiko-mono/issues/13152)) ([edbdd3d](https://github.com/taikoxyz/taiko-mono/commit/edbdd3d2859e2769ef759ae0c1d8936eff4e4a06))
* **protocol:** re-implement bridge receive check ([#13134](https://github.com/taikoxyz/taiko-mono/issues/13134)) ([3c10706](https://github.com/taikoxyz/taiko-mono/commit/3c107066dabb1dda55814c10933d604d5069de93))
* **protocol:** restrict receive()'s msg.sender to vaults ([#13110](https://github.com/taikoxyz/taiko-mono/issues/13110)) ([2d8fa12](https://github.com/taikoxyz/taiko-mono/commit/2d8fa12a72f6850f75adb468d945af080671f3f8))
* **protocol:** revert Bridge receive() checks ([#13128](https://github.com/taikoxyz/taiko-mono/issues/13128)) ([675611d](https://github.com/taikoxyz/taiko-mono/commit/675611d2a765c706d6d308635a5820639cbd39c4))
* **protocol:** update Yul PlonkVerifier ([#13133](https://github.com/taikoxyz/taiko-mono/issues/13133)) ([5d9b063](https://github.com/taikoxyz/taiko-mono/commit/5d9b063ab260476023365856c4bbfee151029995))

- **protocol:** add a script to calculate `slotSmoothingFactor` ([#13109](https://github.com/taikoxyz/taiko-mono/issues/13109)) ([61dbc23](https://github.com/taikoxyz/taiko-mono/commit/61dbc2304227b8e844fd19a8b7c5f1cf46f79379))
- **protocol:** add more protocol/tokenomics tests ([#12988](https://github.com/taikoxyz/taiko-mono/issues/12988)) ([3a7523f](https://github.com/taikoxyz/taiko-mono/commit/3a7523f0008d58bee3e839bed37d62161aa39b36))
- **protocol:** change statevariables to return a struct ([#13113](https://github.com/taikoxyz/taiko-mono/issues/13113)) ([0bffeb0](https://github.com/taikoxyz/taiko-mono/commit/0bffeb0f3d17938bf2146772962719ae21ce22fa))
- **protocol:** check message.to on source chain as well ([#13107](https://github.com/taikoxyz/taiko-mono/issues/13107)) ([b55a646](https://github.com/taikoxyz/taiko-mono/commit/b55a6461f7bc665254825b7627cf0e2fb91c716f))
- **protocol:** deploy a test ERC-20 token to test bridge ([#13132](https://github.com/taikoxyz/taiko-mono/issues/13132)) ([95596e4](https://github.com/taikoxyz/taiko-mono/commit/95596e4e2bf3506d94d83e85494ddade1f35dc70))
- **protocol:** improve precision for slot-availability multipliers ([#13108](https://github.com/taikoxyz/taiko-mono/issues/13108)) ([3ed5138](https://github.com/taikoxyz/taiko-mono/commit/3ed513850eba361a5ee45fc7143e4dd30c4ed025))
- **protocol:** no longer delete commit records ([#13152](https://github.com/taikoxyz/taiko-mono/issues/13152)) ([edbdd3d](https://github.com/taikoxyz/taiko-mono/commit/edbdd3d2859e2769ef759ae0c1d8936eff4e4a06))
- **protocol:** re-implement bridge receive check ([#13134](https://github.com/taikoxyz/taiko-mono/issues/13134)) ([3c10706](https://github.com/taikoxyz/taiko-mono/commit/3c107066dabb1dda55814c10933d604d5069de93))
- **protocol:** restrict receive()'s msg.sender to vaults ([#13110](https://github.com/taikoxyz/taiko-mono/issues/13110)) ([2d8fa12](https://github.com/taikoxyz/taiko-mono/commit/2d8fa12a72f6850f75adb468d945af080671f3f8))
- **protocol:** revert Bridge receive() checks ([#13128](https://github.com/taikoxyz/taiko-mono/issues/13128)) ([675611d](https://github.com/taikoxyz/taiko-mono/commit/675611d2a765c706d6d308635a5820639cbd39c4))
- **protocol:** update Yul PlonkVerifier ([#13133](https://github.com/taikoxyz/taiko-mono/issues/13133)) ([5d9b063](https://github.com/taikoxyz/taiko-mono/commit/5d9b063ab260476023365856c4bbfee151029995))

### Bug Fixes

* **protocol:** allow resolver to return zero address for EtherVault ([#13083](https://github.com/taikoxyz/taiko-mono/issues/13083)) ([cb34cf0](https://github.com/taikoxyz/taiko-mono/commit/cb34cf0e0fd182feb6eed4abf6ca9f6a2801e5f1))
- **protocol:** allow resolver to return zero address for EtherVault ([#13083](https://github.com/taikoxyz/taiko-mono/issues/13083)) ([cb34cf0](https://github.com/taikoxyz/taiko-mono/commit/cb34cf0e0fd182feb6eed4abf6ca9f6a2801e5f1))

## [0.2.0](https://github.com/taikoxyz/taiko-mono/compare/protocol-v0.1.0...protocol-v0.2.0) (2023-01-31)

Expand Down
6 changes: 5 additions & 1 deletion packages/protocol/contracts/L1/libs/LibVerifying.sol
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ library LibVerifying {
for (
uint256 i = state.latestVerifiedId + 1;
i < state.nextBlockId && processed < maxBlocks;
i++

) {
TaikoData.ForkChoice storage fc = state.forkChoices[i][
latestL2Hash
Expand Down Expand Up @@ -88,6 +88,10 @@ library LibVerifying {
fc.prover = address(0);
fc.provenAt = 0;
}

unchecked {
++i;
}
}

if (processed > 0) {
Expand Down
15 changes: 9 additions & 6 deletions packages/protocol/contracts/bridge/libs/LibBridgeProcess.sol
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ library LibBridgeProcess {
AddressResolver resolver,
IBridge.Message calldata message,
bytes calldata proof
) external {
) internal {
// If the gas limit is set to zero, only the owner can process the message.
if (message.gasLimit == 0 && msg.sender != message.owner) {
revert B_FORBIDDEN();
Expand Down Expand Up @@ -86,17 +86,20 @@ library LibBridgeProcess {
revert B_SIGNAL_NOT_RECEIVED();
}

uint256 allValue = message.depositValue +
message.callValue +
message.processingFee;
// We retrieve the necessary ether from EtherVault if receiving on
// Taiko, otherwise it is already available in this Bridge.
address ethVault = resolver.resolve("ether_vault", true);
if (ethVault != address(0)) {
EtherVault(payable(ethVault)).releaseEther(
message.depositValue + message.callValue + message.processingFee
);
if (ethVault != address(0) && (allValue > 0)) {
EtherVault(payable(ethVault)).releaseEther(allValue);
}
// We send the Ether before the message call in case the call will
// actually consume Ether.
message.owner.sendEther(message.depositValue);
if (message.depositValue > 0) {
message.owner.sendEther(message.depositValue);
}

LibBridgeStatus.MessageStatus status;
uint256 refundAmount;
Expand Down
2 changes: 1 addition & 1 deletion packages/protocol/contracts/bridge/libs/LibBridgeRetry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ library LibBridgeRetry {
AddressResolver resolver,
IBridge.Message calldata message,
bool isLastAttempt
) external {
) internal {
// If the gasLimit is not set to 0 or isLastAttempt is true, the
// address calling this function must be message.owner.
if (message.gasLimit == 0 || isLastAttempt) {
Expand Down
17 changes: 15 additions & 2 deletions packages/protocol/contracts/signal/SignalService.sol
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,20 @@ contract SignalService is ISignalService, EssentialContract {
function getSignalSlot(
address app,
bytes32 signal
) public pure returns (bytes32) {
return keccak256(abi.encodePacked(app, signal));
) public pure returns (bytes32 signalSlot) {
assembly {
// Load the free memory pointer and allocate memory for the concatenated arguments
let input := mload(0x40)

// Store the app address and signal bytes32 value in the allocated memory
mstore(input, app)
mstore(add(input, 0x20), signal)

// Calculate the hash of the concatenated arguments using keccak256
signalSlot := keccak256(input, 0x40)

// Free the memory allocated for the input
mstore(0x40, add(input, 0x60))
}
}
}
35 changes: 11 additions & 24 deletions packages/protocol/contracts/thirdparty/AddressManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,17 @@ contract AddressManager is OwnableUpgradeable {

/**
* Changes the address associated with a particular name.
* @param _name String name to associate an address with.
* @param _address Address to associate with the name.
* @param name String name to associate an address with.
* @param newAddress Address to associate with the name.
*/
function setAddress(
string memory _name,
address _address
string memory name,
address newAddress
) external onlyOwner {
bytes32 nameHash = _getNameHash(_name);
bytes32 nameHash = keccak256(bytes(name));
address oldAddress = addresses[nameHash];
addresses[nameHash] = _address;

emit AddressSet(_name, _address, oldAddress);
addresses[nameHash] = newAddress;
emit AddressSet(name, newAddress, oldAddress);
}

/********************
Expand All @@ -85,23 +84,11 @@ contract AddressManager is OwnableUpgradeable {

/**
* Retrieves the address associated with a given name.
* @param _name Name to retrieve an address for.
* @param name Name to retrieve an address for.
* @return Address associated with the given name.
*/
function getAddress(string memory _name) external view returns (address) {
return addresses[_getNameHash(_name)];
}

/**********************
* Internal Functions *
**********************/

/**
* Computes the hash of a name.
* @param _name Name to compute a hash for.
* @return Hash of the given name.
*/
function _getNameHash(string memory _name) internal pure returns (bytes32) {
return keccak256(abi.encodePacked(_name));
function getAddress(string memory name) external view returns (address) {
bytes32 nameHash = keccak256(bytes(name));
return addresses[nameHash];
}
}
15 changes: 11 additions & 4 deletions packages/protocol/contracts/thirdparty/LibMerkleTrie.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,20 +46,20 @@ library LibMerkleTrie {
}

struct TrieNode {
bytes encoded;
LibRLPReader.RLPItem[] decoded;
bytes encoded;
}

/**********************
* Contract Constants *
**********************/

// TREE_RADIX determines the number of elements per branch node.
uint256 constant TREE_RADIX = 16;
uint8 constant TREE_RADIX = 16;
// Branch nodes have TREE_RADIX elements plus an additional `value` slot.
uint256 constant BRANCH_NODE_LENGTH = TREE_RADIX + 1;
uint8 constant BRANCH_NODE_LENGTH = TREE_RADIX + 1;
// Leaf nodes and extension nodes always have two elements, a `path` and a `value`.
uint256 constant LEAF_OR_EXTENSION_NODE_LENGTH = 2;
uint8 constant LEAF_OR_EXTENSION_NODE_LENGTH = 2;

// Prefixes are prepended to the `path` within a leaf or extension node and
// allow us to differentiate between the two node types. `ODD` or `EVEN` is
Expand Down Expand Up @@ -343,6 +343,13 @@ library LibMerkleTrie {
return LibRLPReader.readBytes(_node.decoded[_node.decoded.length - 1]);
}

/**
* @notice Utility; determines the number of nibbles shared between two
* nibble arrays.
* @param _a First nibble array.
* @param _b Second nibble array.
* @return _shared Number of shared nibbles.
*/
/**
* @notice Utility; determines the number of nibbles shared between two
* nibble arrays.
Expand Down
35 changes: 18 additions & 17 deletions packages/protocol/contracts/thirdparty/LibRLPReader.sol
Original file line number Diff line number Diff line change
Expand Up @@ -411,26 +411,26 @@ library LibRLPReader {
uint256 _src,
uint256 _offset,
uint256 _length
) private pure returns (bytes memory) {
bytes memory out = new bytes(_length);
if (out.length == 0) {
return out;
) internal pure returns (bytes memory) {
bytes memory result = new bytes(_length);
if (result.length == 0) {
return result;
}

uint256 src = _src + _offset;
uint256 dest;
bytes memory src;
bytes memory dst;
assembly {
dest := add(out, 32)
}
src := add(_src, _offset)

// Copy over as many complete words as we can.
for (uint256 i; i < _length / 32; ++i) {
assembly {
mstore(dest, mload(src))
}
dst := add(result, 32)

src += 32;
dest += 32;
for {
let i := 0
} lt(i, _length) {
i := add(i, 32)
} {
mstore(add(dst, i), mload(add(src, i)))
}
}

// Pick out the remaining bytes.
Expand All @@ -440,9 +440,10 @@ library LibRLPReader {
}

assembly {
mstore(dest, or(and(mload(src), not(mask)), and(mload(dest), mask)))
mstore(dst, or(and(mload(src), not(mask)), and(mload(dst), mask)))
}
return out;

return result;
}

/**
Expand Down
7 changes: 0 additions & 7 deletions packages/protocol/tasks/deploy_L1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -324,16 +324,9 @@ async function deployBaseLibs(hre: any) {

async function deployBridge(hre: any, addressManager: string): Promise<any> {
const libTrieProof = await utils.deployContract(hre, "LibTrieProof");
const libBridgeRetry = await utils.deployContract(hre, "LibBridgeRetry");
const libBridgeProcess = await utils.deployContract(
hre,
"LibBridgeProcess"
);

const Bridge = await utils.deployContract(hre, "Bridge", {
LibTrieProof: libTrieProof.address,
LibBridgeRetry: libBridgeRetry.address,
LibBridgeProcess: libBridgeProcess.address,
});

await utils.waitTx(hre, await Bridge.init(addressManager));
Expand Down

0 comments on commit 178e382

Please sign in to comment.