From 8970e6d09cb80e277cc004acddfc4c87b50e6075 Mon Sep 17 00:00:00 2001 From: Ishan Date: Wed, 17 Jan 2024 12:17:01 +0100 Subject: [PATCH 01/13] =?UTF-8?q?=F0=9F=8C=B1=20Add=20chain=20utils?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 8 ++ go.mod | 39 +++++++- go.sum | 192 ++++++++++++++++++++++++++++++++++++++- pkg/chain/chain.go | 86 ++++++++++++++++++ pkg/chain/chain_mocks.go | 59 ++++++++++++ pkg/chain/chain_test.go | 119 ++++++++++++++++++++++++ pkg/chain/eth_client.go | 64 +++++++++++++ 7 files changed, 563 insertions(+), 4 deletions(-) create mode 100644 pkg/chain/chain_mocks.go create mode 100644 pkg/chain/chain_test.go create mode 100644 pkg/chain/eth_client.go diff --git a/Makefile b/Makefile index ffb9b7d..83d8818 100644 --- a/Makefile +++ b/Makefile @@ -8,11 +8,19 @@ test: @echo "Test packages" @go test -race -shuffle=on -coverprofile=coverage.out -cover $(PKGS) +test.coverage: test + go tool cover -func=coverage.out + +test.coverage.html: test + go tool cover -html=coverage.out + lint: @go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest golangci-lint run + format: gofmt -s -w . + godocs: @go install golang.org/x/tools/cmd/godoc@latest @echo "open http://localhost:6060/pkg/github.com/LiskHQ/op-fault-detector" diff --git a/go.mod b/go.mod index beecaed..c9c98d0 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,41 @@ module github.com/LiskHQ/op-fault-detector go 1.21.5 -require go.uber.org/zap v1.26.0 +require ( + github.com/ethereum/go-ethereum v1.13.10 + github.com/stretchr/testify v1.8.4 + go.uber.org/zap v1.26.0 +) -require go.uber.org/multierr v1.10.0 // indirect +require ( + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/StackExchange/wmi v1.2.1 // indirect + github.com/bits-and-blooms/bitset v1.10.0 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect + github.com/consensys/bavard v0.1.13 // indirect + github.com/consensys/gnark-crypto v0.12.1 // indirect + github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/deckarep/golang-set/v2 v2.1.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect + github.com/ethereum/c-kzg-4844 v0.4.0 // indirect + github.com/go-ole/go-ole v1.2.5 // indirect + github.com/gorilla/websocket v1.4.2 // indirect + github.com/holiman/uint256 v1.2.4 // indirect + github.com/mmcloughlin/addchain v0.4.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect + github.com/stretchr/objx v0.5.0 // indirect + github.com/supranational/blst v0.3.11 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect + go.uber.org/multierr v1.10.0 // indirect + golang.org/x/crypto v0.17.0 // indirect + golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect + golang.org/x/mod v0.14.0 // indirect + golang.org/x/sync v0.5.0 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/tools v0.15.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + rsc.io/tmplfunc v0.0.3 // indirect +) diff --git a/go.sum b/go.sum index f39e3a4..6bd8bfe 100644 --- a/go.sum +++ b/go.sum @@ -1,14 +1,202 @@ +github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= +github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= +github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= +github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= +github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bits-and-blooms/bitset v1.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88= +github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k= +github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cockroachdb/errors v1.8.1 h1:A5+txlVZfOqFBDa4mGz2bUWSp0aHElvHX2bKkdbQu+Y= +github.com/cockroachdb/errors v1.8.1/go.mod h1:qGwQn6JmZ+oMjuLwjWzUNqblqk0xl4CVV3SQbGwK7Ac= +github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f h1:o/kfcElHqOiXqcou5a3rIlMc7oJbMQkeLk0VQJ7zgqY= +github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= +github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 h1:aPEJyR4rPBvDmeyi+l/FS/VtA00IWvjeFvjen1m1l1A= +github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593/go.mod h1:6hk1eMY/u5t+Cf18q5lFMUA1Rc+Sm5I6Ra1QuPyxXCo= +github.com/cockroachdb/redact v1.0.8 h1:8QG/764wK+vmEYoOlfobpe12EQcS81ukx/a4hdVMxNw= +github.com/cockroachdb/redact v1.0.8/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2 h1:IKgmqgMQlVJIZj19CdocBeSfSaiCbEBZGKODaixqtHM= +github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2/go.mod h1:8BT+cPK6xvFOcRlk0R8eg+OTkcqI6baNH4xAkpiYVvQ= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= +github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= +github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= +github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= +github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 h1:d28BXYi+wUpz1KBmiF9bWrjEMacUEREV6MBi2ODnrfQ= +github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= +github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBShovmncxvA= +github.com/crate-crypto/go-kzg-4844 v0.7.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= +github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= +github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= +github.com/ethereum/go-ethereum v1.13.10 h1:Ppdil79nN+Vc+mXfge0AuUgmKWuVv4eMqzoIVSdqZek= +github.com/ethereum/go-ethereum v1.13.10/go.mod h1:sc48XYQxCzH3fG9BcrXCOOgQk2JfZzNAmIKnceogzsA= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= +github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= +github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 h1:BAIP2GihuqhwdILrV+7GJel5lyPV3u1+PgzrWLc0TkE= +github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46/go.mod h1:QNpY22eby74jVhqH4WhDLDwxc/vqsern6pW+u2kbkpc= +github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY= +github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= +github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= +github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 h1:3JQNjnMRil1yD0IfZKHF9GxxWKDJGj8I0IqOUol//sw= +github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= +github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= +github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= +github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= +github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= +github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= +github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= +github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= +github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= +github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= +github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/prometheus/client_golang v1.12.0 h1:C+UIj/QWtmqY13Arb8kwMt5j34/0Z2iKamrJ+ryC0Gg= +github.com/prometheus/client_golang v1.12.0/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a h1:CmF68hwI0XsOQ5UwlBopMi2Ow4Pbg32akc4KIVCOm+Y= +github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= +github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= +github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= +github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= +github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= +github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8= +golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk= +google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= +rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= diff --git a/pkg/chain/chain.go b/pkg/chain/chain.go index d65013d..8756920 100644 --- a/pkg/chain/chain.go +++ b/pkg/chain/chain.go @@ -1,2 +1,88 @@ // Package chain implements everything related to interaction with smart contracts, rpcprovider, etc package chain + +import ( + "context" + "math/big" + + "github.com/LiskHQ/op-fault-detector/pkg/log" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" +) + +type ChainAPIClient struct { + client *APIClient + log log.Logger +} + +// NewChainAPIClient returns a [ChainAPIClient], wrapping all RPC endpoints to access chain related data. +func NewChainAPIClient(log log.Logger) (*ChainAPIClient, error) { + return &ChainAPIClient{ + log: log, + }, nil +} + +func (c *ChainAPIClient) Connect(ethClientObj EthClientInterface, url string) { + client, err := ethClientObj.Dial(url) + if err != nil { + c.log.Errorf("Error occurred while connecting %w", err) + } + c.client = NewAPIClient(client) +} + +// Returns chainID of the connected node. +func (c *ChainAPIClient) GetChainID() (*big.Int, error) { + chainID, err := c.client.ChainID(context.Background()) + if err != nil { + return nil, err + } + + return chainID, nil +} + +// Returns latest block number from the connected node. +func (c *ChainAPIClient) GetLatestBlockNumber() (uint64, error) { + blockNumber, err := c.client.BlockNumber(context.Background()) + if err != nil { + return 0, err + } + + return blockNumber, nil +} + +// Returns block for a given block number from the connected node. +func (c *ChainAPIClient) GetBlockByNumber(blockNumber *big.Int) (*types.Block, error) { + block, err := c.client.BlockByNumber(context.Background(), blockNumber) + if err != nil { + return nil, err + } + + return block, nil +} + +type ProofResponse struct { + Address common.Address `json:"address"` + AccountProof []hexutil.Bytes `json:"accountProof"` + Balance *hexutil.Big `json:"balance"` + CodeHash common.Hash `json:"codeHash"` + Nonce hexutil.Uint64 `json:"nonce"` + StorageHash common.Hash `json:"storageHash"` + StorageProof []common.Hash `json:"storageProof"` +} + +const ( + RPCEndpointGetProof = "eth_getProof" +) + +// Returns the account and storage values, including the Merkle proof, of the specified account/address. +func (c *ChainAPIClient) GetProof(blockNumber *big.Int, address string) (*ProofResponse, error) { + var result ProofResponse + + rpcClient := &RPCClient{c.client} + if err := rpcClient.Call(&result, RPCEndpointGetProof, address, []string{}, hexutil.EncodeBig(blockNumber)); err != nil { + return nil, err + } + + return &result, nil +} diff --git a/pkg/chain/chain_mocks.go b/pkg/chain/chain_mocks.go new file mode 100644 index 0000000..4a29e57 --- /dev/null +++ b/pkg/chain/chain_mocks.go @@ -0,0 +1,59 @@ +package chain + +import ( + "context" + "math/big" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rpc" + "github.com/stretchr/testify/mock" +) + +// Mock function + +type MockEthClient struct { + mock.Mock +} + +func (e *MockEthClient) Dial(url string) (APIClientInterface, error) { + ret := e.Called(url) + + return ret.Get(0).(APIClientInterface), ret.Error(1) +} + +type MockAPIClient struct { + mock.Mock +} + +func (c *MockAPIClient) ChainID(ctx context.Context) (*big.Int, error) { + ret := c.Called(ctx) + + return ret.Get(0).(*big.Int), ret.Error(1) +} +func (c *MockAPIClient) BlockNumber(ctx context.Context) (uint64, error) { + ret := c.Called(ctx) + + return ret.Get(0).(uint64), ret.Error(1) +} +func (c *MockAPIClient) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) { + ret := c.Called(ctx, number) + + return ret.Get(0).(*types.Block), ret.Error(1) +} +func (c *MockAPIClient) Client() *rpc.Client { + ret := c.Called() + + return ret.Get(0).(*rpc.Client) +} + +type MockRPCClient struct { + mock.Mock +} + +func (c *MockAPIClient) Call(result interface{}, method string, args ...interface{}) error { + ret := c.Called() + + ptr := &result + *ptr = ret.Get(0) + return ret.Error(1) +} diff --git a/pkg/chain/chain_test.go b/pkg/chain/chain_test.go new file mode 100644 index 0000000..5fbfe4c --- /dev/null +++ b/pkg/chain/chain_test.go @@ -0,0 +1,119 @@ +package chain + +import ( + "context" + "math/big" + "testing" + "time" + + "github.com/LiskHQ/op-fault-detector/pkg/log" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/assert" +) + +const ( + fake_url = "localhost:8080" +) + +func TestNewChainAPIClient(t *testing.T) { + log := log.DefaultLogger + + chainClient, _ := NewChainAPIClient(log) + assert.Equal(t, chainClient.log, log) +} + +func TestConnect(t *testing.T) { + log := log.DefaultLogger + ethClientMock := &MockEthClient{} + + apiClientMock := &MockAPIClient{} + ethClientMock.On("Dial", fake_url).Return(apiClientMock, nil) + + chainClient, _ := NewChainAPIClient(log) + chainClient.Connect(ethClientMock, fake_url) + + assert.Equal(t, chainClient.log, log) +} + +func TestGetChainID(t *testing.T) { + log := log.DefaultLogger + ethClientMock := &MockEthClient{} + + apiClientMock := &MockAPIClient{} + ethClientMock.On("Dial", fake_url).Return(apiClientMock, nil) + + chainClient, _ := NewChainAPIClient(log) + chainClient.Connect(ethClientMock, fake_url) + + assert.Equal(t, chainClient.log, log) + + expectedChainID := big.NewInt(2) + apiClientMock.On("ChainID", context.Background()).Return(expectedChainID, nil) + receivedChainID, _ := chainClient.GetChainID() + assert.Equal(t, expectedChainID, receivedChainID) +} + +func TestGetLatestBlockNumber(t *testing.T) { + log := log.DefaultLogger + ethClientMock := &MockEthClient{} + + apiClientMock := &MockAPIClient{} + ethClientMock.On("Dial", fake_url).Return(apiClientMock, nil) + + chainClient, _ := NewChainAPIClient(log) + chainClient.Connect(ethClientMock, fake_url) + + assert.Equal(t, chainClient.log, log) + + expectedLatestBlockNumber := uint64(12345) + apiClientMock.On("BlockNumber", context.Background()).Return(expectedLatestBlockNumber, nil) + receivedLatestBlockNumber, _ := chainClient.GetLatestBlockNumber() + assert.Equal(t, expectedLatestBlockNumber, receivedLatestBlockNumber) +} + +func TestGetBlockByNumber(t *testing.T) { + log := log.DefaultLogger + ethClientMock := &MockEthClient{} + + apiClientMock := &MockAPIClient{} + ethClientMock.On("Dial", fake_url).Return(apiClientMock, nil) + + chainClient, _ := NewChainAPIClient(log) + chainClient.Connect(ethClientMock, fake_url) + + assert.Equal(t, chainClient.log, log) + + blockNumber := big.NewInt(800) + expectedBlock := &types.Block{ + ReceivedAt: time.Now(), + } + apiClientMock.On("BlockByNumber", context.Background(), blockNumber).Return(expectedBlock, nil) + receivedBlock, _ := chainClient.GetBlockByNumber(blockNumber) + assert.Equal(t, expectedBlock, receivedBlock) +} + +func TestGetProof(t *testing.T) { + t.Skip("skipping testing") + log := log.DefaultLogger + ethClientMock := &MockEthClient{} + + apiClientMock := &MockAPIClient{} + ethClientMock.On("Dial", fake_url).Return(apiClientMock, nil) + + chainClient, _ := NewChainAPIClient(log) + chainClient.Connect(ethClientMock, fake_url) + + assert.Equal(t, chainClient.log, log) + + rpcClientMock := &MockRPCClient{} + apiClientMock.On("Client").Return(rpcClientMock, nil) + + address := common.Address{} + blockNumber := big.NewInt(800) + proofResponseExpected := &ProofResponse{} + rpcClientMock.On("Call", proofResponseExpected, RPCEndpointGetProof, address, []string{}, hexutil.EncodeBig(blockNumber)).Return(nil) + proofResponseRecieved, _ := chainClient.GetProof(blockNumber, address.Hex()) + assert.Equal(t, proofResponseExpected, proofResponseRecieved) +} diff --git a/pkg/chain/eth_client.go b/pkg/chain/eth_client.go new file mode 100644 index 0000000..5315464 --- /dev/null +++ b/pkg/chain/eth_client.go @@ -0,0 +1,64 @@ +package chain + +import ( + "context" + "math/big" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/rpc" +) + +type EthClientInterface interface { + Dial(url string) (APIClientInterface, error) +} + +type EthClient struct{} + +func (e *EthClient) Dial(url string) (APIClientInterface, error) { + client, err := ethclient.Dial(url) + if err != nil { + return nil, err + } + + return client, nil +} + +type APIClientInterface interface { + ChainID(ctx context.Context) (*big.Int, error) + BlockNumber(ctx context.Context) (uint64, error) + BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) + Client() *rpc.Client +} + +type APIClient struct { + client APIClientInterface +} + +func NewAPIClient(client APIClientInterface) *APIClient { + return &APIClient{client: client} +} +func (c *APIClient) ChainID(ctx context.Context) (*big.Int, error) { + return c.client.ChainID(context.Background()) +} +func (c *APIClient) BlockNumber(ctx context.Context) (uint64, error) { + return c.client.BlockNumber(context.Background()) +} +func (c *APIClient) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) { + return c.client.BlockByNumber(context.Background(), number) +} +func (c *APIClient) Client() *rpc.Client { + return c.client.Client() +} + +type RPCClientInterface interface { + Call(result interface{}, method string, args ...interface{}) error +} + +type RPCClient struct { + apiClient APIClientInterface +} + +func (c *RPCClient) Call(result interface{}, method string, args ...interface{}) error { + return c.apiClient.Client().Call(result, method, args) +} From af3252a244d4605cbb8f021119a466c202d8b3cb Mon Sep 17 00:00:00 2001 From: nagdahimanshu Date: Wed, 17 Jan 2024 18:11:55 +0100 Subject: [PATCH 02/13] :construction: Add chain constants file --- pkg/chain/chain_constants.go | 212 +++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 pkg/chain/chain_constants.go diff --git a/pkg/chain/chain_constants.go b/pkg/chain/chain_constants.go new file mode 100644 index 0000000..d286828 --- /dev/null +++ b/pkg/chain/chain_constants.go @@ -0,0 +1,212 @@ +package chain + +import ( + "reflect" +) + +type DefaultL2ContractAddress struct { + L2CrossDomainMessenger string + L2ToL1MessagePasser string + L2StandardBridge string + OVM_L1BlockNumber string + OVM_L2ToL1MessagePasser string + OVM_DeployerWhitelist string + OVM_ETH string + OVM_GasPriceOracle string + OVM_SequencerFeeVault string + WETH string + BedrockMessagePasser string +} + +type NetworkType struct { + mainnet string + goerli string + sepolia string +} + +type L2ChainIDs struct { + OPTIMISM int + OPTIMISM_GOERLI int + OPTIMISM_HARDHAT_LOCAL int + OPTIMISM_HARDHAT_DEVNET int + OPTIMISM_BEDROCK_LOCAL_DEVNET int + OPTIMISM_BEDROCK_ALPHA_TESTNET int + BASE_GOERLI int + ZORA_GOERLI int + ZORA_MAINNET int + OPTIMISM_SEPOLIA int + BASE_SEPOLIA int + BASE_MAINNET int +} + +var L2_CHAIN_ID = L2ChainIDs{ + OPTIMISM: 10, + OPTIMISM_GOERLI: 420, + OPTIMISM_SEPOLIA: 11155420, + OPTIMISM_HARDHAT_LOCAL: 31337, + OPTIMISM_HARDHAT_DEVNET: 17, + OPTIMISM_BEDROCK_ALPHA_TESTNET: 28528, + BASE_GOERLI: 84531, + BASE_SEPOLIA: 84532, + BASE_MAINNET: 8453, + ZORA_GOERLI: 999, + ZORA_MAINNET: 7777777, +} + +var L2_OUTPUT_ORACLE_ADDRESSES = NetworkType{ + mainnet: "0xdfe97868233d1aa22e815a266982f2cf17685a27", + goerli: "0xE6Dfba0953616Bacab0c9A8ecb3a9BBa77FC15c0", + sepolia: "0x90E9c4f8a994a250F6aEfd61CAFb4F2e895D458F", +} + +var L1_CROSS_DOMAIN_MESSENGER = NetworkType{ + mainnet: "0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1", + goerli: "0x5086d1eEF304eb5284A0f6720f79403b4e9bE294", + sepolia: "0x58Cc85b8D04EA49cC6DBd3CbFFd00B4B8D6cb3ef", +} + +var STATE_COMMITMENT_CHAIN = NetworkType{ + mainnet: "0xBe5dAb4A2e9cd0F27300dB4aB94BeE3A233AEB19", + goerli: "0x9c945aC97Baf48cB784AbBB61399beB71aF7A378", + sepolia: "0x0000000000000000000000000000000000000000", +} + +var OPTIMISM_PORTAL_ADDRESS = NetworkType{ + mainnet: "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed", + goerli: "0x5b47E1A08Ea6d985D6649300584e6722Ec4B1383", + sepolia: "0x16Fc5058F25648194471939df75CF27A2fdC48BC", +} + +type L1Contracts struct { + L1CrossDomainMessenger string + StateCommitmentChain string + OptimismPortal string + L2OutputOracle string +} + +type ContractAddresses struct { + L1Contracts + DefaultL2ContractAddress +} + +var DEFAULT_L2_CONTRACT_ADDRESS = DefaultL2ContractAddress{ + BedrockMessagePasser: "0x4200000000000000000000000000000000000016", + L2CrossDomainMessenger: "0x4200000000000000000000000000000000000007", + L2StandardBridge: "0x4200000000000000000000000000000000000010", + L2ToL1MessagePasser: "0x4200000000000000000000000000000000000016", + OVM_DeployerWhitelist: "0x4200000000000000000000000000000000000002", + OVM_ETH: "0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000", + OVM_GasPriceOracle: "0x420000000000000000000000000000000000000F", + OVM_L1BlockNumber: "0x4200000000000000000000000000000000000013", + OVM_L2ToL1MessagePasser: "0x4200000000000000000000000000000000000016", + OVM_SequencerFeeVault: "0x4200000000000000000000000000000000000011", + WETH: "0x4200000000000000000000000000000000000006", +} + +func FilterAddressByNetwork(c NetworkType, network string) string { + ref := reflect.ValueOf(c) + f := reflect.Indirect(ref).FieldByName(network) + return string(f.String()) +} + +func getL1ContractsByNetworkName(network string) L1Contracts { + L1Contracts := L1Contracts{ + L1CrossDomainMessenger: FilterAddressByNetwork(L1_CROSS_DOMAIN_MESSENGER, network), + StateCommitmentChain: FilterAddressByNetwork(STATE_COMMITMENT_CHAIN, network), + OptimismPortal: FilterAddressByNetwork(OPTIMISM_PORTAL_ADDRESS, network), + L2OutputOracle: FilterAddressByNetwork(L2_OUTPUT_ORACLE_ADDRESSES, network), + } + + return L1Contracts +} + +func getContractAddresses() map[int]map[string]L1Contracts { + CONTRACT_ADDRESSES := map[int]map[string]L1Contracts{ + L2_CHAIN_ID.OPTIMISM: { + "l1": getL1ContractsByNetworkName("mainnet"), + // "l2": DEFAULT_L2_CONTRACT_ADDRESS, + }, + L2_CHAIN_ID.OPTIMISM_GOERLI: { + "l1": getL1ContractsByNetworkName("goerli"), + // "l2": DEFAULT_L2_CONTRACT_ADDRESS, + }, + L2_CHAIN_ID.OPTIMISM_SEPOLIA: { + "l1": getL1ContractsByNetworkName("sepolia"), + // "l2": DEFAULT_L2_CONTRACT_ADDRESS, + }, + L2_CHAIN_ID.OPTIMISM_HARDHAT_LOCAL: { + "l1": { + L1CrossDomainMessenger: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", + StateCommitmentChain: "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", + OptimismPortal: "0x0000000000000000000000000000000000000000", + L2OutputOracle: "0x0000000000000000000000000000000000000000", + }, + // "l2": DEFAULT_L2_CONTRACT_ADDRESS, + }, + L2_CHAIN_ID.OPTIMISM_HARDHAT_DEVNET: { + "l1": { + L1CrossDomainMessenger: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", + StateCommitmentChain: "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", + OptimismPortal: "0x0000000000000000000000000000000000000000", + L2OutputOracle: "0x0000000000000000000000000000000000000000", + }, + // "l2": DEFAULT_L2_CONTRACT_ADDRESS, + }, + L2_CHAIN_ID.OPTIMISM_BEDROCK_ALPHA_TESTNET: { + "l1": { + L1CrossDomainMessenger: "0x838a6DC4E37CA45D4Ef05bb776bf05eEf50798De", + StateCommitmentChain: "0x0000000000000000000000000000000000000000", + OptimismPortal: "0xA581Ca3353DB73115C4625FFC7aDF5dB379434A8", + L2OutputOracle: "0x3A234299a14De50027eA65dCdf1c0DaC729e04A6", + }, + // "l2": DEFAULT_L2_CONTRACT_ADDRESS, + }, + L2_CHAIN_ID.BASE_GOERLI: { + "l1": { + L1CrossDomainMessenger: "0x8e5693140eA606bcEB98761d9beB1BC87383706D", + StateCommitmentChain: "0x0000000000000000000000000000000000000000", + OptimismPortal: "0xe93c8cD0D409341205A592f8c4Ac1A5fe5585cfA", + L2OutputOracle: "0x2A35891ff30313CcFa6CE88dcf3858bb075A2298", + }, + // "l2": DEFAULT_L2_CONTRACT_ADDRESS, + }, + L2_CHAIN_ID.BASE_SEPOLIA: { + "l1": { + L1CrossDomainMessenger: "0xC34855F4De64F1840e5686e64278da901e261f20", + StateCommitmentChain: "0x0000000000000000000000000000000000000000", + OptimismPortal: "0x49f53e41452C74589E85cA1677426Ba426459e85", + L2OutputOracle: "0x84457ca9D0163FbC4bbfe4Dfbb20ba46e48DF254", + }, + // "l2": DEFAULT_L2_CONTRACT_ADDRESS, + }, + L2_CHAIN_ID.BASE_MAINNET: { + "l1": { + L1CrossDomainMessenger: "0x866E82a600A1414e583f7F13623F1aC5d58b0Afa", + StateCommitmentChain: "0x0000000000000000000000000000000000000000", + OptimismPortal: "0x49048044D57e1C92A77f79988d21Fa8fAF74E97e", + L2OutputOracle: "0x56315b90c40730925ec5485cf004d835058518A0", + }, + // "l2": DEFAULT_L2_CONTRACT_ADDRESS, + }, + L2_CHAIN_ID.ZORA_GOERLI: { + "l1": { + L1CrossDomainMessenger: "0xD87342e16352D33170557A7dA1e5fB966a60FafC", + StateCommitmentChain: "0x0000000000000000000000000000000000000000", + OptimismPortal: "0xDb9F51790365e7dc196e7D072728df39Be958ACe", + L2OutputOracle: "0xdD292C9eEd00f6A32Ff5245d0BCd7f2a15f24e00", + }, + // "l2": DEFAULT_L2_CONTRACT_ADDRESS, + }, + L2_CHAIN_ID.ZORA_MAINNET: { + "l1": { + L1CrossDomainMessenger: "0xdC40a14d9abd6F410226f1E6de71aE03441ca506", + StateCommitmentChain: "0x0000000000000000000000000000000000000000", + OptimismPortal: "0x1a0ad011913A150f69f6A19DF447A0CfD9551054", + L2OutputOracle: "0x9E6204F750cD866b299594e2aC9eA824E2e5f95c", + }, + // "l2": DEFAULT_L2_CONTRACT_ADDRESS, + }, + } + + return CONTRACT_ADDRESSES +} From 58f3a2fa54257c478cef21c0560bc1791e57f943 Mon Sep 17 00:00:00 2001 From: nagdahimanshu Date: Wed, 17 Jan 2024 18:12:41 +0100 Subject: [PATCH 03/13] :construction: Add initial implementation to interact with contracts on chain --- go.mod | 11 +++--- go.sum | 27 ++++++++------ pkg/chain/chain_constants.go | 2 +- pkg/chain/contracts.go | 68 ++++++++++++++++++++++++++++++++++++ 4 files changed, 93 insertions(+), 15 deletions(-) create mode 100644 pkg/chain/contracts.go diff --git a/go.mod b/go.mod index c9c98d0..f7a9563 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/LiskHQ/op-fault-detector go 1.21.5 require ( + github.com/ethereum-optimism/optimism/op-bindings v0.10.14 github.com/ethereum/go-ethereum v1.13.10 github.com/stretchr/testify v1.8.4 go.uber.org/zap v1.26.0 @@ -10,7 +11,6 @@ require ( require ( github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/StackExchange/wmi v1.2.1 // indirect github.com/bits-and-blooms/bitset v1.10.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect github.com/consensys/bavard v0.1.13 // indirect @@ -20,16 +20,19 @@ require ( github.com/deckarep/golang-set/v2 v2.1.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect - github.com/go-ole/go-ole v1.2.5 // indirect - github.com/gorilla/websocket v1.4.2 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/gorilla/websocket v1.5.0 // indirect github.com/holiman/uint256 v1.2.4 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect + github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/stretchr/objx v0.5.0 // indirect github.com/supranational/blst v0.3.11 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect + github.com/yusufpapurcu/wmi v1.2.2 // indirect go.uber.org/multierr v1.10.0 // indirect golang.org/x/crypto v0.17.0 // indirect golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect diff --git a/go.sum b/go.sum index 6bd8bfe..99707a4 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,6 @@ github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= -github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -14,6 +12,8 @@ github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPx github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= +github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cockroachdb/errors v1.8.1 h1:A5+txlVZfOqFBDa4mGz2bUWSp0aHElvHX2bKkdbQu+Y= @@ -47,6 +47,8 @@ github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +github.com/ethereum-optimism/optimism/op-bindings v0.10.14 h1:SMMnMdNb1QIhJDyvk7QMUv+crAP4UHHoSYBOASBDIjM= +github.com/ethereum-optimism/optimism/op-bindings v0.10.14/go.mod h1:9ZSUq/rjlzp3uYyBN4sZmhTc3oZgDVqJ4wrUja7vj6c= github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/ethereum/go-ethereum v1.13.10 h1:Ppdil79nN+Vc+mXfge0AuUgmKWuVv4eMqzoIVSdqZek= @@ -59,8 +61,8 @@ github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqG github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 h1:BAIP2GihuqhwdILrV+7GJel5lyPV3u1+PgzrWLc0TkE= github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46/go.mod h1:QNpY22eby74jVhqH4WhDLDwxc/vqsern6pW+u2kbkpc= -github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY= -github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -71,11 +73,13 @@ github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 h1:3JQNjnMRil1yD0IfZKHF9GxxWKDJGj8I0IqOUol//sw= @@ -135,8 +139,8 @@ github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= -github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= +github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -149,8 +153,8 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= -github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= -github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a h1:1ur3QoCqvE5fl+nylMaIr9PVV1w343YRDtsy+Rwu7XI= +github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= @@ -161,6 +165,8 @@ github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= +github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= @@ -176,6 +182,7 @@ golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= diff --git a/pkg/chain/chain_constants.go b/pkg/chain/chain_constants.go index d286828..a364f0b 100644 --- a/pkg/chain/chain_constants.go +++ b/pkg/chain/chain_constants.go @@ -106,7 +106,7 @@ var DEFAULT_L2_CONTRACT_ADDRESS = DefaultL2ContractAddress{ func FilterAddressByNetwork(c NetworkType, network string) string { ref := reflect.ValueOf(c) f := reflect.Indirect(ref).FieldByName(network) - return string(f.String()) + return f.String() } func getL1ContractsByNetworkName(network string) L1Contracts { diff --git a/pkg/chain/contracts.go b/pkg/chain/contracts.go new file mode 100644 index 0000000..3175c0b --- /dev/null +++ b/pkg/chain/contracts.go @@ -0,0 +1,68 @@ +package chain + +import ( + "math/big" + + "github.com/LiskHQ/op-fault-detector/pkg/log" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" + + "github.com/ethereum-optimism/optimism/op-bindings/bindings" +) + +func GetOracleAddressbyChainID(l2ChainID int) string { + ContractAddresses := getContractAddresses() + address := ContractAddresses[l2ChainID]["l1"].L2OutputOracle + return address +} + +// TODO: Create oracle Struct with required functions +func OracleContractInstance(client *ethclient.Client, l2ChainID int, log log.Logger) (*bindings.L2OutputOracle, error) { + oracleContractAddress := GetOracleAddressbyChainID(l2ChainID) + + contract, err := bindings.NewL2OutputOracle(common.HexToAddress(oracleContractAddress), client) + + if err != nil { + return nil, err + } + + return contract, nil +} + +// TODO: Use EthClientInterface +func CreateContractInstance(url string, l2ChainID int, logger log.Logger) *bindings.L2OutputOracle { + client, err := ethclient.Dial(url) + + if err != nil { + logger.Errorf("Error occurred while connecting %w", err) + } + + contract, err := OracleContractInstance(client, l2ChainID, logger) + + if err != nil { + logger.Errorf("Error occurred while creating contract instance %w", err) + } + + return contract +} + +func GetNextOutputIndex(contractInstance *bindings.L2OutputOracle, log log.Logger) *big.Int { + nextOutputIndex, err := contractInstance.NextOutputIndex(&bind.CallOpts{}) + + if err != nil { + log.Errorf("Error occurred while retrieving next output index %w", err) + } + + return nextOutputIndex +} + +func GetL2Output(contractInstance *bindings.L2OutputOracle, index *big.Int, log log.Logger) bindings.TypesOutputProposal { + l2Output, err := contractInstance.GetL2Output(&bind.CallOpts{}, index) + + if err != nil { + log.Errorf("Error occurred while retrieving L2 outout %w", err) + } + + return l2Output +} From d614860463d3f36e9b0a45f753d3223b717580c6 Mon Sep 17 00:00:00 2001 From: Ishan Date: Wed, 17 Jan 2024 18:54:18 +0100 Subject: [PATCH 04/13] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Update=20interfaces?= =?UTF-8?q?=20and=20rename=20file?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/chain/chain.go | 65 +++++++++++------- .../{chain_mocks.go => chain_mocks_test.go} | 13 +--- pkg/chain/chain_test.go | 68 ++++++------------- pkg/chain/eth_client.go | 64 ----------------- 4 files changed, 62 insertions(+), 148 deletions(-) rename pkg/chain/{chain_mocks.go => chain_mocks_test.go} (78%) delete mode 100644 pkg/chain/eth_client.go diff --git a/pkg/chain/chain.go b/pkg/chain/chain.go index 8756920..19c0e36 100644 --- a/pkg/chain/chain.go +++ b/pkg/chain/chain.go @@ -9,31 +9,51 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/rpc" ) -type ChainAPIClient struct { - client *APIClient - log log.Logger +const ( + RPCEndpointGetProof = "eth_getProof" +) + +type APIMethods interface { + ChainID(ctx context.Context) (*big.Int, error) + BlockNumber(ctx context.Context) (uint64, error) + BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) + Client() *rpc.Client } -// NewChainAPIClient returns a [ChainAPIClient], wrapping all RPC endpoints to access chain related data. -func NewChainAPIClient(log log.Logger) (*ChainAPIClient, error) { - return &ChainAPIClient{ - log: log, - }, nil +type RPCClient interface { + Call(result interface{}, method string, args ...interface{}) error } -func (c *ChainAPIClient) Connect(ethClientObj EthClientInterface, url string) { - client, err := ethClientObj.Dial(url) +// GetAPIClient return [ChainAPIClient] with client attached. +func GetAPIClient(url string, log log.Logger) (*ChainAPIClient, error) { + client, err := ethclient.Dial(url) if err != nil { - c.log.Errorf("Error occurred while connecting %w", err) + return nil, err } - c.client = NewAPIClient(client) + + return NewChainAPIClient(client, log) +} + +type ChainAPIClient struct { + apiClient APIMethods + log log.Logger +} + +// NewChainAPIClient returns a [ChainAPIClient], wrapping all RPC endpoints to access chain related data. +func NewChainAPIClient(apiClient APIMethods, log log.Logger) (*ChainAPIClient, error) { + return &ChainAPIClient{ + apiClient: apiClient, + log: log, + }, nil } // Returns chainID of the connected node. -func (c *ChainAPIClient) GetChainID() (*big.Int, error) { - chainID, err := c.client.ChainID(context.Background()) +func (c *ChainAPIClient) GetChainID(ctx context.Context) (*big.Int, error) { + chainID, err := c.apiClient.ChainID(ctx) if err != nil { return nil, err } @@ -42,8 +62,8 @@ func (c *ChainAPIClient) GetChainID() (*big.Int, error) { } // Returns latest block number from the connected node. -func (c *ChainAPIClient) GetLatestBlockNumber() (uint64, error) { - blockNumber, err := c.client.BlockNumber(context.Background()) +func (c *ChainAPIClient) GetLatestBlockNumber(ctx context.Context) (uint64, error) { + blockNumber, err := c.apiClient.BlockNumber(ctx) if err != nil { return 0, err } @@ -52,8 +72,8 @@ func (c *ChainAPIClient) GetLatestBlockNumber() (uint64, error) { } // Returns block for a given block number from the connected node. -func (c *ChainAPIClient) GetBlockByNumber(blockNumber *big.Int) (*types.Block, error) { - block, err := c.client.BlockByNumber(context.Background(), blockNumber) +func (c *ChainAPIClient) GetBlockByNumber(ctx context.Context, blockNumber *big.Int) (*types.Block, error) { + block, err := c.apiClient.BlockByNumber(ctx, blockNumber) if err != nil { return nil, err } @@ -71,16 +91,11 @@ type ProofResponse struct { StorageProof []common.Hash `json:"storageProof"` } -const ( - RPCEndpointGetProof = "eth_getProof" -) - // Returns the account and storage values, including the Merkle proof, of the specified account/address. -func (c *ChainAPIClient) GetProof(blockNumber *big.Int, address string) (*ProofResponse, error) { +func (c *ChainAPIClient) GetProof(client RPCClient, blockNumber *big.Int, address string) (*ProofResponse, error) { var result ProofResponse - rpcClient := &RPCClient{c.client} - if err := rpcClient.Call(&result, RPCEndpointGetProof, address, []string{}, hexutil.EncodeBig(blockNumber)); err != nil { + if err := client.Call(&result, RPCEndpointGetProof, address, []string{}, blockNumber); err != nil { return nil, err } diff --git a/pkg/chain/chain_mocks.go b/pkg/chain/chain_mocks_test.go similarity index 78% rename from pkg/chain/chain_mocks.go rename to pkg/chain/chain_mocks_test.go index 4a29e57..192bf88 100644 --- a/pkg/chain/chain_mocks.go +++ b/pkg/chain/chain_mocks_test.go @@ -10,17 +10,6 @@ import ( ) // Mock function - -type MockEthClient struct { - mock.Mock -} - -func (e *MockEthClient) Dial(url string) (APIClientInterface, error) { - ret := e.Called(url) - - return ret.Get(0).(APIClientInterface), ret.Error(1) -} - type MockAPIClient struct { mock.Mock } @@ -50,7 +39,7 @@ type MockRPCClient struct { mock.Mock } -func (c *MockAPIClient) Call(result interface{}, method string, args ...interface{}) error { +func (c *MockRPCClient) Call(result interface{}, method string, args ...interface{}) error { ret := c.Called() ptr := &result diff --git a/pkg/chain/chain_test.go b/pkg/chain/chain_test.go index 5fbfe4c..e3aadf1 100644 --- a/pkg/chain/chain_test.go +++ b/pkg/chain/chain_test.go @@ -2,13 +2,13 @@ package chain import ( "context" + "fmt" "math/big" "testing" "time" "github.com/LiskHQ/op-fault-detector/pkg/log" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/stretchr/testify/assert" ) @@ -20,68 +20,44 @@ const ( func TestNewChainAPIClient(t *testing.T) { log := log.DefaultLogger - chainClient, _ := NewChainAPIClient(log) - assert.Equal(t, chainClient.log, log) -} - -func TestConnect(t *testing.T) { - log := log.DefaultLogger - ethClientMock := &MockEthClient{} - apiClientMock := &MockAPIClient{} - ethClientMock.On("Dial", fake_url).Return(apiClientMock, nil) - - chainClient, _ := NewChainAPIClient(log) - chainClient.Connect(ethClientMock, fake_url) - + chainClient, _ := NewChainAPIClient(apiClientMock, log) assert.Equal(t, chainClient.log, log) } func TestGetChainID(t *testing.T) { + ctx := context.Background() log := log.DefaultLogger - ethClientMock := &MockEthClient{} - apiClientMock := &MockAPIClient{} - ethClientMock.On("Dial", fake_url).Return(apiClientMock, nil) - - chainClient, _ := NewChainAPIClient(log) - chainClient.Connect(ethClientMock, fake_url) + chainClient, _ := NewChainAPIClient(apiClientMock, log) assert.Equal(t, chainClient.log, log) expectedChainID := big.NewInt(2) apiClientMock.On("ChainID", context.Background()).Return(expectedChainID, nil) - receivedChainID, _ := chainClient.GetChainID() + receivedChainID, _ := chainClient.GetChainID(ctx) assert.Equal(t, expectedChainID, receivedChainID) } func TestGetLatestBlockNumber(t *testing.T) { + ctx := context.Background() log := log.DefaultLogger - ethClientMock := &MockEthClient{} - apiClientMock := &MockAPIClient{} - ethClientMock.On("Dial", fake_url).Return(apiClientMock, nil) - - chainClient, _ := NewChainAPIClient(log) - chainClient.Connect(ethClientMock, fake_url) + chainClient, _ := NewChainAPIClient(apiClientMock, log) assert.Equal(t, chainClient.log, log) expectedLatestBlockNumber := uint64(12345) apiClientMock.On("BlockNumber", context.Background()).Return(expectedLatestBlockNumber, nil) - receivedLatestBlockNumber, _ := chainClient.GetLatestBlockNumber() + receivedLatestBlockNumber, _ := chainClient.GetLatestBlockNumber(ctx) assert.Equal(t, expectedLatestBlockNumber, receivedLatestBlockNumber) } func TestGetBlockByNumber(t *testing.T) { + ctx := context.Background() log := log.DefaultLogger - ethClientMock := &MockEthClient{} - apiClientMock := &MockAPIClient{} - ethClientMock.On("Dial", fake_url).Return(apiClientMock, nil) - - chainClient, _ := NewChainAPIClient(log) - chainClient.Connect(ethClientMock, fake_url) + chainClient, _ := NewChainAPIClient(apiClientMock, log) assert.Equal(t, chainClient.log, log) @@ -90,30 +66,28 @@ func TestGetBlockByNumber(t *testing.T) { ReceivedAt: time.Now(), } apiClientMock.On("BlockByNumber", context.Background(), blockNumber).Return(expectedBlock, nil) - receivedBlock, _ := chainClient.GetBlockByNumber(blockNumber) + receivedBlock, _ := chainClient.GetBlockByNumber(ctx, blockNumber) assert.Equal(t, expectedBlock, receivedBlock) } func TestGetProof(t *testing.T) { - t.Skip("skipping testing") + // t.Skipf("Skipping GetProof test") log := log.DefaultLogger - ethClientMock := &MockEthClient{} - apiClientMock := &MockAPIClient{} - ethClientMock.On("Dial", fake_url).Return(apiClientMock, nil) - - chainClient, _ := NewChainAPIClient(log) - chainClient.Connect(ethClientMock, fake_url) + chainClient, _ := NewChainAPIClient(apiClientMock, log) assert.Equal(t, chainClient.log, log) rpcClientMock := &MockRPCClient{} - apiClientMock.On("Client").Return(rpcClientMock, nil) - + // Args for Call() method address := common.Address{} blockNumber := big.NewInt(800) - proofResponseExpected := &ProofResponse{} - rpcClientMock.On("Call", proofResponseExpected, RPCEndpointGetProof, address, []string{}, hexutil.EncodeBig(blockNumber)).Return(nil) - proofResponseRecieved, _ := chainClient.GetProof(blockNumber, address.Hex()) + var proofResponseExpected ProofResponse + + apiClientMock.On("Client").Return(rpcClientMock, nil) + rpcClientMock.On("Call", &proofResponseExpected, RPCEndpointGetProof, address.String(), []string{}, blockNumber).Return(fmt.Println("Error")) + + proofResponseRecieved, _ := chainClient.GetProof(rpcClientMock, blockNumber, address.Hex()) + assert.Equal(t, proofResponseExpected, proofResponseRecieved) } diff --git a/pkg/chain/eth_client.go b/pkg/chain/eth_client.go deleted file mode 100644 index 5315464..0000000 --- a/pkg/chain/eth_client.go +++ /dev/null @@ -1,64 +0,0 @@ -package chain - -import ( - "context" - "math/big" - - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethclient" - "github.com/ethereum/go-ethereum/rpc" -) - -type EthClientInterface interface { - Dial(url string) (APIClientInterface, error) -} - -type EthClient struct{} - -func (e *EthClient) Dial(url string) (APIClientInterface, error) { - client, err := ethclient.Dial(url) - if err != nil { - return nil, err - } - - return client, nil -} - -type APIClientInterface interface { - ChainID(ctx context.Context) (*big.Int, error) - BlockNumber(ctx context.Context) (uint64, error) - BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) - Client() *rpc.Client -} - -type APIClient struct { - client APIClientInterface -} - -func NewAPIClient(client APIClientInterface) *APIClient { - return &APIClient{client: client} -} -func (c *APIClient) ChainID(ctx context.Context) (*big.Int, error) { - return c.client.ChainID(context.Background()) -} -func (c *APIClient) BlockNumber(ctx context.Context) (uint64, error) { - return c.client.BlockNumber(context.Background()) -} -func (c *APIClient) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) { - return c.client.BlockByNumber(context.Background(), number) -} -func (c *APIClient) Client() *rpc.Client { - return c.client.Client() -} - -type RPCClientInterface interface { - Call(result interface{}, method string, args ...interface{}) error -} - -type RPCClient struct { - apiClient APIClientInterface -} - -func (c *RPCClient) Call(result interface{}, method string, args ...interface{}) error { - return c.apiClient.Client().Call(result, method, args) -} From 9c989ffb5c6154152f37213c6e38613ba2813273 Mon Sep 17 00:00:00 2001 From: Ishan Date: Thu, 18 Jan 2024 10:58:03 +0100 Subject: [PATCH 05/13] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Fix=20test=20and=20m?= =?UTF-8?q?ocking?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/chain/chain_mocks_test.go | 5 +++-- pkg/chain/chain_test.go | 12 +++++------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/pkg/chain/chain_mocks_test.go b/pkg/chain/chain_mocks_test.go index 192bf88..ede01f8 100644 --- a/pkg/chain/chain_mocks_test.go +++ b/pkg/chain/chain_mocks_test.go @@ -9,7 +9,6 @@ import ( "github.com/stretchr/testify/mock" ) -// Mock function type MockAPIClient struct { mock.Mock } @@ -40,7 +39,9 @@ type MockRPCClient struct { } func (c *MockRPCClient) Call(result interface{}, method string, args ...interface{}) error { - ret := c.Called() + allArgs := []interface{}{result, method} + allArgs = append(allArgs, args...) + ret := c.Called(allArgs...) ptr := &result *ptr = ret.Get(0) diff --git a/pkg/chain/chain_test.go b/pkg/chain/chain_test.go index e3aadf1..7080877 100644 --- a/pkg/chain/chain_test.go +++ b/pkg/chain/chain_test.go @@ -11,10 +11,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/stretchr/testify/assert" -) - -const ( - fake_url = "localhost:8080" + "github.com/stretchr/testify/mock" ) func TestNewChainAPIClient(t *testing.T) { @@ -85,9 +82,10 @@ func TestGetProof(t *testing.T) { var proofResponseExpected ProofResponse apiClientMock.On("Client").Return(rpcClientMock, nil) - rpcClientMock.On("Call", &proofResponseExpected, RPCEndpointGetProof, address.String(), []string{}, blockNumber).Return(fmt.Println("Error")) + rpcClientMock.On("Call", mock.AnythingOfType("*chain.ProofResponse"), RPCEndpointGetProof, address.String(), []string{}, blockNumber).Return(fmt.Println("Error")) - proofResponseRecieved, _ := chainClient.GetProof(rpcClientMock, blockNumber, address.Hex()) + proofResponseRecieved, err := chainClient.GetProof(rpcClientMock, blockNumber, address.Hex()) - assert.Equal(t, proofResponseExpected, proofResponseRecieved) + assert.NoError(t, err) + assert.Equal(t, &proofResponseExpected, proofResponseRecieved) } From 34590dd5003ebecbfc44bdea34c71fa8bddbd0d9 Mon Sep 17 00:00:00 2001 From: nagdahimanshu Date: Thu, 18 Jan 2024 09:44:01 +0100 Subject: [PATCH 06/13] Update chainIds type --- pkg/chain/chain_constants.go | 218 +++++++++++------------------------ pkg/chain/contracts.go | 14 +-- 2 files changed, 76 insertions(+), 156 deletions(-) diff --git a/pkg/chain/chain_constants.go b/pkg/chain/chain_constants.go index a364f0b..21f9535 100644 --- a/pkg/chain/chain_constants.go +++ b/pkg/chain/chain_constants.go @@ -1,42 +1,18 @@ package chain -import ( - "reflect" -) - -type DefaultL2ContractAddress struct { - L2CrossDomainMessenger string - L2ToL1MessagePasser string - L2StandardBridge string - OVM_L1BlockNumber string - OVM_L2ToL1MessagePasser string - OVM_DeployerWhitelist string - OVM_ETH string - OVM_GasPriceOracle string - OVM_SequencerFeeVault string - WETH string - BedrockMessagePasser string -} - -type NetworkType struct { - mainnet string - goerli string - sepolia string -} - type L2ChainIDs struct { - OPTIMISM int - OPTIMISM_GOERLI int - OPTIMISM_HARDHAT_LOCAL int - OPTIMISM_HARDHAT_DEVNET int - OPTIMISM_BEDROCK_LOCAL_DEVNET int - OPTIMISM_BEDROCK_ALPHA_TESTNET int - BASE_GOERLI int - ZORA_GOERLI int - ZORA_MAINNET int - OPTIMISM_SEPOLIA int - BASE_SEPOLIA int - BASE_MAINNET int + OPTIMISM uint64 + OPTIMISM_GOERLI uint64 + OPTIMISM_HARDHAT_LOCAL uint64 + OPTIMISM_HARDHAT_DEVNET uint64 + OPTIMISM_BEDROCK_LOCAL_DEVNET uint64 + OPTIMISM_BEDROCK_ALPHA_TESTNET uint64 + BASE_GOERLI uint64 + ZORA_GOERLI uint64 + ZORA_MAINNET uint64 + OPTIMISM_SEPOLIA uint64 + BASE_SEPOLIA uint64 + BASE_MAINNET uint64 } var L2_CHAIN_ID = L2ChainIDs{ @@ -53,160 +29,104 @@ var L2_CHAIN_ID = L2ChainIDs{ ZORA_MAINNET: 7777777, } -var L2_OUTPUT_ORACLE_ADDRESSES = NetworkType{ - mainnet: "0xdfe97868233d1aa22e815a266982f2cf17685a27", - goerli: "0xE6Dfba0953616Bacab0c9A8ecb3a9BBa77FC15c0", - sepolia: "0x90E9c4f8a994a250F6aEfd61CAFb4F2e895D458F", -} - -var L1_CROSS_DOMAIN_MESSENGER = NetworkType{ - mainnet: "0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1", - goerli: "0x5086d1eEF304eb5284A0f6720f79403b4e9bE294", - sepolia: "0x58Cc85b8D04EA49cC6DBd3CbFFd00B4B8D6cb3ef", -} - -var STATE_COMMITMENT_CHAIN = NetworkType{ - mainnet: "0xBe5dAb4A2e9cd0F27300dB4aB94BeE3A233AEB19", - goerli: "0x9c945aC97Baf48cB784AbBB61399beB71aF7A378", - sepolia: "0x0000000000000000000000000000000000000000", -} - -var OPTIMISM_PORTAL_ADDRESS = NetworkType{ - mainnet: "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed", - goerli: "0x5b47E1A08Ea6d985D6649300584e6722Ec4B1383", - sepolia: "0x16Fc5058F25648194471939df75CF27A2fdC48BC", -} - type L1Contracts struct { - L1CrossDomainMessenger string - StateCommitmentChain string - OptimismPortal string - L2OutputOracle string -} - -type ContractAddresses struct { - L1Contracts - DefaultL2ContractAddress + l1CrossDomainMessenger string + stateCommitmentChain string + optimismPortal string + l2OutputOracle string } -var DEFAULT_L2_CONTRACT_ADDRESS = DefaultL2ContractAddress{ - BedrockMessagePasser: "0x4200000000000000000000000000000000000016", - L2CrossDomainMessenger: "0x4200000000000000000000000000000000000007", - L2StandardBridge: "0x4200000000000000000000000000000000000010", - L2ToL1MessagePasser: "0x4200000000000000000000000000000000000016", - OVM_DeployerWhitelist: "0x4200000000000000000000000000000000000002", - OVM_ETH: "0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000", - OVM_GasPriceOracle: "0x420000000000000000000000000000000000000F", - OVM_L1BlockNumber: "0x4200000000000000000000000000000000000013", - OVM_L2ToL1MessagePasser: "0x4200000000000000000000000000000000000016", - OVM_SequencerFeeVault: "0x4200000000000000000000000000000000000011", - WETH: "0x4200000000000000000000000000000000000006", -} - -func FilterAddressByNetwork(c NetworkType, network string) string { - ref := reflect.ValueOf(c) - f := reflect.Indirect(ref).FieldByName(network) - return f.String() -} - -func getL1ContractsByNetworkName(network string) L1Contracts { - L1Contracts := L1Contracts{ - L1CrossDomainMessenger: FilterAddressByNetwork(L1_CROSS_DOMAIN_MESSENGER, network), - StateCommitmentChain: FilterAddressByNetwork(STATE_COMMITMENT_CHAIN, network), - OptimismPortal: FilterAddressByNetwork(OPTIMISM_PORTAL_ADDRESS, network), - L2OutputOracle: FilterAddressByNetwork(L2_OUTPUT_ORACLE_ADDRESSES, network), - } - - return L1Contracts -} - -func getContractAddresses() map[int]map[string]L1Contracts { - CONTRACT_ADDRESSES := map[int]map[string]L1Contracts{ +func GetContractAddresses(chainID uint64) map[string]L1Contracts { + CONTRACT_ADDRESSES := map[uint64]map[string]L1Contracts{ L2_CHAIN_ID.OPTIMISM: { - "l1": getL1ContractsByNetworkName("mainnet"), - // "l2": DEFAULT_L2_CONTRACT_ADDRESS, + "l1": { + l1CrossDomainMessenger: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", + stateCommitmentChain: "0xBe5dAb4A2e9cd0F27300dB4aB94BeE3A233AEB19", + optimismPortal: "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed", + l2OutputOracle: "0xdfe97868233d1aa22e815a266982f2cf17685a27", + }, }, L2_CHAIN_ID.OPTIMISM_GOERLI: { - "l1": getL1ContractsByNetworkName("goerli"), - // "l2": DEFAULT_L2_CONTRACT_ADDRESS, + "l1": { + l1CrossDomainMessenger: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", + stateCommitmentChain: "0x9c945aC97Baf48cB784AbBB61399beB71aF7A378", + optimismPortal: "0x5b47E1A08Ea6d985D6649300584e6722Ec4B1383", + l2OutputOracle: "0xE6Dfba0953616Bacab0c9A8ecb3a9BBa77FC15c0", + }, }, L2_CHAIN_ID.OPTIMISM_SEPOLIA: { - "l1": getL1ContractsByNetworkName("sepolia"), - // "l2": DEFAULT_L2_CONTRACT_ADDRESS, + "l1": { + l1CrossDomainMessenger: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", + stateCommitmentChain: "0x0000000000000000000000000000000000000000", + optimismPortal: "0x16Fc5058F25648194471939df75CF27A2fdC48BC", + l2OutputOracle: "0x90E9c4f8a994a250F6aEfd61CAFb4F2e895D458F", + }, }, L2_CHAIN_ID.OPTIMISM_HARDHAT_LOCAL: { "l1": { - L1CrossDomainMessenger: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", - StateCommitmentChain: "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", - OptimismPortal: "0x0000000000000000000000000000000000000000", - L2OutputOracle: "0x0000000000000000000000000000000000000000", + l1CrossDomainMessenger: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", + stateCommitmentChain: "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", + optimismPortal: "0x0000000000000000000000000000000000000000", + l2OutputOracle: "0x0000000000000000000000000000000000000000", }, - // "l2": DEFAULT_L2_CONTRACT_ADDRESS, }, L2_CHAIN_ID.OPTIMISM_HARDHAT_DEVNET: { "l1": { - L1CrossDomainMessenger: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", - StateCommitmentChain: "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", - OptimismPortal: "0x0000000000000000000000000000000000000000", - L2OutputOracle: "0x0000000000000000000000000000000000000000", + l1CrossDomainMessenger: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", + stateCommitmentChain: "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", + optimismPortal: "0x0000000000000000000000000000000000000000", + l2OutputOracle: "0x0000000000000000000000000000000000000000", }, - // "l2": DEFAULT_L2_CONTRACT_ADDRESS, }, L2_CHAIN_ID.OPTIMISM_BEDROCK_ALPHA_TESTNET: { "l1": { - L1CrossDomainMessenger: "0x838a6DC4E37CA45D4Ef05bb776bf05eEf50798De", - StateCommitmentChain: "0x0000000000000000000000000000000000000000", - OptimismPortal: "0xA581Ca3353DB73115C4625FFC7aDF5dB379434A8", - L2OutputOracle: "0x3A234299a14De50027eA65dCdf1c0DaC729e04A6", + l1CrossDomainMessenger: "0x838a6DC4E37CA45D4Ef05bb776bf05eEf50798De", + stateCommitmentChain: "0x0000000000000000000000000000000000000000", + optimismPortal: "0xA581Ca3353DB73115C4625FFC7aDF5dB379434A8", + l2OutputOracle: "0x3A234299a14De50027eA65dCdf1c0DaC729e04A6", }, - // "l2": DEFAULT_L2_CONTRACT_ADDRESS, }, L2_CHAIN_ID.BASE_GOERLI: { "l1": { - L1CrossDomainMessenger: "0x8e5693140eA606bcEB98761d9beB1BC87383706D", - StateCommitmentChain: "0x0000000000000000000000000000000000000000", - OptimismPortal: "0xe93c8cD0D409341205A592f8c4Ac1A5fe5585cfA", - L2OutputOracle: "0x2A35891ff30313CcFa6CE88dcf3858bb075A2298", + l1CrossDomainMessenger: "0x8e5693140eA606bcEB98761d9beB1BC87383706D", + stateCommitmentChain: "0x0000000000000000000000000000000000000000", + optimismPortal: "0xe93c8cD0D409341205A592f8c4Ac1A5fe5585cfA", + l2OutputOracle: "0x2A35891ff30313CcFa6CE88dcf3858bb075A2298", }, - // "l2": DEFAULT_L2_CONTRACT_ADDRESS, }, L2_CHAIN_ID.BASE_SEPOLIA: { "l1": { - L1CrossDomainMessenger: "0xC34855F4De64F1840e5686e64278da901e261f20", - StateCommitmentChain: "0x0000000000000000000000000000000000000000", - OptimismPortal: "0x49f53e41452C74589E85cA1677426Ba426459e85", - L2OutputOracle: "0x84457ca9D0163FbC4bbfe4Dfbb20ba46e48DF254", + l1CrossDomainMessenger: "0xC34855F4De64F1840e5686e64278da901e261f20", + stateCommitmentChain: "0x0000000000000000000000000000000000000000", + optimismPortal: "0x49f53e41452C74589E85cA1677426Ba426459e85", + l2OutputOracle: "0x84457ca9D0163FbC4bbfe4Dfbb20ba46e48DF254", }, - // "l2": DEFAULT_L2_CONTRACT_ADDRESS, }, L2_CHAIN_ID.BASE_MAINNET: { "l1": { - L1CrossDomainMessenger: "0x866E82a600A1414e583f7F13623F1aC5d58b0Afa", - StateCommitmentChain: "0x0000000000000000000000000000000000000000", - OptimismPortal: "0x49048044D57e1C92A77f79988d21Fa8fAF74E97e", - L2OutputOracle: "0x56315b90c40730925ec5485cf004d835058518A0", + l1CrossDomainMessenger: "0x866E82a600A1414e583f7F13623F1aC5d58b0Afa", + stateCommitmentChain: "0x0000000000000000000000000000000000000000", + optimismPortal: "0x49048044D57e1C92A77f79988d21Fa8fAF74E97e", + l2OutputOracle: "0x56315b90c40730925ec5485cf004d835058518A0", }, - // "l2": DEFAULT_L2_CONTRACT_ADDRESS, }, L2_CHAIN_ID.ZORA_GOERLI: { "l1": { - L1CrossDomainMessenger: "0xD87342e16352D33170557A7dA1e5fB966a60FafC", - StateCommitmentChain: "0x0000000000000000000000000000000000000000", - OptimismPortal: "0xDb9F51790365e7dc196e7D072728df39Be958ACe", - L2OutputOracle: "0xdD292C9eEd00f6A32Ff5245d0BCd7f2a15f24e00", + l1CrossDomainMessenger: "0xD87342e16352D33170557A7dA1e5fB966a60FafC", + stateCommitmentChain: "0x0000000000000000000000000000000000000000", + optimismPortal: "0xDb9F51790365e7dc196e7D072728df39Be958ACe", + l2OutputOracle: "0xdD292C9eEd00f6A32Ff5245d0BCd7f2a15f24e00", }, - // "l2": DEFAULT_L2_CONTRACT_ADDRESS, }, L2_CHAIN_ID.ZORA_MAINNET: { "l1": { - L1CrossDomainMessenger: "0xdC40a14d9abd6F410226f1E6de71aE03441ca506", - StateCommitmentChain: "0x0000000000000000000000000000000000000000", - OptimismPortal: "0x1a0ad011913A150f69f6A19DF447A0CfD9551054", - L2OutputOracle: "0x9E6204F750cD866b299594e2aC9eA824E2e5f95c", + l1CrossDomainMessenger: "0xdC40a14d9abd6F410226f1E6de71aE03441ca506", + stateCommitmentChain: "0x0000000000000000000000000000000000000000", + optimismPortal: "0x1a0ad011913A150f69f6A19DF447A0CfD9551054", + l2OutputOracle: "0x9E6204F750cD866b299594e2aC9eA824E2e5f95c", }, - // "l2": DEFAULT_L2_CONTRACT_ADDRESS, }, } - return CONTRACT_ADDRESSES + return CONTRACT_ADDRESSES[chainID] } diff --git a/pkg/chain/contracts.go b/pkg/chain/contracts.go index 3175c0b..d312135 100644 --- a/pkg/chain/contracts.go +++ b/pkg/chain/contracts.go @@ -11,15 +11,15 @@ import ( "github.com/ethereum-optimism/optimism/op-bindings/bindings" ) -func GetOracleAddressbyChainID(l2ChainID int) string { - ContractAddresses := getContractAddresses() - address := ContractAddresses[l2ChainID]["l1"].L2OutputOracle +func GetL1OracleContractAddressByChainID(chainID uint64) string { + ContractAddresses := GetContractAddresses(chainID) + address := ContractAddresses["l1"].l2OutputOracle return address } // TODO: Create oracle Struct with required functions -func OracleContractInstance(client *ethclient.Client, l2ChainID int, log log.Logger) (*bindings.L2OutputOracle, error) { - oracleContractAddress := GetOracleAddressbyChainID(l2ChainID) +func OracleContractInstance(client *ethclient.Client, chainID uint64, log log.Logger) (*bindings.L2OutputOracle, error) { + oracleContractAddress := GetL1OracleContractAddressByChainID(chainID) contract, err := bindings.NewL2OutputOracle(common.HexToAddress(oracleContractAddress), client) @@ -31,14 +31,14 @@ func OracleContractInstance(client *ethclient.Client, l2ChainID int, log log.Log } // TODO: Use EthClientInterface -func CreateContractInstance(url string, l2ChainID int, logger log.Logger) *bindings.L2OutputOracle { +func CreateContractInstance(url string, chainID uint64, logger log.Logger) *bindings.L2OutputOracle { client, err := ethclient.Dial(url) if err != nil { logger.Errorf("Error occurred while connecting %w", err) } - contract, err := OracleContractInstance(client, l2ChainID, logger) + contract, err := OracleContractInstance(client, chainID, logger) if err != nil { logger.Errorf("Error occurred while creating contract instance %w", err) From f21eab2167827c3341001de5edf6fcdf81c620a2 Mon Sep 17 00:00:00 2001 From: nagdahimanshu Date: Thu, 18 Jan 2024 12:25:13 +0100 Subject: [PATCH 07/13] :art: Code cleanup --- pkg/chain/chain_constants.go | 26 ++++++++++++------------- pkg/chain/contracts.go | 37 +++++++++++++++++++++++------------- 2 files changed, 37 insertions(+), 26 deletions(-) diff --git a/pkg/chain/chain_constants.go b/pkg/chain/chain_constants.go index 21f9535..213e012 100644 --- a/pkg/chain/chain_constants.go +++ b/pkg/chain/chain_constants.go @@ -15,7 +15,7 @@ type L2ChainIDs struct { BASE_MAINNET uint64 } -var L2_CHAIN_ID = L2ChainIDs{ +var L2_CHAIN_IDS = L2ChainIDs{ OPTIMISM: 10, OPTIMISM_GOERLI: 420, OPTIMISM_SEPOLIA: 11155420, @@ -36,9 +36,9 @@ type L1Contracts struct { l2OutputOracle string } -func GetContractAddresses(chainID uint64) map[string]L1Contracts { +func GetContractAddressesByChainID(chainID uint64) map[string]L1Contracts { CONTRACT_ADDRESSES := map[uint64]map[string]L1Contracts{ - L2_CHAIN_ID.OPTIMISM: { + L2_CHAIN_IDS.OPTIMISM: { "l1": { l1CrossDomainMessenger: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", stateCommitmentChain: "0xBe5dAb4A2e9cd0F27300dB4aB94BeE3A233AEB19", @@ -46,7 +46,7 @@ func GetContractAddresses(chainID uint64) map[string]L1Contracts { l2OutputOracle: "0xdfe97868233d1aa22e815a266982f2cf17685a27", }, }, - L2_CHAIN_ID.OPTIMISM_GOERLI: { + L2_CHAIN_IDS.OPTIMISM_GOERLI: { "l1": { l1CrossDomainMessenger: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", stateCommitmentChain: "0x9c945aC97Baf48cB784AbBB61399beB71aF7A378", @@ -54,7 +54,7 @@ func GetContractAddresses(chainID uint64) map[string]L1Contracts { l2OutputOracle: "0xE6Dfba0953616Bacab0c9A8ecb3a9BBa77FC15c0", }, }, - L2_CHAIN_ID.OPTIMISM_SEPOLIA: { + L2_CHAIN_IDS.OPTIMISM_SEPOLIA: { "l1": { l1CrossDomainMessenger: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", stateCommitmentChain: "0x0000000000000000000000000000000000000000", @@ -62,7 +62,7 @@ func GetContractAddresses(chainID uint64) map[string]L1Contracts { l2OutputOracle: "0x90E9c4f8a994a250F6aEfd61CAFb4F2e895D458F", }, }, - L2_CHAIN_ID.OPTIMISM_HARDHAT_LOCAL: { + L2_CHAIN_IDS.OPTIMISM_HARDHAT_LOCAL: { "l1": { l1CrossDomainMessenger: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", stateCommitmentChain: "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", @@ -70,7 +70,7 @@ func GetContractAddresses(chainID uint64) map[string]L1Contracts { l2OutputOracle: "0x0000000000000000000000000000000000000000", }, }, - L2_CHAIN_ID.OPTIMISM_HARDHAT_DEVNET: { + L2_CHAIN_IDS.OPTIMISM_HARDHAT_DEVNET: { "l1": { l1CrossDomainMessenger: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", stateCommitmentChain: "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", @@ -78,7 +78,7 @@ func GetContractAddresses(chainID uint64) map[string]L1Contracts { l2OutputOracle: "0x0000000000000000000000000000000000000000", }, }, - L2_CHAIN_ID.OPTIMISM_BEDROCK_ALPHA_TESTNET: { + L2_CHAIN_IDS.OPTIMISM_BEDROCK_ALPHA_TESTNET: { "l1": { l1CrossDomainMessenger: "0x838a6DC4E37CA45D4Ef05bb776bf05eEf50798De", stateCommitmentChain: "0x0000000000000000000000000000000000000000", @@ -86,7 +86,7 @@ func GetContractAddresses(chainID uint64) map[string]L1Contracts { l2OutputOracle: "0x3A234299a14De50027eA65dCdf1c0DaC729e04A6", }, }, - L2_CHAIN_ID.BASE_GOERLI: { + L2_CHAIN_IDS.BASE_GOERLI: { "l1": { l1CrossDomainMessenger: "0x8e5693140eA606bcEB98761d9beB1BC87383706D", stateCommitmentChain: "0x0000000000000000000000000000000000000000", @@ -94,7 +94,7 @@ func GetContractAddresses(chainID uint64) map[string]L1Contracts { l2OutputOracle: "0x2A35891ff30313CcFa6CE88dcf3858bb075A2298", }, }, - L2_CHAIN_ID.BASE_SEPOLIA: { + L2_CHAIN_IDS.BASE_SEPOLIA: { "l1": { l1CrossDomainMessenger: "0xC34855F4De64F1840e5686e64278da901e261f20", stateCommitmentChain: "0x0000000000000000000000000000000000000000", @@ -102,7 +102,7 @@ func GetContractAddresses(chainID uint64) map[string]L1Contracts { l2OutputOracle: "0x84457ca9D0163FbC4bbfe4Dfbb20ba46e48DF254", }, }, - L2_CHAIN_ID.BASE_MAINNET: { + L2_CHAIN_IDS.BASE_MAINNET: { "l1": { l1CrossDomainMessenger: "0x866E82a600A1414e583f7F13623F1aC5d58b0Afa", stateCommitmentChain: "0x0000000000000000000000000000000000000000", @@ -110,7 +110,7 @@ func GetContractAddresses(chainID uint64) map[string]L1Contracts { l2OutputOracle: "0x56315b90c40730925ec5485cf004d835058518A0", }, }, - L2_CHAIN_ID.ZORA_GOERLI: { + L2_CHAIN_IDS.ZORA_GOERLI: { "l1": { l1CrossDomainMessenger: "0xD87342e16352D33170557A7dA1e5fB966a60FafC", stateCommitmentChain: "0x0000000000000000000000000000000000000000", @@ -118,7 +118,7 @@ func GetContractAddresses(chainID uint64) map[string]L1Contracts { l2OutputOracle: "0xdD292C9eEd00f6A32Ff5245d0BCd7f2a15f24e00", }, }, - L2_CHAIN_ID.ZORA_MAINNET: { + L2_CHAIN_IDS.ZORA_MAINNET: { "l1": { l1CrossDomainMessenger: "0xdC40a14d9abd6F410226f1E6de71aE03441ca506", stateCommitmentChain: "0x0000000000000000000000000000000000000000", diff --git a/pkg/chain/contracts.go b/pkg/chain/contracts.go index d312135..c1dbd8e 100644 --- a/pkg/chain/contracts.go +++ b/pkg/chain/contracts.go @@ -11,13 +11,24 @@ import ( "github.com/ethereum-optimism/optimism/op-bindings/bindings" ) +type OracleContract struct { + contractInstance *bindings.L2OutputOracle + log log.Logger +} + +func SetContractInstance(contractInstance *bindings.L2OutputOracle, log log.Logger) (*OracleContract, error) { + return &OracleContract{ + contractInstance: contractInstance, + log: log, + }, nil +} + func GetL1OracleContractAddressByChainID(chainID uint64) string { - ContractAddresses := GetContractAddresses(chainID) + ContractAddresses := GetContractAddressesByChainID(chainID) address := ContractAddresses["l1"].l2OutputOracle return address } -// TODO: Create oracle Struct with required functions func OracleContractInstance(client *ethclient.Client, chainID uint64, log log.Logger) (*bindings.L2OutputOracle, error) { oracleContractAddress := GetL1OracleContractAddressByChainID(chainID) @@ -30,38 +41,38 @@ func OracleContractInstance(client *ethclient.Client, chainID uint64, log log.Lo return contract, nil } -// TODO: Use EthClientInterface -func CreateContractInstance(url string, chainID uint64, logger log.Logger) *bindings.L2OutputOracle { +// CreateContractInstance return [OracleContract] with contract instance. +func CreateContractInstance(url string, chainID uint64, logger log.Logger) (*OracleContract, error) { client, err := ethclient.Dial(url) if err != nil { logger.Errorf("Error occurred while connecting %w", err) } - contract, err := OracleContractInstance(client, chainID, logger) + contractInstance, err := OracleContractInstance(client, chainID, logger) if err != nil { - logger.Errorf("Error occurred while creating contract instance %w", err) + return nil, err } - return contract + return SetContractInstance(contractInstance, logger) } -func GetNextOutputIndex(contractInstance *bindings.L2OutputOracle, log log.Logger) *big.Int { - nextOutputIndex, err := contractInstance.NextOutputIndex(&bind.CallOpts{}) +func (oc *OracleContract) GetNextOutputIndex() *big.Int { + nextOutputIndex, err := oc.contractInstance.NextOutputIndex(&bind.CallOpts{}) if err != nil { - log.Errorf("Error occurred while retrieving next output index %w", err) + oc.log.Errorf("Error occurred while retrieving next output index %w", err) } return nextOutputIndex } -func GetL2Output(contractInstance *bindings.L2OutputOracle, index *big.Int, log log.Logger) bindings.TypesOutputProposal { - l2Output, err := contractInstance.GetL2Output(&bind.CallOpts{}, index) +func (oc *OracleContract) GetL2Output(index *big.Int) bindings.TypesOutputProposal { + l2Output, err := oc.contractInstance.GetL2Output(&bind.CallOpts{}, index) if err != nil { - log.Errorf("Error occurred while retrieving L2 outout %w", err) + oc.log.Errorf("Error occurred while retrieving L2 outout %w", err) } return l2Output From 3950db419ef104a265133a725a73cf5d7fe0daeb Mon Sep 17 00:00:00 2001 From: nagdahimanshu Date: Thu, 18 Jan 2024 13:58:37 +0100 Subject: [PATCH 08/13] :white_check_mark: Add tests --- pkg/chain/chain_constants.go | 85 ++++++++++++++----------------- pkg/chain/chain_constants_test.go | 25 +++++++++ pkg/chain/contracts.go | 37 +++++--------- pkg/chain/contracts_test.go | 19 +++++++ 4 files changed, 94 insertions(+), 72 deletions(-) create mode 100644 pkg/chain/chain_constants_test.go create mode 100644 pkg/chain/contracts_test.go diff --git a/pkg/chain/chain_constants.go b/pkg/chain/chain_constants.go index 213e012..f406484 100644 --- a/pkg/chain/chain_constants.go +++ b/pkg/chain/chain_constants.go @@ -30,100 +30,89 @@ var L2_CHAIN_IDS = L2ChainIDs{ } type L1Contracts struct { - l1CrossDomainMessenger string - stateCommitmentChain string - optimismPortal string - l2OutputOracle string + stateCommitmentChain string + optimismPortal string + l2OutputOracle string } +// GetContractAddressesByChainID returns contract addresses by chainID. func GetContractAddressesByChainID(chainID uint64) map[string]L1Contracts { CONTRACT_ADDRESSES := map[uint64]map[string]L1Contracts{ L2_CHAIN_IDS.OPTIMISM: { "l1": { - l1CrossDomainMessenger: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", - stateCommitmentChain: "0xBe5dAb4A2e9cd0F27300dB4aB94BeE3A233AEB19", - optimismPortal: "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed", - l2OutputOracle: "0xdfe97868233d1aa22e815a266982f2cf17685a27", + stateCommitmentChain: "0xBe5dAb4A2e9cd0F27300dB4aB94BeE3A233AEB19", + optimismPortal: "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed", + l2OutputOracle: "0xdfe97868233d1aa22e815a266982f2cf17685a27", }, }, L2_CHAIN_IDS.OPTIMISM_GOERLI: { "l1": { - l1CrossDomainMessenger: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", - stateCommitmentChain: "0x9c945aC97Baf48cB784AbBB61399beB71aF7A378", - optimismPortal: "0x5b47E1A08Ea6d985D6649300584e6722Ec4B1383", - l2OutputOracle: "0xE6Dfba0953616Bacab0c9A8ecb3a9BBa77FC15c0", + stateCommitmentChain: "0x9c945aC97Baf48cB784AbBB61399beB71aF7A378", + optimismPortal: "0x5b47E1A08Ea6d985D6649300584e6722Ec4B1383", + l2OutputOracle: "0xE6Dfba0953616Bacab0c9A8ecb3a9BBa77FC15c0", }, }, L2_CHAIN_IDS.OPTIMISM_SEPOLIA: { "l1": { - l1CrossDomainMessenger: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", - stateCommitmentChain: "0x0000000000000000000000000000000000000000", - optimismPortal: "0x16Fc5058F25648194471939df75CF27A2fdC48BC", - l2OutputOracle: "0x90E9c4f8a994a250F6aEfd61CAFb4F2e895D458F", + stateCommitmentChain: "0x0000000000000000000000000000000000000000", + optimismPortal: "0x16Fc5058F25648194471939df75CF27A2fdC48BC", + l2OutputOracle: "0x90E9c4f8a994a250F6aEfd61CAFb4F2e895D458F", }, }, L2_CHAIN_IDS.OPTIMISM_HARDHAT_LOCAL: { "l1": { - l1CrossDomainMessenger: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", - stateCommitmentChain: "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", - optimismPortal: "0x0000000000000000000000000000000000000000", - l2OutputOracle: "0x0000000000000000000000000000000000000000", + stateCommitmentChain: "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", + optimismPortal: "0x0000000000000000000000000000000000000000", + l2OutputOracle: "0x0000000000000000000000000000000000000000", }, }, L2_CHAIN_IDS.OPTIMISM_HARDHAT_DEVNET: { "l1": { - l1CrossDomainMessenger: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318", - stateCommitmentChain: "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", - optimismPortal: "0x0000000000000000000000000000000000000000", - l2OutputOracle: "0x0000000000000000000000000000000000000000", + stateCommitmentChain: "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", + optimismPortal: "0x0000000000000000000000000000000000000000", + l2OutputOracle: "0x0000000000000000000000000000000000000000", }, }, L2_CHAIN_IDS.OPTIMISM_BEDROCK_ALPHA_TESTNET: { "l1": { - l1CrossDomainMessenger: "0x838a6DC4E37CA45D4Ef05bb776bf05eEf50798De", - stateCommitmentChain: "0x0000000000000000000000000000000000000000", - optimismPortal: "0xA581Ca3353DB73115C4625FFC7aDF5dB379434A8", - l2OutputOracle: "0x3A234299a14De50027eA65dCdf1c0DaC729e04A6", + stateCommitmentChain: "0x0000000000000000000000000000000000000000", + optimismPortal: "0xA581Ca3353DB73115C4625FFC7aDF5dB379434A8", + l2OutputOracle: "0x3A234299a14De50027eA65dCdf1c0DaC729e04A6", }, }, L2_CHAIN_IDS.BASE_GOERLI: { "l1": { - l1CrossDomainMessenger: "0x8e5693140eA606bcEB98761d9beB1BC87383706D", - stateCommitmentChain: "0x0000000000000000000000000000000000000000", - optimismPortal: "0xe93c8cD0D409341205A592f8c4Ac1A5fe5585cfA", - l2OutputOracle: "0x2A35891ff30313CcFa6CE88dcf3858bb075A2298", + stateCommitmentChain: "0x0000000000000000000000000000000000000000", + optimismPortal: "0xe93c8cD0D409341205A592f8c4Ac1A5fe5585cfA", + l2OutputOracle: "0x2A35891ff30313CcFa6CE88dcf3858bb075A2298", }, }, L2_CHAIN_IDS.BASE_SEPOLIA: { "l1": { - l1CrossDomainMessenger: "0xC34855F4De64F1840e5686e64278da901e261f20", - stateCommitmentChain: "0x0000000000000000000000000000000000000000", - optimismPortal: "0x49f53e41452C74589E85cA1677426Ba426459e85", - l2OutputOracle: "0x84457ca9D0163FbC4bbfe4Dfbb20ba46e48DF254", + stateCommitmentChain: "0x0000000000000000000000000000000000000000", + optimismPortal: "0x49f53e41452C74589E85cA1677426Ba426459e85", + l2OutputOracle: "0x84457ca9D0163FbC4bbfe4Dfbb20ba46e48DF254", }, }, L2_CHAIN_IDS.BASE_MAINNET: { "l1": { - l1CrossDomainMessenger: "0x866E82a600A1414e583f7F13623F1aC5d58b0Afa", - stateCommitmentChain: "0x0000000000000000000000000000000000000000", - optimismPortal: "0x49048044D57e1C92A77f79988d21Fa8fAF74E97e", - l2OutputOracle: "0x56315b90c40730925ec5485cf004d835058518A0", + stateCommitmentChain: "0x0000000000000000000000000000000000000000", + optimismPortal: "0x49048044D57e1C92A77f79988d21Fa8fAF74E97e", + l2OutputOracle: "0x56315b90c40730925ec5485cf004d835058518A0", }, }, L2_CHAIN_IDS.ZORA_GOERLI: { "l1": { - l1CrossDomainMessenger: "0xD87342e16352D33170557A7dA1e5fB966a60FafC", - stateCommitmentChain: "0x0000000000000000000000000000000000000000", - optimismPortal: "0xDb9F51790365e7dc196e7D072728df39Be958ACe", - l2OutputOracle: "0xdD292C9eEd00f6A32Ff5245d0BCd7f2a15f24e00", + stateCommitmentChain: "0x0000000000000000000000000000000000000000", + optimismPortal: "0xDb9F51790365e7dc196e7D072728df39Be958ACe", + l2OutputOracle: "0xdD292C9eEd00f6A32Ff5245d0BCd7f2a15f24e00", }, }, L2_CHAIN_IDS.ZORA_MAINNET: { "l1": { - l1CrossDomainMessenger: "0xdC40a14d9abd6F410226f1E6de71aE03441ca506", - stateCommitmentChain: "0x0000000000000000000000000000000000000000", - optimismPortal: "0x1a0ad011913A150f69f6A19DF447A0CfD9551054", - l2OutputOracle: "0x9E6204F750cD866b299594e2aC9eA824E2e5f95c", + stateCommitmentChain: "0x0000000000000000000000000000000000000000", + optimismPortal: "0x1a0ad011913A150f69f6A19DF447A0CfD9551054", + l2OutputOracle: "0x9E6204F750cD866b299594e2aC9eA824E2e5f95c", }, }, } diff --git a/pkg/chain/chain_constants_test.go b/pkg/chain/chain_constants_test.go new file mode 100644 index 0000000..3f858a6 --- /dev/null +++ b/pkg/chain/chain_constants_test.go @@ -0,0 +1,25 @@ +package chain + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestGetContractAddressesByChainID(t *testing.T) { + const availableChainID uint64 = 10 + var contractAddresses = GetContractAddressesByChainID(availableChainID) + var contractAddressesExpected = map[string]L1Contracts{ + "l1": { + stateCommitmentChain: "0xBe5dAb4A2e9cd0F27300dB4aB94BeE3A233AEB19", + optimismPortal: "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed", + l2OutputOracle: "0xdfe97868233d1aa22e815a266982f2cf17685a27", + }} + + assert.Equal(t, contractAddressesExpected, contractAddresses) + + const unavailableChainID uint64 = 5 + contractAddresses = GetContractAddressesByChainID(unavailableChainID) + + assert.Equal(t, 0, len(contractAddresses)) +} diff --git a/pkg/chain/contracts.go b/pkg/chain/contracts.go index c1dbd8e..f77c8d6 100644 --- a/pkg/chain/contracts.go +++ b/pkg/chain/contracts.go @@ -11,53 +11,41 @@ import ( "github.com/ethereum-optimism/optimism/op-bindings/bindings" ) +// OracleContract binds oracle contract to an instance for querying data. type OracleContract struct { contractInstance *bindings.L2OutputOracle log log.Logger } -func SetContractInstance(contractInstance *bindings.L2OutputOracle, log log.Logger) (*OracleContract, error) { - return &OracleContract{ - contractInstance: contractInstance, - log: log, - }, nil -} - +// GetL1OracleContractAddressByChainID returns L1 oracle contract address by chainID. func GetL1OracleContractAddressByChainID(chainID uint64) string { ContractAddresses := GetContractAddressesByChainID(chainID) address := ContractAddresses["l1"].l2OutputOracle return address } -func OracleContractInstance(client *ethclient.Client, chainID uint64, log log.Logger) (*bindings.L2OutputOracle, error) { - oracleContractAddress := GetL1OracleContractAddressByChainID(chainID) - - contract, err := bindings.NewL2OutputOracle(common.HexToAddress(oracleContractAddress), client) - - if err != nil { - return nil, err - } - - return contract, nil -} - -// CreateContractInstance return [OracleContract] with contract instance. -func CreateContractInstance(url string, chainID uint64, logger log.Logger) (*OracleContract, error) { +// CreateOracleContractInstance returns [OracleContract] with contract instance. +func CreateOracleContractInstance(url string, chainID uint64, logger log.Logger) (*OracleContract, error) { client, err := ethclient.Dial(url) if err != nil { - logger.Errorf("Error occurred while connecting %w", err) + return nil, err } - contractInstance, err := OracleContractInstance(client, chainID, logger) + oracleContractAddress := GetL1OracleContractAddressByChainID(chainID) + contractInstance, err := bindings.NewL2OutputOracle(common.HexToAddress(oracleContractAddress), client) if err != nil { return nil, err } - return SetContractInstance(contractInstance, logger) + return &OracleContract{ + contractInstance: contractInstance, + log: logger, + }, nil } +// GetNextOutputIndex returns index of next output to be proposed. func (oc *OracleContract) GetNextOutputIndex() *big.Int { nextOutputIndex, err := oc.contractInstance.NextOutputIndex(&bind.CallOpts{}) @@ -68,6 +56,7 @@ func (oc *OracleContract) GetNextOutputIndex() *big.Int { return nextOutputIndex } +// GetL2Output returns L2 output at given index. func (oc *OracleContract) GetL2Output(index *big.Int) bindings.TypesOutputProposal { l2Output, err := oc.contractInstance.GetL2Output(&bind.CallOpts{}, index) diff --git a/pkg/chain/contracts_test.go b/pkg/chain/contracts_test.go new file mode 100644 index 0000000..e278bc9 --- /dev/null +++ b/pkg/chain/contracts_test.go @@ -0,0 +1,19 @@ +package chain + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestGetL1OracleContractAddressByChainID(t *testing.T) { + const availableChainID uint64 = 10 + var contractAddresses = GetL1OracleContractAddressByChainID(availableChainID) + var oracleContractAddressesExpected = "0xdfe97868233d1aa22e815a266982f2cf17685a27" + + assert.Equal(t, oracleContractAddressesExpected, contractAddresses) + + const unavailableChainID uint64 = 5 + contractAddresses = GetL1OracleContractAddressByChainID(unavailableChainID) + assert.Equal(t, 0, len(contractAddresses)) +} From 6a8df0cd3f700b05ad3b22ee29df54a6327cd3eb Mon Sep 17 00:00:00 2001 From: nagdahimanshu Date: Fri, 19 Jan 2024 11:09:20 +0100 Subject: [PATCH 09/13] :ok_hand: Applied suggestions from code review --- pkg/chain/chain_constants.go | 75 ++++++++++++++++--------------- pkg/chain/chain_constants_test.go | 10 +++-- pkg/chain/contracts.go | 36 +++++---------- pkg/chain/contracts_test.go | 15 ++++--- 4 files changed, 65 insertions(+), 71 deletions(-) diff --git a/pkg/chain/chain_constants.go b/pkg/chain/chain_constants.go index f406484..e2859eb 100644 --- a/pkg/chain/chain_constants.go +++ b/pkg/chain/chain_constants.go @@ -1,34 +1,35 @@ package chain +// L2ChainIDs manages L2 network chainIDs. type L2ChainIDs struct { - OPTIMISM uint64 - OPTIMISM_GOERLI uint64 - OPTIMISM_HARDHAT_LOCAL uint64 - OPTIMISM_HARDHAT_DEVNET uint64 - OPTIMISM_BEDROCK_LOCAL_DEVNET uint64 - OPTIMISM_BEDROCK_ALPHA_TESTNET uint64 - BASE_GOERLI uint64 - ZORA_GOERLI uint64 - ZORA_MAINNET uint64 - OPTIMISM_SEPOLIA uint64 - BASE_SEPOLIA uint64 - BASE_MAINNET uint64 + optimism uint64 + optimismGoerli uint64 + optimismSepolia uint64 + optimismHardhatLocal uint64 + optimismHardhatDevnet uint64 + optimismBedrockAlphaTestnet uint64 + baseMainnet uint64 + baseGoerli uint64 + baseSepolia uint64 + zoraGoerli uint64 + zoraMainnet uint64 } -var L2_CHAIN_IDS = L2ChainIDs{ - OPTIMISM: 10, - OPTIMISM_GOERLI: 420, - OPTIMISM_SEPOLIA: 11155420, - OPTIMISM_HARDHAT_LOCAL: 31337, - OPTIMISM_HARDHAT_DEVNET: 17, - OPTIMISM_BEDROCK_ALPHA_TESTNET: 28528, - BASE_GOERLI: 84531, - BASE_SEPOLIA: 84532, - BASE_MAINNET: 8453, - ZORA_GOERLI: 999, - ZORA_MAINNET: 7777777, +var l2NetworkChainIDs = L2ChainIDs{ + optimism: 10, + optimismGoerli: 420, + optimismSepolia: 11155420, + optimismHardhatLocal: 31337, + optimismHardhatDevnet: 17, + optimismBedrockAlphaTestnet: 28528, + baseGoerli: 84531, + baseSepolia: 84532, + baseMainnet: 8453, + zoraGoerli: 999, + zoraMainnet: 7777777, } +// L1Contracts returns L1 network contracts adresses. type L1Contracts struct { stateCommitmentChain string optimismPortal string @@ -37,78 +38,78 @@ type L1Contracts struct { // GetContractAddressesByChainID returns contract addresses by chainID. func GetContractAddressesByChainID(chainID uint64) map[string]L1Contracts { - CONTRACT_ADDRESSES := map[uint64]map[string]L1Contracts{ - L2_CHAIN_IDS.OPTIMISM: { + contractAddresses := map[uint64]map[string]L1Contracts{ + l2NetworkChainIDs.optimism: { "l1": { stateCommitmentChain: "0xBe5dAb4A2e9cd0F27300dB4aB94BeE3A233AEB19", optimismPortal: "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed", l2OutputOracle: "0xdfe97868233d1aa22e815a266982f2cf17685a27", }, }, - L2_CHAIN_IDS.OPTIMISM_GOERLI: { + l2NetworkChainIDs.optimismGoerli: { "l1": { stateCommitmentChain: "0x9c945aC97Baf48cB784AbBB61399beB71aF7A378", optimismPortal: "0x5b47E1A08Ea6d985D6649300584e6722Ec4B1383", l2OutputOracle: "0xE6Dfba0953616Bacab0c9A8ecb3a9BBa77FC15c0", }, }, - L2_CHAIN_IDS.OPTIMISM_SEPOLIA: { + l2NetworkChainIDs.optimismSepolia: { "l1": { stateCommitmentChain: "0x0000000000000000000000000000000000000000", optimismPortal: "0x16Fc5058F25648194471939df75CF27A2fdC48BC", l2OutputOracle: "0x90E9c4f8a994a250F6aEfd61CAFb4F2e895D458F", }, }, - L2_CHAIN_IDS.OPTIMISM_HARDHAT_LOCAL: { + l2NetworkChainIDs.optimismHardhatLocal: { "l1": { stateCommitmentChain: "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", optimismPortal: "0x0000000000000000000000000000000000000000", l2OutputOracle: "0x0000000000000000000000000000000000000000", }, }, - L2_CHAIN_IDS.OPTIMISM_HARDHAT_DEVNET: { + l2NetworkChainIDs.optimismHardhatDevnet: { "l1": { stateCommitmentChain: "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", optimismPortal: "0x0000000000000000000000000000000000000000", l2OutputOracle: "0x0000000000000000000000000000000000000000", }, }, - L2_CHAIN_IDS.OPTIMISM_BEDROCK_ALPHA_TESTNET: { + l2NetworkChainIDs.optimismBedrockAlphaTestnet: { "l1": { stateCommitmentChain: "0x0000000000000000000000000000000000000000", optimismPortal: "0xA581Ca3353DB73115C4625FFC7aDF5dB379434A8", l2OutputOracle: "0x3A234299a14De50027eA65dCdf1c0DaC729e04A6", }, }, - L2_CHAIN_IDS.BASE_GOERLI: { + l2NetworkChainIDs.baseGoerli: { "l1": { stateCommitmentChain: "0x0000000000000000000000000000000000000000", optimismPortal: "0xe93c8cD0D409341205A592f8c4Ac1A5fe5585cfA", l2OutputOracle: "0x2A35891ff30313CcFa6CE88dcf3858bb075A2298", }, }, - L2_CHAIN_IDS.BASE_SEPOLIA: { + l2NetworkChainIDs.baseSepolia: { "l1": { stateCommitmentChain: "0x0000000000000000000000000000000000000000", optimismPortal: "0x49f53e41452C74589E85cA1677426Ba426459e85", l2OutputOracle: "0x84457ca9D0163FbC4bbfe4Dfbb20ba46e48DF254", }, }, - L2_CHAIN_IDS.BASE_MAINNET: { + l2NetworkChainIDs.baseMainnet: { "l1": { stateCommitmentChain: "0x0000000000000000000000000000000000000000", optimismPortal: "0x49048044D57e1C92A77f79988d21Fa8fAF74E97e", l2OutputOracle: "0x56315b90c40730925ec5485cf004d835058518A0", }, }, - L2_CHAIN_IDS.ZORA_GOERLI: { + l2NetworkChainIDs.zoraGoerli: { "l1": { stateCommitmentChain: "0x0000000000000000000000000000000000000000", optimismPortal: "0xDb9F51790365e7dc196e7D072728df39Be958ACe", l2OutputOracle: "0xdD292C9eEd00f6A32Ff5245d0BCd7f2a15f24e00", }, }, - L2_CHAIN_IDS.ZORA_MAINNET: { + l2NetworkChainIDs.zoraMainnet: { "l1": { stateCommitmentChain: "0x0000000000000000000000000000000000000000", optimismPortal: "0x1a0ad011913A150f69f6A19DF447A0CfD9551054", @@ -117,5 +118,5 @@ func GetContractAddressesByChainID(chainID uint64) map[string]L1Contracts { }, } - return CONTRACT_ADDRESSES[chainID] + return contractAddresses[chainID] } diff --git a/pkg/chain/chain_constants_test.go b/pkg/chain/chain_constants_test.go index 3f858a6..b7093c5 100644 --- a/pkg/chain/chain_constants_test.go +++ b/pkg/chain/chain_constants_test.go @@ -6,10 +6,10 @@ import ( "github.com/stretchr/testify/assert" ) -func TestGetContractAddressesByChainID(t *testing.T) { +func TestGetContractAddressesByChainID_AvailableChainID(t *testing.T) { const availableChainID uint64 = 10 - var contractAddresses = GetContractAddressesByChainID(availableChainID) - var contractAddressesExpected = map[string]L1Contracts{ + contractAddresses := GetContractAddressesByChainID(availableChainID) + contractAddressesExpected := map[string]L1Contracts{ "l1": { stateCommitmentChain: "0xBe5dAb4A2e9cd0F27300dB4aB94BeE3A233AEB19", optimismPortal: "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed", @@ -17,9 +17,11 @@ func TestGetContractAddressesByChainID(t *testing.T) { }} assert.Equal(t, contractAddressesExpected, contractAddresses) +} +func TestGetContractAddressesByChainID_UnavailableChainID(t *testing.T) { const unavailableChainID uint64 = 5 - contractAddresses = GetContractAddressesByChainID(unavailableChainID) + contractAddresses := GetContractAddressesByChainID(unavailableChainID) assert.Equal(t, 0, len(contractAddresses)) } diff --git a/pkg/chain/contracts.go b/pkg/chain/contracts.go index f77c8d6..78023b5 100644 --- a/pkg/chain/contracts.go +++ b/pkg/chain/contracts.go @@ -11,58 +11,46 @@ import ( "github.com/ethereum-optimism/optimism/op-bindings/bindings" ) -// OracleContract binds oracle contract to an instance for querying data. -type OracleContract struct { +// OracleAccessor binds oracle contract to an instance for querying data. +type OracleAccessor struct { contractInstance *bindings.L2OutputOracle log log.Logger } -// GetL1OracleContractAddressByChainID returns L1 oracle contract address by chainID. -func GetL1OracleContractAddressByChainID(chainID uint64) string { +// getL1OracleContractAddressByChainID returns L1 oracle contract address by chainID. +func getL1OracleContractAddressByChainID(chainID uint64) string { ContractAddresses := GetContractAddressesByChainID(chainID) address := ContractAddresses["l1"].l2OutputOracle return address } -// CreateOracleContractInstance returns [OracleContract] with contract instance. -func CreateOracleContractInstance(url string, chainID uint64, logger log.Logger) (*OracleContract, error) { +// NewOracleContract returns [OracleAccessor] with contract instance. +func NewOracleContract(url string, chainID uint64, logger log.Logger) (*OracleAccessor, error) { client, err := ethclient.Dial(url) if err != nil { return nil, err } - oracleContractAddress := GetL1OracleContractAddressByChainID(chainID) + oracleContractAddress := getL1OracleContractAddressByChainID(chainID) contractInstance, err := bindings.NewL2OutputOracle(common.HexToAddress(oracleContractAddress), client) if err != nil { return nil, err } - return &OracleContract{ + return &OracleAccessor{ contractInstance: contractInstance, log: logger, }, nil } // GetNextOutputIndex returns index of next output to be proposed. -func (oc *OracleContract) GetNextOutputIndex() *big.Int { - nextOutputIndex, err := oc.contractInstance.NextOutputIndex(&bind.CallOpts{}) - - if err != nil { - oc.log.Errorf("Error occurred while retrieving next output index %w", err) - } - - return nextOutputIndex +func (oc *OracleAccessor) GetNextOutputIndex() (*big.Int, error) { + return oc.contractInstance.NextOutputIndex(&bind.CallOpts{}) } // GetL2Output returns L2 output at given index. -func (oc *OracleContract) GetL2Output(index *big.Int) bindings.TypesOutputProposal { - l2Output, err := oc.contractInstance.GetL2Output(&bind.CallOpts{}, index) - - if err != nil { - oc.log.Errorf("Error occurred while retrieving L2 outout %w", err) - } - - return l2Output +func (oc *OracleAccessor) GetL2Output(index *big.Int) (bindings.TypesOutputProposal, error) { + return oc.contractInstance.GetL2Output(&bind.CallOpts{}, index) } diff --git a/pkg/chain/contracts_test.go b/pkg/chain/contracts_test.go index e278bc9..d843af4 100644 --- a/pkg/chain/contracts_test.go +++ b/pkg/chain/contracts_test.go @@ -6,14 +6,17 @@ import ( "github.com/stretchr/testify/assert" ) -func TestGetL1OracleContractAddressByChainID(t *testing.T) { +func TestGetL1OracleContractAddressByChainID_AvailableChainID(t *testing.T) { const availableChainID uint64 = 10 - var contractAddresses = GetL1OracleContractAddressByChainID(availableChainID) - var oracleContractAddressesExpected = "0xdfe97868233d1aa22e815a266982f2cf17685a27" + var contractAddress = getL1OracleContractAddressByChainID(availableChainID) + var oracleContractAddressExpected = "0xdfe97868233d1aa22e815a266982f2cf17685a27" - assert.Equal(t, oracleContractAddressesExpected, contractAddresses) + assert.Equal(t, oracleContractAddressExpected, contractAddress) +} +func TestGetL1OracleContractAddressByChainID_UnavailableChainID(t *testing.T) { const unavailableChainID uint64 = 5 - contractAddresses = GetL1OracleContractAddressByChainID(unavailableChainID) - assert.Equal(t, 0, len(contractAddresses)) + contractAddress := getL1OracleContractAddressByChainID(unavailableChainID) + + assert.Equal(t, 0, len(contractAddress)) } From 9ffb3a8c713e88c7461f767aed0354f2b9101176 Mon Sep 17 00:00:00 2001 From: nagdahimanshu Date: Fri, 19 Jan 2024 18:01:41 +0100 Subject: [PATCH 10/13] :ok_hand: Applied suggestions --- pkg/chain/chain_constants.go | 132 ++++++++++++++++-------------- pkg/chain/chain_constants_test.go | 21 +++-- pkg/chain/contracts.go | 45 +++++++--- pkg/chain/contracts_test.go | 6 +- 4 files changed, 120 insertions(+), 84 deletions(-) diff --git a/pkg/chain/chain_constants.go b/pkg/chain/chain_constants.go index e2859eb..aa8f40c 100644 --- a/pkg/chain/chain_constants.go +++ b/pkg/chain/chain_constants.go @@ -1,5 +1,7 @@ package chain +import "fmt" + // L2ChainIDs manages L2 network chainIDs. type L2ChainIDs struct { optimism uint64 @@ -13,6 +15,7 @@ type L2ChainIDs struct { baseSepolia uint64 zoraGoerli uint64 zoraMainnet uint64 + liskSepolia uint64 } var l2NetworkChainIDs = L2ChainIDs{ @@ -27,96 +30,105 @@ var l2NetworkChainIDs = L2ChainIDs{ baseMainnet: 8453, zoraGoerli: 999, zoraMainnet: 7777777, + liskSepolia: 4202, } -// L1Contracts returns L1 network contracts adresses. -type L1Contracts struct { +type NetworkType = string + +const ( + L1 = NetworkType("L1") + L2 = NetworkType("L2") +) + +// Contracts has information of the L1 & L2 contracts addresses. +type Contracts struct { stateCommitmentChain string optimismPortal string l2OutputOracle string + networkType NetworkType } // GetContractAddressesByChainID returns contract addresses by chainID. -func GetContractAddressesByChainID(chainID uint64) map[string]L1Contracts { - contractAddresses := map[uint64]map[string]L1Contracts{ +func GetContractAddressesByChainID(chainID uint64) (Contracts, error) { + contractAddresses := map[uint64]Contracts{ l2NetworkChainIDs.optimism: { - "l1": { - stateCommitmentChain: "0xBe5dAb4A2e9cd0F27300dB4aB94BeE3A233AEB19", - optimismPortal: "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed", - l2OutputOracle: "0xdfe97868233d1aa22e815a266982f2cf17685a27", - }, + stateCommitmentChain: "0xBe5dAb4A2e9cd0F27300dB4aB94BeE3A233AEB19", + optimismPortal: "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed", + l2OutputOracle: "0xdfe97868233d1aa22e815a266982f2cf17685a27", + networkType: L1, }, l2NetworkChainIDs.optimismGoerli: { - "l1": { - stateCommitmentChain: "0x9c945aC97Baf48cB784AbBB61399beB71aF7A378", - optimismPortal: "0x5b47E1A08Ea6d985D6649300584e6722Ec4B1383", - l2OutputOracle: "0xE6Dfba0953616Bacab0c9A8ecb3a9BBa77FC15c0", - }, + stateCommitmentChain: "0x9c945aC97Baf48cB784AbBB61399beB71aF7A378", + optimismPortal: "0x5b47E1A08Ea6d985D6649300584e6722Ec4B1383", + l2OutputOracle: "0xE6Dfba0953616Bacab0c9A8ecb3a9BBa77FC15c0", + networkType: L1, }, l2NetworkChainIDs.optimismSepolia: { - "l1": { - stateCommitmentChain: "0x0000000000000000000000000000000000000000", - optimismPortal: "0x16Fc5058F25648194471939df75CF27A2fdC48BC", - l2OutputOracle: "0x90E9c4f8a994a250F6aEfd61CAFb4F2e895D458F", - }, + stateCommitmentChain: "0x0000000000000000000000000000000000000000", + optimismPortal: "0x16Fc5058F25648194471939df75CF27A2fdC48BC", + l2OutputOracle: "0x90E9c4f8a994a250F6aEfd61CAFb4F2e895D458F", + networkType: L1, }, l2NetworkChainIDs.optimismHardhatLocal: { - "l1": { - stateCommitmentChain: "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", - optimismPortal: "0x0000000000000000000000000000000000000000", - l2OutputOracle: "0x0000000000000000000000000000000000000000", - }, + stateCommitmentChain: "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", + optimismPortal: "0x0000000000000000000000000000000000000000", + l2OutputOracle: "0x0000000000000000000000000000000000000000", + networkType: L1, }, l2NetworkChainIDs.optimismHardhatDevnet: { - "l1": { - stateCommitmentChain: "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", - optimismPortal: "0x0000000000000000000000000000000000000000", - l2OutputOracle: "0x0000000000000000000000000000000000000000", - }, + stateCommitmentChain: "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", + optimismPortal: "0x0000000000000000000000000000000000000000", + l2OutputOracle: "0x0000000000000000000000000000000000000000", + networkType: L1, }, l2NetworkChainIDs.optimismBedrockAlphaTestnet: { - "l1": { - stateCommitmentChain: "0x0000000000000000000000000000000000000000", - optimismPortal: "0xA581Ca3353DB73115C4625FFC7aDF5dB379434A8", - l2OutputOracle: "0x3A234299a14De50027eA65dCdf1c0DaC729e04A6", - }, + stateCommitmentChain: "0x0000000000000000000000000000000000000000", + optimismPortal: "0xA581Ca3353DB73115C4625FFC7aDF5dB379434A8", + l2OutputOracle: "0x3A234299a14De50027eA65dCdf1c0DaC729e04A6", + networkType: L1, }, l2NetworkChainIDs.baseGoerli: { - "l1": { - stateCommitmentChain: "0x0000000000000000000000000000000000000000", - optimismPortal: "0xe93c8cD0D409341205A592f8c4Ac1A5fe5585cfA", - l2OutputOracle: "0x2A35891ff30313CcFa6CE88dcf3858bb075A2298", - }, + stateCommitmentChain: "0x0000000000000000000000000000000000000000", + optimismPortal: "0xe93c8cD0D409341205A592f8c4Ac1A5fe5585cfA", + l2OutputOracle: "0x2A35891ff30313CcFa6CE88dcf3858bb075A2298", + networkType: L1, }, l2NetworkChainIDs.baseSepolia: { - "l1": { - stateCommitmentChain: "0x0000000000000000000000000000000000000000", - optimismPortal: "0x49f53e41452C74589E85cA1677426Ba426459e85", - l2OutputOracle: "0x84457ca9D0163FbC4bbfe4Dfbb20ba46e48DF254", - }, + stateCommitmentChain: "0x0000000000000000000000000000000000000000", + optimismPortal: "0x49f53e41452C74589E85cA1677426Ba426459e85", + l2OutputOracle: "0x84457ca9D0163FbC4bbfe4Dfbb20ba46e48DF254", + networkType: L1, }, l2NetworkChainIDs.baseMainnet: { - "l1": { - stateCommitmentChain: "0x0000000000000000000000000000000000000000", - optimismPortal: "0x49048044D57e1C92A77f79988d21Fa8fAF74E97e", - l2OutputOracle: "0x56315b90c40730925ec5485cf004d835058518A0", - }, + stateCommitmentChain: "0x0000000000000000000000000000000000000000", + optimismPortal: "0x49048044D57e1C92A77f79988d21Fa8fAF74E97e", + l2OutputOracle: "0x56315b90c40730925ec5485cf004d835058518A0", + networkType: L1, }, l2NetworkChainIDs.zoraGoerli: { - "l1": { - stateCommitmentChain: "0x0000000000000000000000000000000000000000", - optimismPortal: "0xDb9F51790365e7dc196e7D072728df39Be958ACe", - l2OutputOracle: "0xdD292C9eEd00f6A32Ff5245d0BCd7f2a15f24e00", - }, + stateCommitmentChain: "0x0000000000000000000000000000000000000000", + optimismPortal: "0xDb9F51790365e7dc196e7D072728df39Be958ACe", + l2OutputOracle: "0xdD292C9eEd00f6A32Ff5245d0BCd7f2a15f24e00", + networkType: L1, }, l2NetworkChainIDs.zoraMainnet: { - "l1": { - stateCommitmentChain: "0x0000000000000000000000000000000000000000", - optimismPortal: "0x1a0ad011913A150f69f6A19DF447A0CfD9551054", - l2OutputOracle: "0x9E6204F750cD866b299594e2aC9eA824E2e5f95c", - }, + stateCommitmentChain: "0x0000000000000000000000000000000000000000", + optimismPortal: "0x1a0ad011913A150f69f6A19DF447A0CfD9551054", + l2OutputOracle: "0x9E6204F750cD866b299594e2aC9eA824E2e5f95c", + networkType: L1, + }, + l2NetworkChainIDs.liskSepolia: { + optimismPortal: "0xe3d90F21490686Ec7eF37BE788E02dfC12787264", + l2OutputOracle: "0xA0E35F56C318DE1bD5D9ca6A94Fe7e37C5663348", + networkType: L1, }, } - return contractAddresses[chainID] + filteredContracts := contractAddresses[chainID] + + if len(filteredContracts.l2OutputOracle) == 0 { + return filteredContracts, fmt.Errorf("contract information is unavailable for the chain %v", chainID) + } + + return filteredContracts, nil } diff --git a/pkg/chain/chain_constants_test.go b/pkg/chain/chain_constants_test.go index b7093c5..1c77169 100644 --- a/pkg/chain/chain_constants_test.go +++ b/pkg/chain/chain_constants_test.go @@ -8,20 +8,23 @@ import ( func TestGetContractAddressesByChainID_AvailableChainID(t *testing.T) { const availableChainID uint64 = 10 - contractAddresses := GetContractAddressesByChainID(availableChainID) - contractAddressesExpected := map[string]L1Contracts{ - "l1": { - stateCommitmentChain: "0xBe5dAb4A2e9cd0F27300dB4aB94BeE3A233AEB19", - optimismPortal: "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed", - l2OutputOracle: "0xdfe97868233d1aa22e815a266982f2cf17685a27", - }} + contractAddresses, err := GetContractAddressesByChainID(availableChainID) + contractAddressesExpected := Contracts{ + stateCommitmentChain: "0xBe5dAb4A2e9cd0F27300dB4aB94BeE3A233AEB19", + optimismPortal: "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed", + l2OutputOracle: "0xdfe97868233d1aa22e815a266982f2cf17685a27", + networkType: "L1", + } + + assert.NoError(t, err) assert.Equal(t, contractAddressesExpected, contractAddresses) } func TestGetContractAddressesByChainID_UnavailableChainID(t *testing.T) { const unavailableChainID uint64 = 5 - contractAddresses := GetContractAddressesByChainID(unavailableChainID) + contractAddresses, err := GetContractAddressesByChainID(unavailableChainID) - assert.Equal(t, 0, len(contractAddresses)) + assert.Error(t, err) + assert.Equal(t, 0, len(contractAddresses.l2OutputOracle)) } diff --git a/pkg/chain/contracts.go b/pkg/chain/contracts.go index 78023b5..253d199 100644 --- a/pkg/chain/contracts.go +++ b/pkg/chain/contracts.go @@ -1,9 +1,10 @@ package chain import ( + "context" + "fmt" "math/big" - "github.com/LiskHQ/op-fault-detector/pkg/log" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethclient" @@ -14,34 +15,52 @@ import ( // OracleAccessor binds oracle contract to an instance for querying data. type OracleAccessor struct { contractInstance *bindings.L2OutputOracle - log log.Logger +} + +type ConfigOptions struct { + L1RPCEndpoint string + ChainID uint64 + L2OutputOracleContractAddress string } // getL1OracleContractAddressByChainID returns L1 oracle contract address by chainID. -func getL1OracleContractAddressByChainID(chainID uint64) string { - ContractAddresses := GetContractAddressesByChainID(chainID) - address := ContractAddresses["l1"].l2OutputOracle - return address +func getL1OracleContractAddressByChainID(chainID uint64) (string, error) { + ContractAddresses, err := GetContractAddressesByChainID(chainID) + if err != nil { + return "", err + } + + address := ContractAddresses.l2OutputOracle + return address, nil } // NewOracleContract returns [OracleAccessor] with contract instance. -func NewOracleContract(url string, chainID uint64, logger log.Logger) (*OracleAccessor, error) { - client, err := ethclient.Dial(url) - +func NewOracleContract(ctx context.Context, opts ConfigOptions) (*OracleAccessor, error) { + client, err := ethclient.DialContext(ctx, opts.L1RPCEndpoint) if err != nil { return nil, err } - oracleContractAddress := getL1OracleContractAddressByChainID(chainID) - contractInstance, err := bindings.NewL2OutputOracle(common.HexToAddress(oracleContractAddress), client) + oracleContractAddress, err := getL1OracleContractAddressByChainID(opts.ChainID) + + // Verify if oracle contract address is available in the chain constants + // If not available, use l2OutputContractAddress from the config options + if err != nil { + if len(opts.L2OutputOracleContractAddress) > 0 { + oracleContractAddress = opts.L2OutputOracleContractAddress + } else { + return nil, fmt.Errorf("L2 output oracle contract address is not available") + } + } + + oracleContractInstance, err := bindings.NewL2OutputOracle(common.HexToAddress(oracleContractAddress), client) if err != nil { return nil, err } return &OracleAccessor{ - contractInstance: contractInstance, - log: logger, + contractInstance: oracleContractInstance, }, nil } diff --git a/pkg/chain/contracts_test.go b/pkg/chain/contracts_test.go index d843af4..523988a 100644 --- a/pkg/chain/contracts_test.go +++ b/pkg/chain/contracts_test.go @@ -8,15 +8,17 @@ import ( func TestGetL1OracleContractAddressByChainID_AvailableChainID(t *testing.T) { const availableChainID uint64 = 10 - var contractAddress = getL1OracleContractAddressByChainID(availableChainID) + var contractAddress, err = getL1OracleContractAddressByChainID(availableChainID) var oracleContractAddressExpected = "0xdfe97868233d1aa22e815a266982f2cf17685a27" + assert.NoError(t, err) assert.Equal(t, oracleContractAddressExpected, contractAddress) } func TestGetL1OracleContractAddressByChainID_UnavailableChainID(t *testing.T) { const unavailableChainID uint64 = 5 - contractAddress := getL1OracleContractAddressByChainID(unavailableChainID) + contractAddress, err := getL1OracleContractAddressByChainID(unavailableChainID) + assert.Error(t, err) assert.Equal(t, 0, len(contractAddress)) } From 1e645caa2eff1e9b0b325da66e1dbb4cba62b96e Mon Sep 17 00:00:00 2001 From: nagdahimanshu Date: Mon, 22 Jan 2024 09:43:34 +0100 Subject: [PATCH 11/13] :ok_hand: Applied suggestions --- pkg/chain/chain_constants_test.go | 19 ++++++++----------- pkg/chain/contracts.go | 7 +++---- pkg/chain/contracts_test.go | 22 ++++++++++------------ 3 files changed, 21 insertions(+), 27 deletions(-) diff --git a/pkg/chain/chain_constants_test.go b/pkg/chain/chain_constants_test.go index 1c77169..4d7f920 100644 --- a/pkg/chain/chain_constants_test.go +++ b/pkg/chain/chain_constants_test.go @@ -6,25 +6,22 @@ import ( "github.com/stretchr/testify/assert" ) -func TestGetContractAddressesByChainID_AvailableChainID(t *testing.T) { +func TestGetContractAddressesByChainID(t *testing.T) { + assert := assert.New(t) + const availableChainID uint64 = 10 contractAddresses, err := GetContractAddressesByChainID(availableChainID) - contractAddressesExpected := Contracts{ stateCommitmentChain: "0xBe5dAb4A2e9cd0F27300dB4aB94BeE3A233AEB19", optimismPortal: "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed", l2OutputOracle: "0xdfe97868233d1aa22e815a266982f2cf17685a27", networkType: "L1", } + assert.NoError(err) + assert.Equal(contractAddressesExpected, contractAddresses) - assert.NoError(t, err) - assert.Equal(t, contractAddressesExpected, contractAddresses) -} - -func TestGetContractAddressesByChainID_UnavailableChainID(t *testing.T) { const unavailableChainID uint64 = 5 - contractAddresses, err := GetContractAddressesByChainID(unavailableChainID) - - assert.Error(t, err) - assert.Equal(t, 0, len(contractAddresses.l2OutputOracle)) + contractAddresses, err = GetContractAddressesByChainID(unavailableChainID) + assert.Error(err) + assert.Equal(0, len(contractAddresses.l2OutputOracle)) } diff --git a/pkg/chain/contracts.go b/pkg/chain/contracts.go index 253d199..9b00557 100644 --- a/pkg/chain/contracts.go +++ b/pkg/chain/contracts.go @@ -17,21 +17,20 @@ type OracleAccessor struct { contractInstance *bindings.L2OutputOracle } +// ConfigOptions are the options required to interact with the oracle contract. type ConfigOptions struct { L1RPCEndpoint string ChainID uint64 L2OutputOracleContractAddress string } -// getL1OracleContractAddressByChainID returns L1 oracle contract address by chainID. func getL1OracleContractAddressByChainID(chainID uint64) (string, error) { - ContractAddresses, err := GetContractAddressesByChainID(chainID) + cAddr, err := GetContractAddressesByChainID(chainID) if err != nil { return "", err } - address := ContractAddresses.l2OutputOracle - return address, nil + return cAddr.l2OutputOracle, nil } // NewOracleContract returns [OracleAccessor] with contract instance. diff --git a/pkg/chain/contracts_test.go b/pkg/chain/contracts_test.go index 523988a..09ff3c2 100644 --- a/pkg/chain/contracts_test.go +++ b/pkg/chain/contracts_test.go @@ -6,19 +6,17 @@ import ( "github.com/stretchr/testify/assert" ) -func TestGetL1OracleContractAddressByChainID_AvailableChainID(t *testing.T) { - const availableChainID uint64 = 10 - var contractAddress, err = getL1OracleContractAddressByChainID(availableChainID) - var oracleContractAddressExpected = "0xdfe97868233d1aa22e815a266982f2cf17685a27" +func TestGetL1OracleContractAddressByChainID(t *testing.T) { + assert := assert.New(t) - assert.NoError(t, err) - assert.Equal(t, oracleContractAddressExpected, contractAddress) -} + const availableChainID uint64 = 10 + oracleContractAddressExpected := "0xdfe97868233d1aa22e815a266982f2cf17685a27" + contractAddress, err := getL1OracleContractAddressByChainID(availableChainID) + assert.NoError(err) + assert.Equal(oracleContractAddressExpected, contractAddress) -func TestGetL1OracleContractAddressByChainID_UnavailableChainID(t *testing.T) { const unavailableChainID uint64 = 5 - contractAddress, err := getL1OracleContractAddressByChainID(unavailableChainID) - - assert.Error(t, err) - assert.Equal(t, 0, len(contractAddress)) + contractAddress, err = getL1OracleContractAddressByChainID(unavailableChainID) + assert.Error(err) + assert.Equal(0, len(contractAddress)) } From 26f0f607fc34ee41e1d4ee55384f9f6a58894f97 Mon Sep 17 00:00:00 2001 From: nagdahimanshu Date: Mon, 22 Jan 2024 11:12:37 +0100 Subject: [PATCH 12/13] :ok_hand: Applied suggestions from code review --- pkg/chain/chain_constants.go | 16 +++++++++------- pkg/chain/chain_constants_test.go | 8 ++++---- pkg/chain/contracts.go | 18 +++++++++--------- pkg/chain/contracts_test.go | 8 ++++---- 4 files changed, 26 insertions(+), 24 deletions(-) diff --git a/pkg/chain/chain_constants.go b/pkg/chain/chain_constants.go index aa8f40c..8b465bb 100644 --- a/pkg/chain/chain_constants.go +++ b/pkg/chain/chain_constants.go @@ -1,7 +1,5 @@ package chain -import "fmt" - // L2ChainIDs manages L2 network chainIDs. type L2ChainIDs struct { optimism uint64 @@ -48,9 +46,10 @@ type Contracts struct { networkType NetworkType } -// GetContractAddressesByChainID returns contract addresses by chainID. -func GetContractAddressesByChainID(chainID uint64) (Contracts, error) { - contractAddresses := map[uint64]Contracts{ +var contractAddresses map[uint64]Contracts + +func init() { + contractAddresses = map[uint64]Contracts{ l2NetworkChainIDs.optimism: { stateCommitmentChain: "0xBe5dAb4A2e9cd0F27300dB4aB94BeE3A233AEB19", optimismPortal: "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed", @@ -123,12 +122,15 @@ func GetContractAddressesByChainID(chainID uint64) (Contracts, error) { networkType: L1, }, } +} +// GetContractAddressesByChainID returns contract addresses by network chainID. +func GetContractAddressesByChainID(chainID uint64) (Contracts, bool) { filteredContracts := contractAddresses[chainID] if len(filteredContracts.l2OutputOracle) == 0 { - return filteredContracts, fmt.Errorf("contract information is unavailable for the chain %v", chainID) + return filteredContracts, false } - return filteredContracts, nil + return filteredContracts, true } diff --git a/pkg/chain/chain_constants_test.go b/pkg/chain/chain_constants_test.go index 4d7f920..e7ffea9 100644 --- a/pkg/chain/chain_constants_test.go +++ b/pkg/chain/chain_constants_test.go @@ -10,18 +10,18 @@ func TestGetContractAddressesByChainID(t *testing.T) { assert := assert.New(t) const availableChainID uint64 = 10 - contractAddresses, err := GetContractAddressesByChainID(availableChainID) + contractAddresses, areAddressesAvailable := GetContractAddressesByChainID(availableChainID) contractAddressesExpected := Contracts{ stateCommitmentChain: "0xBe5dAb4A2e9cd0F27300dB4aB94BeE3A233AEB19", optimismPortal: "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed", l2OutputOracle: "0xdfe97868233d1aa22e815a266982f2cf17685a27", networkType: "L1", } - assert.NoError(err) + assert.Equal(true, areAddressesAvailable) assert.Equal(contractAddressesExpected, contractAddresses) const unavailableChainID uint64 = 5 - contractAddresses, err = GetContractAddressesByChainID(unavailableChainID) - assert.Error(err) + contractAddresses, areAddressesAvailable = GetContractAddressesByChainID(unavailableChainID) + assert.Equal(false, areAddressesAvailable) assert.Equal(0, len(contractAddresses.l2OutputOracle)) } diff --git a/pkg/chain/contracts.go b/pkg/chain/contracts.go index 9b00557..0f55efd 100644 --- a/pkg/chain/contracts.go +++ b/pkg/chain/contracts.go @@ -24,31 +24,31 @@ type ConfigOptions struct { L2OutputOracleContractAddress string } -func getL1OracleContractAddressByChainID(chainID uint64) (string, error) { - cAddr, err := GetContractAddressesByChainID(chainID) - if err != nil { - return "", err +func getL1OracleContractAddressByChainID(chainID uint64) (string, bool) { + cAddr, areAddressesAvailable := GetContractAddressesByChainID(chainID) + if !areAddressesAvailable { + return "", false } - return cAddr.l2OutputOracle, nil + return cAddr.l2OutputOracle, true } // NewOracleContract returns [OracleAccessor] with contract instance. -func NewOracleContract(ctx context.Context, opts ConfigOptions) (*OracleAccessor, error) { +func NewOracleContract(ctx context.Context, opts *ConfigOptions) (*OracleAccessor, error) { client, err := ethclient.DialContext(ctx, opts.L1RPCEndpoint) if err != nil { return nil, err } - oracleContractAddress, err := getL1OracleContractAddressByChainID(opts.ChainID) + oracleContractAddress, isAddressExists := getL1OracleContractAddressByChainID(opts.ChainID) // Verify if oracle contract address is available in the chain constants // If not available, use l2OutputContractAddress from the config options - if err != nil { + if !isAddressExists { if len(opts.L2OutputOracleContractAddress) > 0 { oracleContractAddress = opts.L2OutputOracleContractAddress } else { - return nil, fmt.Errorf("L2 output oracle contract address is not available") + return nil, fmt.Errorf("L2OutputOracleContractAddress is not available") } } diff --git a/pkg/chain/contracts_test.go b/pkg/chain/contracts_test.go index 09ff3c2..6d6458d 100644 --- a/pkg/chain/contracts_test.go +++ b/pkg/chain/contracts_test.go @@ -11,12 +11,12 @@ func TestGetL1OracleContractAddressByChainID(t *testing.T) { const availableChainID uint64 = 10 oracleContractAddressExpected := "0xdfe97868233d1aa22e815a266982f2cf17685a27" - contractAddress, err := getL1OracleContractAddressByChainID(availableChainID) - assert.NoError(err) + contractAddress, isAddressExists := getL1OracleContractAddressByChainID(availableChainID) + assert.Equal(true, isAddressExists) assert.Equal(oracleContractAddressExpected, contractAddress) const unavailableChainID uint64 = 5 - contractAddress, err = getL1OracleContractAddressByChainID(unavailableChainID) - assert.Error(err) + contractAddress, isAddressExists = getL1OracleContractAddressByChainID(unavailableChainID) + assert.Equal(false, isAddressExists) assert.Equal(0, len(contractAddress)) } From 8d8da8ac44032a24af2d5e9d2246bebadc814e63 Mon Sep 17 00:00:00 2001 From: nagdahimanshu Date: Tue, 23 Jan 2024 00:05:33 +0100 Subject: [PATCH 13/13] :ok_hand: Applied suggestions --- pkg/chain/contracts.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pkg/chain/contracts.go b/pkg/chain/contracts.go index 0f55efd..778b280 100644 --- a/pkg/chain/contracts.go +++ b/pkg/chain/contracts.go @@ -33,8 +33,8 @@ func getL1OracleContractAddressByChainID(chainID uint64) (string, bool) { return cAddr.l2OutputOracle, true } -// NewOracleContract returns [OracleAccessor] with contract instance. -func NewOracleContract(ctx context.Context, opts *ConfigOptions) (*OracleAccessor, error) { +// NewOracleAccessor returns [OracleAccessor] with contract instance. +func NewOracleAccessor(ctx context.Context, opts *ConfigOptions) (*OracleAccessor, error) { client, err := ethclient.DialContext(ctx, opts.L1RPCEndpoint) if err != nil { return nil, err @@ -45,11 +45,10 @@ func NewOracleContract(ctx context.Context, opts *ConfigOptions) (*OracleAccesso // Verify if oracle contract address is available in the chain constants // If not available, use l2OutputContractAddress from the config options if !isAddressExists { - if len(opts.L2OutputOracleContractAddress) > 0 { - oracleContractAddress = opts.L2OutputOracleContractAddress - } else { + if len(opts.L2OutputOracleContractAddress) == 0 { return nil, fmt.Errorf("L2OutputOracleContractAddress is not available") } + oracleContractAddress = opts.L2OutputOracleContractAddress } oracleContractInstance, err := bindings.NewL2OutputOracle(common.HexToAddress(oracleContractAddress), client)