Skip to content

Commit

Permalink
feat(bridge): implement the bridge relayer (#191)
Browse files Browse the repository at this point in the history
* bridge tests, WIP

* wip on a relayer. golang backend syncing ethereum messages to a the database. able to 'catch up'. also, a hideous UI for me to test sending messages from.

* default provider

* message processing/proof generation

* wip

* abi types

* web3 library for simpler ABI

* rm unneeded deps

* wip...

* types

* refactor, cleanup

* handleEvent func

* rf

* comments

* wip

* whole lotta WIP...

* remove test things

* wip tests + githubactions

* test/moving/renaming

* gha

* rlp encoding is a yes, everything else massive WIP and logging...

* abi encoding + rlp encodng working and decoding, still reverting tho

* cleanup

* rm console logs, add V1TaikoL2 bindings, try to see if message is verified first

* wip

* refactor to separate servces

* block header test for proof

* fix some tests

* Crosslayer => dest

* logs, tests

* estimate gas

* add iHeaderSync to relayer

* block hash

* block hash

* tests

* storageproof test

* signal proof encoding test

* log cleanup

* wip

* default env

* l1_taiko_addr

* tests

* rm hardcoded block

* comment

* processing works!

* Update auto-generated docs

* CLI args

* remove temp bridge ui

* Update auto-generated docs

* separate dependencies out to interfaces in prover

* Update auto-generated docs

* tests

* Update auto-generated docs

* sol lints

* Update auto-generated docs

* event FindAllByAddress

* Update auto-generated docs

* Update packages/protocol/test/test_integration.sh

Co-authored-by: David <[email protected]>

* remove unused imports

* Update packages/protocol/contracts/test/libs/TestLibTrieProof.sol

Co-authored-by: David <[email protected]>

* mysql_password is optional

* separate DSN w/o mysql pw

* Update auto-generated docs

* Update packages/relayer/indexer/filter_then_subscribe.go

Co-authored-by: David <[email protected]>

* Update auto-generated docs

* check if message owner is relayer addr

* Update packages/relayer/indexer/filter_then_subscribe.go

Co-authored-by: David <[email protected]>

* Update auto-generated docs

* golangcilint job + check err for CallContext

* wait for receipt + check status in process_message

* change hashing to go-ethereum lib

* Update auto-generated docs

* abigen script, remove abis, add to gitignore

* skip-dirs

* Update auto-generated docs

* lints

* lints

* Update auto-generated docs

* pass config file to gha

* args

* args

* latest

* Update auto-generated docs

* use go 1.19

* Update auto-generated docs

* basic readme

* Update auto-generated docs

* goose

* Update auto-generated docs

* receipt fixes for unnecessary status check, remove dead code

Co-authored-by: cyberhorsey <[email protected]>
Co-authored-by: David <[email protected]>
  • Loading branch information
3 people authored Nov 11, 2022
1 parent ebf6aa6 commit 9f49e4c
Show file tree
Hide file tree
Showing 58 changed files with 7,210 additions and 18 deletions.
47 changes: 47 additions & 0 deletions .github/workflows/golang.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Golang

on:
push:
branches: [main]
paths:
- "packages/relayer/**"
pull_request:
paths:
- "packages/relayer/**"

jobs:
lint:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/setup-go@v3
with:
go-version: 1.19
- uses: actions/checkout@v3
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
# Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version
version: latest

# Optional: working directory, useful for monorepos
working-directory: ./packages/relayer
args: --config=.golangci.yml

build:
runs-on: ubuntu-latest
needs: lint
steps:
- name: Cancel Previous Runs
uses: styfle/[email protected]
with:
access_token: ${{ github.token }}

- uses: actions/checkout@v3
- uses: actions/setup-go@v3
with:
go-version: ">=1.19.0"

- name: relayer - Unit Tests
working-directory: ./packages/relayer
run: go test ./... -count=1
71 changes: 71 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
module github.com/taikochain/taiko-mono

go 1.19

replace github.com/umbracle/ethgo => ../../ethgo

require (
github.com/cyberhorsey/errors v0.0.0-20220929234051-087d6d8bb841
github.com/ethereum/go-ethereum v1.10.25
github.com/joho/godotenv v1.4.0
github.com/pkg/errors v0.9.1
github.com/pressly/goose/v3 v3.7.0
github.com/sirupsen/logrus v1.9.0
github.com/stretchr/testify v1.8.0
github.com/testcontainers/testcontainers-go v0.15.0
gopkg.in/go-playground/assert.v1 v1.2.1
gorm.io/datatypes v1.0.7
gorm.io/driver/mysql v1.4.3
gorm.io/gorm v1.24.0
)

require (
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/Microsoft/go-winio v0.5.2 // indirect
github.com/Microsoft/hcsshim v0.9.4 // indirect
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
github.com/containerd/cgroups v1.0.4 // indirect
github.com/containerd/containerd v1.6.8 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/deckarep/golang-set v1.8.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
github.com/docker/distribution v2.8.1+incompatible // indirect
github.com/docker/docker v20.10.17+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/go-ole/go-ole v1.2.1 // indirect
github.com/go-sql-driver/mysql v1.6.0 // indirect
github.com/go-stack/stack v1.8.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gorilla/websocket v1.4.2 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/magiconair/properties v1.8.6 // indirect
github.com/moby/sys/mount v0.3.3 // indirect
github.com/moby/sys/mountinfo v0.6.2 // indirect
github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect
github.com/opencontainers/runc v1.1.3 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rjeczalik/notify v0.9.1 // indirect
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect
github.com/tklauser/go-sysconf v0.3.5 // indirect
github.com/tklauser/numcpus v0.2.2 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
go.opencensus.io v0.23.0 // indirect
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect
golang.org/x/net v0.0.0-20220812174116-3211cb980234 // indirect
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect
google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad // indirect
google.golang.org/grpc v1.47.0 // indirect
google.golang.org/protobuf v1.28.0 // indirect
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
1,324 changes: 1,324 additions & 0 deletions go.sum

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions packages/protocol/test/bridge/libs/LibBridgeData.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,33 @@ describe("LibBridgeData", function () {

expect(expectedHash).to.be.eq(hashed)
})

it("should return properly hashed message from actual bridge message", async function () {
const { libData } = await deployLibBridgeDataFixture()
// dummy struct to test with

const testMessage = {
id: 0,
sender: "0xDA1Ea1362475997419D2055dD43390AEE34c6c37",
srcChainId: 31336,
destChainId: 167001,
owner: "0x4Ec242468812B6fFC8Be8FF423Af7bd23108d991",
to: "0xF58b02228125baF4B232FF3F2f66F8b9229d5177",
refundAddress: "0x4Ec242468812B6fFC8Be8FF423Af7bd23108d991",
depositValue: 0,
callValue: 0,
processingFee: 0,
gasLimit: 1000000,
data: "0x0c6fab8200000000000000000000000000000000000000000000000000000000000000800000000000000000000000004ec242468812b6ffc8be8ff423af7bd23108d9910000000000000000000000004ec242468812b6ffc8be8ff423af7bd23108d99100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000007a68000000000000000000000000e48a03e23449975df36603c93f59a15e2de75c74000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000004544553540000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000095465737445524332300000000000000000000000000000000000000000000000",
memo: "CronJob SendTokens",
}

const hashed = await libData.hashMessage(testMessage)

expect(
"0xea159ca9f8fa8d139853755222c652413568310fab38095f5700286155a5179b"
).to.be.eq(hashed)
})
})

