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".