From 5a7deb0959936aa0d36e73d1041d571af6f74ffe Mon Sep 17 00:00:00 2001 From: 1xDeFi <90858998+1xDeFi@users.noreply.github.com> Date: Thu, 15 Dec 2022 02:54:16 +0100 Subject: [PATCH 1/7] refactor(protocol): remove internal variables and functions (#419) --- .../reference/smart-contracts/L1/TaikoL1.md | 6 ------ .../reference/smart-contracts/L1/TkoToken.md | 5 ----- .../reference/smart-contracts/L2/TaikoL2.md | 18 ------------------ .../reference/smart-contracts/bridge/Bridge.md | 6 ------ .../smart-contracts/bridge/BridgedERC20.md | 6 ------ 5 files changed, 41 deletions(-) diff --git a/packages/website/docs/reference/smart-contracts/L1/TaikoL1.md b/packages/website/docs/reference/smart-contracts/L1/TaikoL1.md index 34624912bb2..a351c69e3f3 100644 --- a/packages/website/docs/reference/smart-contracts/L1/TaikoL1.md +++ b/packages/website/docs/reference/smart-contracts/L1/TaikoL1.md @@ -12,12 +12,6 @@ struct LibData.State state struct LibData.TentativeState tentative ``` -### \_\_gap - -```solidity -uint256[50] __gap -``` - ### init ```solidity diff --git a/packages/website/docs/reference/smart-contracts/L1/TkoToken.md b/packages/website/docs/reference/smart-contracts/L1/TkoToken.md index d71fc1fb008..147dcf27b1d 100644 --- a/packages/website/docs/reference/smart-contracts/L1/TkoToken.md +++ b/packages/website/docs/reference/smart-contracts/L1/TkoToken.md @@ -2,11 +2,6 @@ _This is Taiko's governance and fee token._ -### \_\_gap - -```solidity -uint256[50] __gap -``` ### Mint diff --git a/packages/website/docs/reference/smart-contracts/L2/TaikoL2.md b/packages/website/docs/reference/smart-contracts/L2/TaikoL2.md index bf7ed0351ec..da9d73373af 100644 --- a/packages/website/docs/reference/smart-contracts/L2/TaikoL2.md +++ b/packages/website/docs/reference/smart-contracts/L2/TaikoL2.md @@ -24,12 +24,6 @@ bytes32 publicInputHash bytes32 latestSyncedHeader ``` -### \_\_gap - -```solidity -uint256[46] __gap -``` - ### BlockInvalidated ```solidity @@ -101,15 +95,3 @@ function getBlockHash(uint256 number) public view returns (bytes32) ```solidity function getConstants() public pure returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256, uint256, uint256, uint256, uint256) ``` - -### \_checkPublicInputs - -```solidity -function _checkPublicInputs() private -``` - -### \_hashPublicInputs - -```solidity -function _hashPublicInputs(uint256 chainId, uint256 number, uint256 baseFee, bytes32[255] ancestors) private pure returns (bytes32) -``` diff --git a/packages/website/docs/reference/smart-contracts/bridge/Bridge.md b/packages/website/docs/reference/smart-contracts/bridge/Bridge.md index e463d1da05b..21277f48c92 100644 --- a/packages/website/docs/reference/smart-contracts/bridge/Bridge.md +++ b/packages/website/docs/reference/smart-contracts/bridge/Bridge.md @@ -11,12 +11,6 @@ _The code hash for the same address on L1 and L2 may be different._ struct LibBridgeData.State state ``` -### \_\_gap - -```solidity -uint256[50] __gap -``` - ### MessageStatusChanged ```solidity diff --git a/packages/website/docs/reference/smart-contracts/bridge/BridgedERC20.md b/packages/website/docs/reference/smart-contracts/bridge/BridgedERC20.md index c5d8c9767d8..9c16648f21b 100644 --- a/packages/website/docs/reference/smart-contracts/bridge/BridgedERC20.md +++ b/packages/website/docs/reference/smart-contracts/bridge/BridgedERC20.md @@ -12,12 +12,6 @@ address srcToken uint256 srcChainId ``` -### \_\_gap - -```solidity -uint256[48] __gap -``` - ### BridgeMint ```solidity From 2fa40e0491ed0c16c1d87834fa79aa21fe09d187 Mon Sep 17 00:00:00 2001 From: wolfderechter <60930264+wolfderechter@users.noreply.github.com> Date: Thu, 15 Dec 2022 05:29:33 +0100 Subject: [PATCH 2/7] fix(website): hero overflow-right taikogeom (#443) --- packages/website/src/components/Hero/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/website/src/components/Hero/index.tsx b/packages/website/src/components/Hero/index.tsx index f4c8ed9a692..07864bb248e 100644 --- a/packages/website/src/components/Hero/index.tsx +++ b/packages/website/src/components/Hero/index.tsx @@ -59,11 +59,11 @@ export default function Hero() {
From 2269cc5ab913c5da84e9d075b7cf86b233efe5dd Mon Sep 17 00:00:00 2001 From: dave | d1onys1us Date: Wed, 14 Dec 2022 23:31:31 -0500 Subject: [PATCH 3/7] feat(bridge-ui): hide input arrows and focus ring (#439) --- .../bridge-ui/src/components/form/BridgeForm.svelte | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/bridge-ui/src/components/form/BridgeForm.svelte b/packages/bridge-ui/src/components/form/BridgeForm.svelte index 934909c209c..ae285de4c39 100644 --- a/packages/bridge-ui/src/components/form/BridgeForm.svelte +++ b/packages/bridge-ui/src/components/form/BridgeForm.svelte @@ -182,7 +182,7 @@ placeholder="0.01" min="0" on:input={updateAmount} - class="input input-primary bg-dark-4 input-md md:input-lg w-full" + class="input input-primary bg-dark-4 input-md md:input-lg w-full focus:ring-0" name="amount" /> @@ -210,3 +210,13 @@ {$_("home.approve")} {/if} + + From 8bf563269d88f9b39305424bed2551580cd3c8e8 Mon Sep 17 00:00:00 2001 From: dave | d1onys1us Date: Wed, 14 Dec 2022 23:34:54 -0500 Subject: [PATCH 4/7] feat(docs): add github discussions links (#436) --- README.md | 6 ++++++ packages/website/docs/intro/index.md | 4 ++++ packages/website/docusaurus.config.js | 5 +++++ packages/website/faq/index.md | 4 ++-- packages/website/src/components/BlogSection/index.tsx | 2 +- packages/website/src/components/Features/index.tsx | 2 +- 6 files changed, 19 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c1ac5e3a4ad..22b98df9b41 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,12 @@ Most documentation can be found on the website, at [taiko.xyz](https://taiko.xyz). There should also be a README in each package, as well as comments in the source code. +## Questions and discussions + +Ask questions and start discussions for new ideas under [GitHub Discussions](https://github.com/taikoxyz/taiko-mono/discussions). + +If you have a specific request/report, you can [open an issue](https://github.com/taikoxyz/taiko-mono/issues/new/choose). + ## Project structure
diff --git a/packages/website/docs/intro/index.md b/packages/website/docs/intro/index.md
index 7bb6274333e..7a39aa8557e 100644
--- a/packages/website/docs/intro/index.md
+++ b/packages/website/docs/intro/index.md
@@ -25,3 +25,7 @@ Here are the best places to learn about Taiko.
 - [GitHub](https://github.com/taikoxyz/)
 - [Reddit](https://www.reddit.com/r/taiko_xyz/)
 - [Twitter](https://twitter.com/taikoxyz)
+
+### Ask questions and start discussions
+
+You can ask questions and start discussions on our [GitHub Discussions](https://github.com/taikoxyz/taiko-mono/discussions).
diff --git a/packages/website/docusaurus.config.js b/packages/website/docusaurus.config.js
index 47f8b4e54cd..16de01d725f 100644
--- a/packages/website/docusaurus.config.js
+++ b/packages/website/docusaurus.config.js
@@ -102,6 +102,11 @@ const config = {
             label: "Blog",
             position: "left",
           },
+          {
+            href: "https://github.com/taikoxyz/taiko-mono/discussions",
+            label: "Discussions",
+            position: "left",
+          },
           {
             to: "talks",
             label: "Talks",
diff --git a/packages/website/faq/index.md b/packages/website/faq/index.md
index 1b3c2d615ac..d253de6e5b5 100644
--- a/packages/website/faq/index.md
+++ b/packages/website/faq/index.md
@@ -20,6 +20,7 @@ Here are the official links to our social media and public documentation:
 - Reddit: https://www.reddit.com/r/taiko_xyz/
 - Blog: https://mirror.xyz/labs.taiko.eth
 - GitHub: https://github.com/taikoxyz/
+- Discussions: https://github.com/taikoxyz/taiko-mono/discussions
 - Whitepaper: https://taikoxyz.github.io/taiko-mono/taiko-whitepaper.pdf
 
 ## What is Layer 2 (L2)?
@@ -64,8 +65,7 @@ There are 2 types of zero-knowledge proofs: ZK-SNARKs and ZK-STARKs. Taiko uses
 
 ## What does "Taiko" mean?
 
-It comes from an old Chinese saying 一鼓作气 (Yīgǔzuòqì) meaning "Do it all at once". 
+It comes from an old Chinese saying 一鼓作气 (Yīgǔzuòqì) meaning "Do it all at once".
 
 The first drum beat cheers people up, the second weakens them, and the third devitalizes them. The first is the most powerful.
 Taiko is the "drum".
-
diff --git a/packages/website/src/components/BlogSection/index.tsx b/packages/website/src/components/BlogSection/index.tsx
index 7bbbff5b026..e997b087738 100644
--- a/packages/website/src/components/BlogSection/index.tsx
+++ b/packages/website/src/components/BlogSection/index.tsx
@@ -86,7 +86,7 @@ export default function BlogSection(): JSX.Element {
                   />
                 
               
-
+
{post.category.name} diff --git a/packages/website/src/components/Features/index.tsx b/packages/website/src/components/Features/index.tsx index 79952c0397d..38fd95b46be 100644 --- a/packages/website/src/components/Features/index.tsx +++ b/packages/website/src/components/Features/index.tsx @@ -33,7 +33,7 @@ export default function Features() {
{features.map((feature) => (
-
+
From 8216cc156d77d76d24b1df957c98ffe02f36f426 Mon Sep 17 00:00:00 2001 From: dave | d1onys1us Date: Wed, 14 Dec 2022 23:38:48 -0500 Subject: [PATCH 5/7] feat(docs): update contributing guide (#437) --- CONTRIBUTING.md | 145 +++++++++++++++++++++--------------------------- 1 file changed, 62 insertions(+), 83 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1e69b90e697..c938c0781e5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,74 +1,93 @@ # Contributing guide -## Table of contents +This contributing guide is divided into the following sections: -1. [Issue guide](#issue-guide) -2. [Coding style guide](#coding-style-guide) -3. [Documentation style guide](#documentation-style-guide) -4. [Git workflow](#git-workflow) +1. [Make a contribution](#make-a-contribution) +2. [Claim a GitPOAP](#claim-a-gitpoap) +3. [Git standards](#git-standards) +4. [Documentation style guide](#documentation-style-guide) -## Issue guide +# Make a contribution -As an open source project, you are free to open issues and work on issues. Please comment on the issue discussion if you are thinking of contributing or picking something up, so as to not overlap on any work. +We use [GitHub issues](https://github.com/taikoxyz/taiko-mono/issues) to track work. We use [GitHub discussions](https://github.com/taikoxyz/taiko-mono/discussions) to ask questions and talk about ideas. -### Finding an issue to work on +## Opening a new issue -If you are looking for a good issue to start with, look for issues tagged with "good first issue". +If you are opening a new issue, try to be descriptive as possible. Also please check if an existing issue already exists for it already. -### Opening a new issue +## Working on an issue -If you are opening a new issue, try to be descriptive as possible. Also please check if an existing issue already exists for it already. +If you are looking for a good issue to start with, look for issues tagged with [good first issue](https://github.com/taikoxyz/taiko-mono/labels/good%20first%20issue). Once you've found an issue to work on, you can assign it to yourself on GitHub and/or leave a comment that you're picking it up. Take a look at our [git standards](#git-standards). -## Coding style guide +## Ask questions and start discussions -### Source code comments +You can participate in questions and discussions under our [GitHub discussions](https://github.com/taikoxyz/taiko-mono/discussions). -Follow the [NatSpec format](https://docs.soliditylang.org/en/v0.8.16/natspec-format.html) for documenting smart contract source code. Please adhere to a few additional standards: +# Claim a GitPOAP -- Choose `/** */` over `///` for multi-line NatSpec comments, to save column space -- Omit the usage of `@notice`, this will be automatically picked up so it will save column space and improve readability -- Take advantage of inheritance for docs (such as documenting the interface), if you need to specify inherited docs use `@inheritdoc` +We are rewarding community contributions with a GitPOAP. This guide explains the requirements to claim a GitPOAP. + +## XXXX Taiko Contributor GitPOAP -### Git standards +The XXXX Taiko Contributor GitPOAP is intended for anyone who makes a meaningful contribution to Taiko during the year XXXX. You can only earn this in the following ways: -#### Commits +- Receive an accepted answer under [GitHub Discussions](https://github.com/taikoxyz/taiko-mono/discussions) +- Merge in a change to one of [our GitHub repos](https://github.com/taikoxyz) + +## How do I receive my GitPOAP? + +There are two ways to receive a GitPOAP: + +- If you merged in a pull request, the gitpoap-bot should have left you a comment to receive your GitPOAP like so: + ![](/assets/images/2022-12-14-09-30-37.png) +- If you made another contribution which fits the requirements of the GitPOAP, please ping the team on Discord so we can issue a GitPOAP manually. + +# Git standards + +## Creating commits Try to specify the scope of your change via a [conventional commit](https://www.conventionalcommits.org/en/v1.0.0/) (eg. `enhance(docs): improve some section`) or specifying the scope in brackets (eg. `[docs] improve some section`). -## Documentation style guide +## Submitting a PR + +Please make sure to use a conventional commit in your PR title (eg. `feat(scope): description of feature`). This will be squashed and merged into the `main` branch. -### Document types +## GitHub Actions -Group documentation under one of the four categories: +Each commit will automatically trigger the GitHub Actions to run. If any commit message in your push or the HEAD commit of your PR contains the strings [skip ci], [ci skip], [no ci], [skip actions], or [actions skip] workflows triggered on the push or pull_request events will be skipped. -- Tutorials -- Guides -- Concepts -- Reference +# Documentation style guide + +Many standards are adopted from [Google dev docs highlights](https://developers.google.com/style/highlights). -### Philosophy +## Philosophy -- Aim for "better" instead of "perfect" -- any enhancement is a worthwhile improvement. -- Create the minimum viable documentation. +- Create the [minimum viable documentation](https://google.github.io/styleguide/docguide/best_practices.html#minimum-viable-documentation). - Don't repeat yourself, use links to existing documentation or inherit it. -- Generate documentation automatically from source code whenever possible. -- Keep your comments as close as possible to the actual source code it is describing. +- Keep documentation close to what it's describing, also called high cohesion (eg. describing a smart contract should be documented as comments in the source code). -### Standards +## Document types + +Group documentation under one of the four categories (adopted from [Diátaxis](https://diataxis.fr/)): + +- Tutorials +- Guides +- Concepts +- Reference -#### Tone and content +## Tone and content - [Use descriptive link text](https://developers.google.com/style/link-text). - [Write accessibly](https://developers.google.com/style/accessibility). - [Write for a global audience](https://developers.google.com/style/translation). -#### Language and grammar +## Language and grammar - [Use second person](https://developers.google.com/style/person): "you" rather than "we". - [Use active voice](https://developers.google.com/style/voice): make clear who's performing the action. - [Put conditional clauses before instructions](https://developers.google.com/style/clause-order), not after. -#### Formatting, punctuation, and organization +## Formatting, punctuation, and organization - [Use sentence case](https://developers.google.com/style/capitalization) for document titles and section headings. - [Use numbered lists](https://developers.google.com/style/lists#types-of-lists) for sequences. @@ -77,55 +96,15 @@ Group documentation under one of the four categories: - [Use serial commas](https://developers.google.com/style/commas). - [Use unambiguous date formatting](https://developers.google.com/style/dates-times). -#### Images +## Source code comments -- Use SVG files or crushed PNG images. -- Provide alt text. - -#### Code blocks - -- Do not use `$` in shell blocks. - - Incorrect ❌: - - ```sh - $ echo "this is worse for copy paste" - ``` - - Correct ✅: - - ```sh - echo "this is better for copy paste" - ``` - -- Escape new lines. - - Incorrect ❌: - - ```sh - echo "going to pretend that this" - && echo "is some really long command" - ``` - - Correct ✅: - - ```sh - echo "at least the command" \ - && echo "looks good when copy pastad" - ``` - -## Git workflow - -### Submitting a PR - -Please make sure to use a conventional commit in your PR title (eg. `feat(scope): description of feature`). This will be squashed and merged into the `main` branch. - -### GitHub Actions +Follow the [NatSpec format](https://docs.soliditylang.org/en/v0.8.16/natspec-format.html) for documenting smart contract source code. Please adhere to a few additional standards: -Each commit will automatically trigger the GitHub Actions to run. If any commit message in your push or the HEAD commit of your PR contains the strings [skip ci], [ci skip], [no ci], [skip actions], or [actions skip] workflows triggered on the push or pull_request events will be skipped. +- Choose `/** */` over `///` for multi-line NatSpec comments, to save column space +- Omit the usage of `@notice`, this will be automatically picked up so it will save column space and improve readability +- Take advantage of inheritance for docs (such as documenting the interface), if you need to specify inherited docs use `@inheritdoc` -## References +## Images -- [Diátaxis](https://diataxis.fr/) -- [Google dev docs highlights](https://developers.google.com/style/highlights) -- [Google docs styleguide](https://google.github.io/styleguide/docguide/) +- Use SVG files or crushed PNG images. +- Provide alt text. From e9fda8bb80ecfefcfd7d64062b50ebf5b5eec2ef Mon Sep 17 00:00:00 2001 From: jeff <113397187+cyberhorsey@users.noreply.github.com> Date: Wed, 14 Dec 2022 20:40:56 -0800 Subject: [PATCH 6/7] feat(relayer): header sync check before processing messages (#441) * header sync check before processing messages * rm gas limit + warn logs * get latest synced header after waiting * lint * use header by hash instead of block by hash --- packages/relayer/.default.env | 3 +- packages/relayer/.golangci.yml | 6 +- packages/relayer/cli/cli.go | 38 ++++++++----- packages/relayer/indexer/service.go | 56 ++++++++++--------- packages/relayer/indexer/subscribe.go | 13 +---- packages/relayer/message/process_message.go | 11 ++-- packages/relayer/message/processor.go | 30 +++++----- packages/relayer/message/processor_test.go | 21 +++---- .../relayer/message/wait_for_confirmations.go | 2 +- .../relayer/message/wait_header_synced.go | 55 ++++++++++++++++++ .../message/wait_header_synced_test.go | 21 +++++++ packages/relayer/mock/eth_client.go | 10 ++++ 12 files changed, 180 insertions(+), 86 deletions(-) create mode 100644 packages/relayer/message/wait_header_synced.go create mode 100644 packages/relayer/message/wait_header_synced_test.go diff --git a/packages/relayer/.default.env b/packages/relayer/.default.env index ecdfd7843b7..7445d2e4e49 100644 --- a/packages/relayer/.default.env +++ b/packages/relayer/.default.env @@ -18,4 +18,5 @@ MYSQL_CONN_MAX_LIFETIME_IN_MS= NUM_GOROUTINES=20 SUBSCRIPTION_BACKOFF_IN_SECONDS=3 CONFIRMATIONS_BEFORE_PROCESSING=15 -CORS_ORIGINS=* \ No newline at end of file +CORS_ORIGINS=* +HEADER_SYNC_INTERVAL_IN_SECONDS=60 \ No newline at end of file diff --git a/packages/relayer/.golangci.yml b/packages/relayer/.golangci.yml index 8408925a1d2..25aa24eb396 100644 --- a/packages/relayer/.golangci.yml +++ b/packages/relayer/.golangci.yml @@ -28,10 +28,10 @@ linters: linters-settings: funlen: - lines: 123 - statements: 50 + lines: 130 + statements: 52 gocognit: - min-complexity: 37 + min-complexity: 40 issues: exclude-rules: diff --git a/packages/relayer/cli/cli.go b/packages/relayer/cli/cli.go index 9a14f230964..ab4ba1adb80 100644 --- a/packages/relayer/cli/cli.go +++ b/packages/relayer/cli/cli.go @@ -42,10 +42,11 @@ var ( "PROMETHEUS_HTTP_PORT", } - defaultBlockBatchSize = 2 - defaultNumGoroutines = 10 - defaultSubscriptionBackoff = 2 * time.Second - defaultConfirmations = 15 + defaultBlockBatchSize = 2 + defaultNumGoroutines = 10 + defaultSubscriptionBackoff = 2 * time.Second + defaultConfirmations = 15 + defaultHeaderSyncIntervalSeconds int = 60 ) func Run( @@ -150,12 +151,17 @@ func makeIndexers( var subscriptionBackoff time.Duration subscriptionBackoffInSeconds, err := strconv.Atoi(os.Getenv("SUBSCRIPTION_BACKOFF_IN_SECONDS")) - if err != nil || numGoroutines <= 0 { + if err != nil || subscriptionBackoffInSeconds <= 0 { subscriptionBackoff = defaultSubscriptionBackoff } else { subscriptionBackoff = time.Duration(subscriptionBackoffInSeconds) * time.Second } + headerSyncIntervalInSeconds, err := strconv.Atoi(os.Getenv("HEADER_SYNC_INTERVAL_IN_SECONDS")) + if err != nil || headerSyncIntervalInSeconds <= 0 { + headerSyncIntervalInSeconds = defaultHeaderSyncIntervalSeconds + } + confirmations, err := strconv.Atoi(os.Getenv("CONFIRMATIONS_BEFORE_PROCESSING")) if err != nil || confirmations <= 0 { confirmations = defaultConfirmations @@ -198,11 +204,12 @@ func makeIndexers( DestTaikoAddress: common.HexToAddress(os.Getenv("L2_TAIKO_ADDRESS")), SrcTaikoAddress: common.HexToAddress(os.Getenv("L1_TAIKO_ADDRESS")), - BlockBatchSize: uint64(blockBatchSize), - NumGoroutines: numGoroutines, - SubscriptionBackoff: subscriptionBackoff, - Confirmations: uint64(confirmations), - ProfitableOnly: profitableOnly, + BlockBatchSize: uint64(blockBatchSize), + NumGoroutines: numGoroutines, + SubscriptionBackoff: subscriptionBackoff, + Confirmations: uint64(confirmations), + ProfitableOnly: profitableOnly, + HeaderSyncIntervalInSeconds: int64(headerSyncIntervalInSeconds), }) if err != nil { log.Fatal(err) @@ -225,11 +232,12 @@ func makeIndexers( DestBridgeAddress: common.HexToAddress(os.Getenv("L1_BRIDGE_ADDRESS")), DestTaikoAddress: common.HexToAddress(os.Getenv("L1_TAIKO_ADDRESS")), - BlockBatchSize: uint64(blockBatchSize), - NumGoroutines: numGoroutines, - SubscriptionBackoff: subscriptionBackoff, - Confirmations: uint64(confirmations), - ProfitableOnly: profitableOnly, + BlockBatchSize: uint64(blockBatchSize), + NumGoroutines: numGoroutines, + SubscriptionBackoff: subscriptionBackoff, + Confirmations: uint64(confirmations), + ProfitableOnly: profitableOnly, + HeaderSyncIntervalInSeconds: int64(headerSyncIntervalInSeconds), }) if err != nil { log.Fatal(err) diff --git a/packages/relayer/indexer/service.go b/packages/relayer/indexer/service.go index aa69bd1227d..8f4f1b824a4 100644 --- a/packages/relayer/indexer/service.go +++ b/packages/relayer/indexer/service.go @@ -50,22 +50,23 @@ type Service struct { } type NewServiceOpts struct { - EventRepo relayer.EventRepository - BlockRepo relayer.BlockRepository - EthClient *ethclient.Client - DestEthClient *ethclient.Client - RPCClient *rpc.Client - DestRPCClient *rpc.Client - ECDSAKey string - BridgeAddress common.Address - DestBridgeAddress common.Address - SrcTaikoAddress common.Address - DestTaikoAddress common.Address - BlockBatchSize uint64 - NumGoroutines int - SubscriptionBackoff time.Duration - Confirmations uint64 - ProfitableOnly relayer.ProfitableOnly + EventRepo relayer.EventRepository + BlockRepo relayer.BlockRepository + EthClient *ethclient.Client + DestEthClient *ethclient.Client + RPCClient *rpc.Client + DestRPCClient *rpc.Client + ECDSAKey string + BridgeAddress common.Address + DestBridgeAddress common.Address + SrcTaikoAddress common.Address + DestTaikoAddress common.Address + BlockBatchSize uint64 + NumGoroutines int + SubscriptionBackoff time.Duration + Confirmations uint64 + ProfitableOnly relayer.ProfitableOnly + HeaderSyncIntervalInSeconds int64 } func NewService(opts NewServiceOpts) (*Service, error) { @@ -144,17 +145,18 @@ func NewService(opts NewServiceOpts) (*Service, error) { } processor, err := message.NewProcessor(message.NewProcessorOpts{ - Prover: prover, - ECDSAKey: privateKey, - RPCClient: opts.RPCClient, - DestETHClient: opts.DestEthClient, - DestBridge: destBridge, - EventRepo: opts.EventRepo, - DestHeaderSyncer: destHeaderSyncer, - RelayerAddress: relayerAddr, - Confirmations: opts.Confirmations, - SrcETHClient: opts.EthClient, - ProfitableOnly: opts.ProfitableOnly, + Prover: prover, + ECDSAKey: privateKey, + RPCClient: opts.RPCClient, + DestETHClient: opts.DestEthClient, + DestBridge: destBridge, + EventRepo: opts.EventRepo, + DestHeaderSyncer: destHeaderSyncer, + RelayerAddress: relayerAddr, + Confirmations: opts.Confirmations, + SrcETHClient: opts.EthClient, + ProfitableOnly: opts.ProfitableOnly, + HeaderSyncIntervalSeconds: opts.HeaderSyncIntervalInSeconds, }) if err != nil { return nil, errors.Wrap(err, "message.NewProcessor") diff --git a/packages/relayer/indexer/subscribe.go b/packages/relayer/indexer/subscribe.go index 7d1a96216c1..e48dfabd452 100644 --- a/packages/relayer/indexer/subscribe.go +++ b/packages/relayer/indexer/subscribe.go @@ -9,7 +9,6 @@ import ( "github.com/pkg/errors" log "github.com/sirupsen/logrus" "github.com/taikoxyz/taiko-mono/packages/relayer/contracts" - "golang.org/x/sync/errgroup" ) // subscribe subscribes to latest events @@ -30,23 +29,17 @@ func (svc *Service) subscribe(ctx context.Context, chainID *big.Int) error { defer sub.Unsubscribe() - group, ctx := errgroup.WithContext(ctx) - - group.SetLimit(svc.numGoroutines) - for { select { case err := <-sub.Err(): return errors.Wrap(err, "sub.Err()") case event := <-sink: - group.Go(func() error { + go func() { err := svc.handleEvent(ctx, chainID, event) if err != nil { - log.Errorf("svc.handleEvent: %v", err) + log.Errorf("svc.subscribe, svc.handleEvent: %v", err) } - - return nil - }) + }() } } } diff --git a/packages/relayer/message/process_message.go b/packages/relayer/message/process_message.go index 0e06a94d232..325e373cdd6 100644 --- a/packages/relayer/message/process_message.go +++ b/packages/relayer/message/process_message.go @@ -32,6 +32,10 @@ func (p *Processor) ProcessMessage( return errors.Wrap(err, "p.waitForConfirmations") } + if err := p.waitHeaderSynced(ctx, event); err != nil { + return errors.Wrap(err, "p.waitHeaderSynced") + } + // get latest synced header since not every header is synced from L1 => L2, // and later blocks still have the storage trie proof from previous blocks. latestSyncedHeader, err := p.destHeaderSyncer.GetLatestSyncedHeader(&bind.CallOpts{}) @@ -39,12 +43,6 @@ func (p *Processor) ProcessMessage( return errors.Wrap(err, "taiko.GetSyncedHeader") } - // if header hasnt been synced, we are unable to process this message - if common.BytesToHash(latestSyncedHeader[:]).Hex() == relayer.ZeroHash.Hex() { - log.Infof("header not synced, bailing") - return nil - } - hashed := crypto.Keccak256( event.Raw.Address.Bytes(), // L1 bridge address event.Signal[:], @@ -69,6 +67,7 @@ func (p *Processor) ProcessMessage( // message will fail when we try to process it if !received { + log.Warnf("signal %v not received on dest chain", common.Hash(event.Signal).Hex()) return errors.New("message not received") } diff --git a/packages/relayer/message/processor.go b/packages/relayer/message/processor.go index f3d472a493e..f25a69a9622 100644 --- a/packages/relayer/message/processor.go +++ b/packages/relayer/message/processor.go @@ -16,6 +16,7 @@ type ethClient interface { PendingNonceAt(ctx context.Context, account common.Address) (uint64, error) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) BlockNumber(ctx context.Context) (uint64, error) + HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) } type Processor struct { eventRepo relayer.EventRepository @@ -35,21 +36,23 @@ type Processor struct { relayerAddr common.Address confirmations uint64 - profitableOnly relayer.ProfitableOnly + profitableOnly relayer.ProfitableOnly + headerSyncIntervalSeconds int64 } type NewProcessorOpts struct { - Prover *proof.Prover - ECDSAKey *ecdsa.PrivateKey - RPCClient relayer.Caller - SrcETHClient ethClient - DestETHClient ethClient - DestBridge relayer.Bridge - EventRepo relayer.EventRepository - DestHeaderSyncer relayer.HeaderSyncer - RelayerAddress common.Address - Confirmations uint64 - ProfitableOnly relayer.ProfitableOnly + Prover *proof.Prover + ECDSAKey *ecdsa.PrivateKey + RPCClient relayer.Caller + SrcETHClient ethClient + DestETHClient ethClient + DestBridge relayer.Bridge + EventRepo relayer.EventRepository + DestHeaderSyncer relayer.HeaderSyncer + RelayerAddress common.Address + Confirmations uint64 + ProfitableOnly relayer.ProfitableOnly + HeaderSyncIntervalSeconds int64 } func NewProcessor(opts NewProcessorOpts) (*Processor, error) { @@ -107,6 +110,7 @@ func NewProcessor(opts NewProcessorOpts) (*Processor, error) { relayerAddr: opts.RelayerAddress, confirmations: opts.Confirmations, - profitableOnly: opts.ProfitableOnly, + profitableOnly: opts.ProfitableOnly, + headerSyncIntervalSeconds: opts.HeaderSyncIntervalSeconds, }, nil } diff --git a/packages/relayer/message/processor_test.go b/packages/relayer/message/processor_test.go index 1125a050aef..f3d10981d36 100644 --- a/packages/relayer/message/processor_test.go +++ b/packages/relayer/message/processor_test.go @@ -26,16 +26,17 @@ func newTestProcessor(profitableOnly relayer.ProfitableOnly) *Processor { ) return &Processor{ - eventRepo: &mock.EventRepository{}, - destBridge: &mock.Bridge{}, - srcEthClient: &mock.EthClient{}, - destEthClient: &mock.EthClient{}, - mu: &sync.Mutex{}, - ecdsaKey: privateKey, - destHeaderSyncer: &mock.HeaderSyncer{}, - prover: prover, - rpc: &mock.Caller{}, - profitableOnly: profitableOnly, + eventRepo: &mock.EventRepository{}, + destBridge: &mock.Bridge{}, + srcEthClient: &mock.EthClient{}, + destEthClient: &mock.EthClient{}, + mu: &sync.Mutex{}, + ecdsaKey: privateKey, + destHeaderSyncer: &mock.HeaderSyncer{}, + prover: prover, + rpc: &mock.Caller{}, + profitableOnly: profitableOnly, + headerSyncIntervalSeconds: 1, } } func Test_NewProcessor(t *testing.T) { diff --git a/packages/relayer/message/wait_for_confirmations.go b/packages/relayer/message/wait_for_confirmations.go index f27333df304..600ac574a02 100644 --- a/packages/relayer/message/wait_for_confirmations.go +++ b/packages/relayer/message/wait_for_confirmations.go @@ -11,7 +11,7 @@ import ( func (p *Processor) waitForConfirmations(ctx context.Context, txHash common.Hash, blockNumber uint64) error { // TODO: make timeout a config var - ctx, cancelFunc := context.WithTimeout(ctx, 2*time.Minute) + ctx, cancelFunc := context.WithTimeout(ctx, 5*time.Minute) defer cancelFunc() diff --git a/packages/relayer/message/wait_header_synced.go b/packages/relayer/message/wait_header_synced.go new file mode 100644 index 00000000000..5175440c345 --- /dev/null +++ b/packages/relayer/message/wait_header_synced.go @@ -0,0 +1,55 @@ +package message + +import ( + "context" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" + log "github.com/sirupsen/logrus" + "github.com/taikoxyz/taiko-mono/packages/relayer/contracts" +) + +func (p *Processor) waitHeaderSynced(ctx context.Context, event *contracts.BridgeMessageSent) error { + ticker := time.NewTicker(time.Duration(p.headerSyncIntervalSeconds) * time.Second) + defer ticker.Stop() + + for { + select { + case <-ctx.Done(): + return ctx.Err() + case <-ticker.C: + // get latest synced header since not every header is synced from L1 => L2, + // and later blocks still have the storage trie proof from previous blocks. + latestSyncedHeader, err := p.destHeaderSyncer.GetLatestSyncedHeader(&bind.CallOpts{}) + if err != nil { + return errors.Wrap(err, "p.destHeaderSyncer.GetLatestSyncedHeader") + } + + header, err := p.srcEthClient.HeaderByHash(ctx, latestSyncedHeader) + if err != nil { + return errors.Wrap(err, "p.destHeaderSyncer.GetLatestSyncedHeader") + } + + // header is caught up and processible + if header.Number.Uint64() >= event.Raw.BlockNumber { + log.Infof( + "signal: %v is processable. occured in block %v, latestSynced is block %v", + common.Hash(event.Signal).Hex(), + event.Raw.BlockNumber, + header.Number.Uint64(), + ) + + return nil + } + + log.Infof( + "signal: %v waiting to be processable. occured in block %v, latestSynced is block %v", + common.Hash(event.Signal).Hex(), + event.Raw.BlockNumber, + header.Number.Uint64(), + ) + } + } +} diff --git a/packages/relayer/message/wait_header_synced_test.go b/packages/relayer/message/wait_header_synced_test.go new file mode 100644 index 00000000000..a8bc0f43abc --- /dev/null +++ b/packages/relayer/message/wait_header_synced_test.go @@ -0,0 +1,21 @@ +package message + +import ( + "context" + "testing" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/assert" + "github.com/taikoxyz/taiko-mono/packages/relayer/contracts" +) + +func Test_waitHeaderSynced(t *testing.T) { + p := newTestProcessor(true) + + err := p.waitHeaderSynced(context.TODO(), &contracts.BridgeMessageSent{ + Raw: types.Log{ + BlockNumber: 1, + }, + }) + assert.Nil(t, err) +} diff --git a/packages/relayer/mock/eth_client.go b/packages/relayer/mock/eth_client.go index b7cca8a08e6..c8ec2e135ed 100644 --- a/packages/relayer/mock/eth_client.go +++ b/packages/relayer/mock/eth_client.go @@ -2,11 +2,13 @@ package mock import ( "context" + "errors" "math/big" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/taikoxyz/taiko-mono/packages/relayer" ) var ( @@ -61,3 +63,11 @@ func (c *EthClient) TransactionReceipt(ctx context.Context, txHash common.Hash) func (c *EthClient) BlockNumber(ctx context.Context) (uint64, error) { return uint64(BlockNum), nil } + +func (c *EthClient) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) { + if hash == relayer.ZeroHash { + return nil, errors.New("cant find block") + } + + return Header, nil +} From ba3b73a5f9de529c947622e5ed268af3dcfdf298 Mon Sep 17 00:00:00 2001 From: Django <109468867+django-onchain@users.noreply.github.com> Date: Thu, 15 Dec 2022 12:57:10 +0800 Subject: [PATCH 7/7] chore(website): update the section on What does Taiko mean (#424) --- packages/website/faq/index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/website/faq/index.md b/packages/website/faq/index.md index d253de6e5b5..b5d757cbf8c 100644 --- a/packages/website/faq/index.md +++ b/packages/website/faq/index.md @@ -65,7 +65,7 @@ There are 2 types of zero-knowledge proofs: ZK-SNARKs and ZK-STARKs. Taiko uses ## What does "Taiko" mean? -It comes from an old Chinese saying 一鼓作气 (Yīgǔzuòqì) meaning "Do it all at once". +It comes from an old Chinese saying 一鼓作气 (Yīgǔzuòqì). The literal meaning is that the first drum beat arouses courage. The implied meaning of the idiom is to accomplish a task or goal in one intense effort. + +Taiko (太鼓) is the Japanese term for a drum. For us, Taiko is the "drum" that arouses courage and leads to accomplishing goals. -The first drum beat cheers people up, the second weakens them, and the third devitalizes them. The first is the most powerful. -Taiko is the "drum".