describe("updateMessageStatus()", async function () {
Expand Down
7 changes: 4 additions & 3 deletions packages/protocol/test/bridge/libs/LibBridgeSignal.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { expect } from "chai"
import { ethers } from "hardhat"
import { TestLibBridgeSignal } from "../../../typechain"

describe("LibBridgeSignal", function () {
describe("integration:LibBridgeSignal", function () {
async function deployLibBridgeSignalFixture() {
const [owner, nonOwner] = await ethers.getSigners()

const libSignal = await (
const libSignal: TestLibBridgeSignal = await (
await ethers.getContractFactory("TestLibBridgeSignal")
).deploy()

Expand All @@ -15,7 +16,7 @@ describe("LibBridgeSignal", function () {
srcChainId: 1,
destChainId: 2,
owner: owner.address,
to: nonOwner.address,
to: owner.address,
refundAddress: owner.address,
depositValue: 0,
callValue: 0,
Expand Down
19 changes: 5 additions & 14 deletions packages/protocol/test/libs/LibTrieProof.test.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,11 @@
import { expect } from "chai"
import { ENOBUFS } from "constants"
import { BigNumber } from "ethers"
import { ethers } from "hardhat"
import RLP from "rlp"
import { Message } from "../utils/message"
import { EthGetProofResponse } from "../utils/rpc"

type StorageEntry = {
key: string
value: string
proof: string[] // Array of rlp-serialized MerkleTree-Nodes, starting with the storageHash-Node,
}
type EthGetProofResponse = {
balance: string
codeHash: string
nonce: string
storageHash: string
accountProof: string[] // array of rlp-serialized merkle nodes beginning with stateRoot-node
storageProof: StorageEntry[]
}
describe("integration:LibTrieProof", function () {
async function deployLibTrieProofFixture() {
const libTrieProof = await (
Expand All @@ -39,7 +29,7 @@ describe("integration:LibTrieProof", function () {

await addressManager.setAddress(
`${chainId}.ether_vault`,
"0x02E725B7e99091Bd4cCBf15228384e160eCdf78f"
"0xEA3dD11036f668F08940E13e3bcB097C93b09E07"
)

const libBridgeRetry = await (
Expand Down Expand Up @@ -67,6 +57,7 @@ describe("integration:LibTrieProof", function () {
await bridge.init(addressManager.address)

const [owner] = await ethers.getSigners()

return { owner, testLibTreProof, bridge }
}
describe("verify()", function () {
Expand Down
2 changes: 1 addition & 1 deletion packages/protocol/test/test_integration.sh
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,4 @@ trap "docker rm --force $TEST_NODE_CONTAINER_NAME $TEST_IMPORT_TEST_ACCOUNT_ETH_

# Run the tests
PRIVATE_KEY=$TEST_ACCOUNT_PRIV_KEY \
pnpm hardhat test --network l1_test --grep "^integration"
pnpm hardhat test --network l1_test --grep "^integration"
61 changes: 61 additions & 0 deletions packages/protocol/test/utils/rpc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { BigNumber } from "ethers"

type StorageEntry = {
key: string
value: string
proof: string[] // Array of rlp-serialized MerkleTree-Nodes, starting with the storageHash-Node,
}

type EthGetProofResponse = {
balance: string
codeHash: string
nonce: string
storageHash: string
accountProof: string[] // array of rlp-serialized merkle nodes beginning with stateRoot-node
storageProof: StorageEntry[]
}

type Block = {
number: number
hash: string
parentHash: string
nonce: number
sha3Uncles: string
logsBloom: string[]
transactionsRoot: string
stateRoot: string
receiptsRoot: string
miner: string
difficulty: number
totalDifficulty: number
extraData: string
size: number
gasLimit: number
gasUsed: number
timestamp: number
transactions: string[]
uncles: string[]
baseFeePerGas?: string
mixHash: string
}

type BlockHeader = {
parentHash: string
ommersHash: string
beneficiary: string
stateRoot: string
transactionsRoot: string
receiptsRoot: string
logsBloom: string[]
difficulty: number
height: number
gasLimit: number
gasUsed: number
timestamp: number
extraData: string
mixHash: string
nonce: number
baseFeePerGas: BigNumber
}

export { Block, BlockHeader, StorageEntry, EthGetProofResponse }
10 changes: 10 additions & 0 deletions packages/relayer/.default.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
HTTP_PORT=4102
MYSQL_USER=root
MYSQL_PASSWORD=root
MYSQL_DATABASE=relayer
MYSQL_HOST=localhost:3306
RELAYER_ECDSA_KEY=
L1_BRIDGE_ADDRESS=0xa566811E9E63e4F573Df89d5453bB89F239F7e10
L2_BRIDGE_ADDRESS=0xa566811E9E63e4F573Df89d5453bB89F239F7e10
L1_RPC_URL="wss://eth-goerli.g.alchemy.com/v2/bPAA5rQ42Zoo4ts9TYnTB2t0cuc5lf7_"
L2_RPC_URL="wss://rinkeby-light.eth.linkpool.io/ws"
47 changes: 47 additions & 0 deletions packages/relayer/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
.netrc
.env
.test.env
main
coverage/profile.cov
coverage/gitlab.xml

# Local .terraform directories
.terraform

# .tfstate files
*.tfstate
*.tfstate.*

# Crash log files
crash.log

# Exclude all .tfvars files, which are likely to contain sentitive data, such as
# password, private keys, and other secrets. These should not be part of version
# control as they are data points which are potentially sensitive and subject
# to change depending on the environment.
#
*.tfvars

# Ignore override files as they are usually used to override resources locally and so
# are not checked in
override.tf
override.tf.json
*_override.tf
*_override.tf.json

# Include override files you do wish to add to version control using negated pattern
#
# !example_override.tf

# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
# example: *tfplan*

# Ignore CLI configuration files
.terraformrc
terraform.rc

.idea

Bridge.json
V1TaikoL2.json
IHeaderSync.json
42 changes: 42 additions & 0 deletions packages/relayer/.golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# See: https://golangci-lint.run/usage/configuration/
#
# Note: for VSCode, you must have the following settings to use this configuration:
#
# "go.lintTool": "golangci-lint",
# "go.lintFlags": [
# "--fast",
# "--config=${workspaceFolder}/.golangci.yml"
# ],

output:
format: colored-line-number

linters:
enable:
- funlen
- gocognit
- gocritic
- gofmt
- golint
- gosec
- lll
- whitespace
- wsl

linters-settings:
funlen:
lines: 100
statements: 45
gocognit:
min-complexity: 32

issues:
exclude-rules:
# Exclude some linters from running on tests files.
- path: _test\.go
linters:
- funlen

run:
skip-dirs:
- contracts/*
Loading

0 comments on commit 9f49e4c

Please sign in to comment.