From d5e9beddff283c1db6d62c670aede0fd16c5db1f Mon Sep 17 00:00:00 2001 From: Tangui Clairet <181825613+Tangui-Bitfly@users.noreply.github.com> Date: Fri, 15 Nov 2024 13:37:42 +0100 Subject: [PATCH] feat(test): add simulated backend for ethereum testing --- backend/go.mod | 58 +- backend/go.sum | 123 +-- backend/internal/contracts/Context.sol | 28 + backend/internal/contracts/ERC20.sol | 312 +++++++ backend/internal/contracts/IERC20.sol | 79 ++ backend/internal/contracts/IERC20Metadata.sol | 26 + backend/internal/contracts/IMulticall3.sol | 75 ++ backend/internal/contracts/Makefile | 30 + backend/internal/contracts/Multicall3.sol | 216 +++++ backend/internal/contracts/README.md | 28 + backend/internal/contracts/Token.sol | 13 + backend/internal/contracts/draft-IERC6093.sol | 161 ++++ backend/internal/contracts/ierc20.go | 645 +++++++++++++++ backend/internal/contracts/imulticall3.go | 732 ++++++++++++++++ backend/internal/contracts/multicall.go | 666 +++++++++++++++ backend/internal/contracts/token.go | 781 ++++++++++++++++++ backend/internal/th/ethereum.go | 224 +++++ .../db2/{store => database}/bigtable.go | 60 +- .../db2/{store => database}/bigtable_test.go | 18 +- .../commons/db2/{store => database}/remote.go | 12 +- .../commons/db2/{store => database}/store.go | 8 +- .../{storetest => databasetest}/bigtable.go | 2 +- backend/pkg/commons/db2/jsonrpc/jsonrpc.go | 20 + backend/pkg/commons/db2/parser.go | 22 +- backend/pkg/commons/db2/parser_test.go | 84 ++ backend/pkg/commons/db2/{ => raw}/cache.go | 36 +- backend/pkg/commons/db2/{ => raw}/client.go | 84 +- .../pkg/commons/db2/{ => raw}/client_test.go | 32 +- backend/pkg/commons/db2/{ => raw}/compress.go | 2 +- backend/pkg/commons/db2/{ => raw}/raw.go | 68 +- backend/pkg/commons/db2/{ => raw}/raw_test.go | 73 +- backend/pkg/commons/db2/{ => raw}/tables.go | 6 +- backend/pkg/commons/db2/rawtest/raw.go | 75 ++ 33 files changed, 4490 insertions(+), 309 deletions(-) create mode 100644 backend/internal/contracts/Context.sol create mode 100644 backend/internal/contracts/ERC20.sol create mode 100644 backend/internal/contracts/IERC20.sol create mode 100644 backend/internal/contracts/IERC20Metadata.sol create mode 100644 backend/internal/contracts/IMulticall3.sol create mode 100644 backend/internal/contracts/Makefile create mode 100644 backend/internal/contracts/Multicall3.sol create mode 100644 backend/internal/contracts/README.md create mode 100644 backend/internal/contracts/Token.sol create mode 100644 backend/internal/contracts/draft-IERC6093.sol create mode 100644 backend/internal/contracts/ierc20.go create mode 100644 backend/internal/contracts/imulticall3.go create mode 100644 backend/internal/contracts/multicall.go create mode 100644 backend/internal/contracts/token.go create mode 100644 backend/internal/th/ethereum.go rename backend/pkg/commons/db2/{store => database}/bigtable.go (82%) rename backend/pkg/commons/db2/{store => database}/bigtable_test.go (89%) rename backend/pkg/commons/db2/{store => database}/remote.go (94%) rename backend/pkg/commons/db2/{store => database}/store.go (76%) rename backend/pkg/commons/db2/{storetest => databasetest}/bigtable.go (97%) create mode 100644 backend/pkg/commons/db2/jsonrpc/jsonrpc.go create mode 100644 backend/pkg/commons/db2/parser_test.go rename backend/pkg/commons/db2/{ => raw}/cache.go (65%) rename backend/pkg/commons/db2/{ => raw}/client.go (63%) rename backend/pkg/commons/db2/{ => raw}/client_test.go (90%) rename backend/pkg/commons/db2/{ => raw}/compress.go (98%) rename backend/pkg/commons/db2/{ => raw}/raw.go (60%) rename backend/pkg/commons/db2/{ => raw}/raw_test.go (90%) rename backend/pkg/commons/db2/{ => raw}/tables.go (83%) create mode 100644 backend/pkg/commons/db2/rawtest/raw.go diff --git a/backend/go.mod b/backend/go.mod index ba1737f6d..8435193a2 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -1,6 +1,6 @@ module github.com/gobitfly/beaconchain -go 1.23 +go 1.23.1 require ( cloud.google.com/go/bigtable v1.21.0 @@ -8,6 +8,7 @@ require ( firebase.google.com/go/v4 v4.14.1 github.com/ClickHouse/clickhouse-go/v2 v2.17.1 github.com/Gurpartap/storekit-go v0.0.0-20201205024111-36b6cd5c6a21 + github.com/Tangui-Bitfly/ethsimtracer v0.0.0-20241031103622-e76546c3d9c1 github.com/alexedwards/scs/redisstore v0.0.0-20240316134038-7e11d57e8885 github.com/alexedwards/scs/v2 v2.8.0 github.com/attestantio/go-eth2-client v0.19.10 @@ -21,7 +22,7 @@ require ( github.com/davecgh/go-spew v1.1.1 github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0 github.com/doug-martin/goqu/v9 v9.19.0 - github.com/ethereum/go-ethereum v1.13.12 + github.com/ethereum/go-ethereum v1.14.11 github.com/fergusstrange/embedded-postgres v1.29.0 github.com/gavv/httpexpect/v2 v2.16.0 github.com/go-faker/faker/v4 v4.3.0 @@ -60,7 +61,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/pressly/goose/v3 v3.18.0 github.com/prometheus/client_golang v1.18.0 - github.com/protolambda/zrnt v0.30.0 + github.com/protolambda/zrnt v0.32.2 github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7 github.com/prysmaticlabs/go-ssz v0.0.0-20210121151755-f6208871c388 github.com/rocket-pool/rocketpool-go v1.8.3-0.20240618173422-783b8668f5b4 @@ -95,9 +96,11 @@ require ( cloud.google.com/go/longrunning v0.5.5 // indirect cloud.google.com/go/storage v1.40.0 // indirect github.com/ClickHouse/ch-go v0.58.2 // indirect + github.com/DataDog/zstd v1.4.5 // indirect github.com/MicahParks/keyfunc v1.9.0 // indirect - github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect github.com/TylerBrock/colorjson v0.0.0-20200706003622-8a50f05110d2 // indirect + github.com/VictoriaMetrics/fastcache v1.12.2 // indirect github.com/ajg/form v1.5.1 // indirect github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/alessio/shellescape v1.4.1 // indirect @@ -118,31 +121,42 @@ require ( github.com/aws/smithy-go v1.20.0 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bits-and-blooms/bitset v1.11.0 // indirect + github.com/bits-and-blooms/bitset v1.13.0 // indirect github.com/blang/semver/v4 v4.0.0 // indirect - github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect github.com/buger/jsonparser v1.1.1 // indirect github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20 // indirect + github.com/cockroachdb/errors v1.11.3 // indirect + github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect + github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect + github.com/cockroachdb/pebble v1.1.2 // indirect + github.com/cockroachdb/redact v1.1.5 // indirect + github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 // indirect - github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect - github.com/deckarep/golang-set/v2 v2.5.0 // indirect + github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c // indirect + github.com/crate-crypto/go-kzg-4844 v1.0.0 // indirect + github.com/deckarep/golang-set/v2 v2.6.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/dgraph-io/ristretto v0.1.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/envoyproxy/go-control-plane v0.13.0 // indirect github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect - github.com/ethereum/c-kzg-4844 v0.4.0 // indirect + github.com/ethereum/c-kzg-4844 v1.0.0 // indirect + github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 // indirect github.com/fatih/color v1.16.0 // indirect github.com/fatih/structs v1.1.0 // indirect github.com/fatih/structtag v1.2.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/ferranbt/fastssz v0.1.3 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect + github.com/getsentry/sentry-go v0.27.0 // indirect github.com/glendc/go-external-ip v0.1.0 // indirect github.com/go-chi/chi/v5 v5.0.8 // indirect github.com/go-faster/city v1.0.1 // indirect @@ -156,6 +170,7 @@ require ( github.com/gobwas/glob v0.2.3 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/goccy/go-yaml v1.9.5 // indirect + github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/glog v1.2.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect @@ -167,9 +182,13 @@ require ( github.com/googleapis/gax-go/v2 v2.12.3 // indirect github.com/gorilla/securecookie v1.1.2 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 // indirect + github.com/hashicorp/go-bexpr v0.1.10 // indirect github.com/herumi/bls-eth-go-binary v1.31.0 // indirect - github.com/holiman/uint256 v1.2.4 // indirect + github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 // indirect + github.com/holiman/bloomfilter/v2 v2.0.3 // indirect + github.com/holiman/uint256 v1.3.1 // indirect github.com/huandu/go-clone v1.6.0 // indirect + github.com/huin/goupnp v1.3.0 // indirect github.com/imkira/go-interpol v1.1.0 // indirect github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/boxo v0.8.0 // indirect @@ -192,20 +211,25 @@ require ( github.com/jackc/pgproto3/v2 v2.1.1 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/jackc/puddle/v2 v2.2.1 // indirect + github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/goprocess v0.1.4 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/k3a/html2text v1.2.1 // indirect github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/kr/text v0.2.0 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect github.com/mfridman/interpolate v0.0.2 // indirect github.com/minio/highwayhash v1.0.2 // indirect github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect + github.com/mitchellh/pointerstructure v1.2.0 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect @@ -216,6 +240,7 @@ require ( github.com/multiformats/go-multibase v0.2.0 // indirect github.com/multiformats/go-multihash v0.2.3 // indirect github.com/multiformats/go-varint v0.0.7 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/paulmach/orb v0.10.0 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect @@ -231,19 +256,26 @@ require ( github.com/prysmaticlabs/gohashtree v0.0.4-beta // indirect github.com/prysmaticlabs/prysm/v3 v3.2.2 // indirect github.com/r3labs/sse/v2 v2.10.0 // indirect + github.com/rivo/uniseg v0.4.4 // indirect + github.com/rogpeppe/go-internal v1.11.0 // indirect + github.com/rs/cors v1.8.2 // indirect github.com/rs/zerolog v1.29.1 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sanity-io/litter v1.5.5 // indirect github.com/segmentio/asm v1.2.0 // indirect github.com/sergi/go-diff v1.2.0 // indirect github.com/sethvargo/go-retry v0.2.4 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect - github.com/supranational/blst v0.3.11 // indirect + github.com/status-im/keycard-go v0.2.0 // indirect + github.com/supranational/blst v0.3.13 // indirect github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e // indirect github.com/tklauser/go-sysconf v0.3.13 // indirect github.com/tklauser/numcpus v0.7.0 // indirect + github.com/tyler-smith/go-bip39 v1.1.0 // indirect + github.com/urfave/cli/v2 v2.25.7 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasthttp v1.34.0 // indirect + github.com/valyala/fasthttp v1.40.0 // indirect github.com/wealdtech/go-bytesutil v1.2.0 // indirect github.com/wealdtech/go-merkletree v1.0.1-0.20190605192610-2bb163c2ea2a // indirect github.com/wealdtech/go-multicodec v1.4.0 // indirect @@ -253,6 +285,7 @@ require ( github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect + github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 // indirect github.com/yudai/gojsondiff v1.0.0 // indirect github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect @@ -275,6 +308,7 @@ require ( google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect + gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.2.1 // indirect moul.io/http2curl/v2 v2.3.0 // indirect diff --git a/backend/go.sum b/backend/go.sum index 17cd8be82..accf0b293 100644 --- a/backend/go.sum +++ b/backend/go.sum @@ -24,8 +24,8 @@ firebase.google.com/go/v4 v4.14.1/go.mod h1:fgk2XshgNDEKaioKco+AouiegSI9oTWVqRaB github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I= -github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/ClickHouse/ch-go v0.58.2 h1:jSm2szHbT9MCAB1rJ3WuCJqmGLi5UTjlNu+f530UTS0= github.com/ClickHouse/ch-go v0.58.2/go.mod h1:Ap/0bEmiLa14gYjCiRkYGbXvbe8vwdrfTYWhsuQ99aw= github.com/ClickHouse/clickhouse-go/v2 v2.17.1 h1:ZCmAYWpu75IyEi7+Yrs/uaAjiCGY5wfW5kXo64exkX4= @@ -39,14 +39,16 @@ github.com/Gurpartap/storekit-go v0.0.0-20201205024111-36b6cd5c6a21/go.mod h1:7P github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/MicahParks/keyfunc v1.9.0 h1:lhKd5xrFHLNOWrDc4Tyb/Q1AJ4LCzQ48GVJyVIID3+o= github.com/MicahParks/keyfunc v1.9.0/go.mod h1:IdnCilugA0O/99dW+/MkvlyrsX8+L8+x95xuVNtM5jw= -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/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= +github.com/Tangui-Bitfly/ethsimtracer v0.0.0-20241031103622-e76546c3d9c1 h1:KUh8TO3q7sULPQOHX4HtRPSRwYqgPHkOkg/rItvsSkk= +github.com/Tangui-Bitfly/ethsimtracer v0.0.0-20241031103622-e76546c3d9c1/go.mod h1:2pEz2HpJ+iF8e+qIy9EU41mAUPIECMt9DBd6aD0b0Uk= github.com/TylerBrock/colorjson v0.0.0-20200706003622-8a50f05110d2 h1:ZBbLwSJqkHBuFDA6DUhhse0IGJ7T5bemHyNILUjvOq4= github.com/TylerBrock/colorjson v0.0.0-20200706003622-8a50f05110d2/go.mod h1:VSw57q4QFiWDbRnjdX8Cb3Ow0SFncRw+bA/ofY6Q83w= -github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= -github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= +github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= +github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= @@ -57,6 +59,8 @@ github.com/alexedwards/scs/redisstore v0.0.0-20240316134038-7e11d57e8885 h1:UdHe github.com/alexedwards/scs/redisstore v0.0.0-20240316134038-7e11d57e8885/go.mod h1:ceKFatoD+hfHWWeHOAYue1J+XgOJjE7dw8l3JtIRTGY= github.com/alexedwards/scs/v2 v2.8.0 h1:h31yUYoycPuL0zt14c0gd+oqxfRwIj6SOjHdKRZxhEw= github.com/alexedwards/scs/v2 v2.8.0/go.mod h1:ToaROZxyKukJKT/xLcVQAChi5k6+Pn1Gvmdl7h3RRj8= +github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= +github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI= github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= @@ -116,16 +120,16 @@ github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= 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.11.0 h1:RMyy2mBBShArUAhfVRZJ2xyBO58KCBCtZFShw3umo6k= -github.com/bits-and-blooms/bitset v1.11.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE= +github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/btcsuite/btcd v0.23.4 h1:IzV6qqkfwbItOS/sg/aDfPDsjPP8twrCOE2R93hxMlQ= -github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= -github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= +github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= 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/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= @@ -142,6 +146,7 @@ github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU= github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -152,16 +157,18 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20 h1:N+3sFI5GUjRKBi+i0TxYVST9h4Ie192jJWpHvthBBgg= github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= -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/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= +github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= +github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/pebble v1.1.2 h1:CUh2IPtR4swHlEj48Rhfzw6l/d0qA31fItcIszQVIsA= +github.com/cockroachdb/pebble v1.1.2/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= 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= @@ -180,11 +187,12 @@ github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0q github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 h1:HVTnpeuvF6Owjd5mniCL8DEXo7uYXdQEmOP4FJbV5tg= github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE= -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/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c h1:uQYC5Z1mdLRPrZhHjHxufI8+2UG/i25QG92j0Er9p6I= +github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= +github.com/crate-crypto/go-kzg-4844 v1.0.0 h1:TsSgHwrkTKecKJ4kadtHi4b3xHW5dCFUDFnUp1TsawI= +github.com/crate-crypto/go-kzg-4844 v1.0.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0= github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= github.com/d4l3k/messagediff v1.2.1 h1:ZcAIMYsUg0EAp9X+tt8/enBE/Q8Yd5kzPynLyKptt9U= @@ -193,8 +201,8 @@ github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2 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.5.0 h1:hn6cEZtQ0h3J8kFrHR/NrzyOoTnjgW1+FmNJzQ7y/sA= -github.com/deckarep/golang-set/v2 v2.5.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= +github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= @@ -233,10 +241,12 @@ github.com/envoyproxy/go-control-plane v0.13.0/go.mod h1:GRaKG3dwvFoTg4nj7aXdZnv github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM= github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4= -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.12 h1:iDr9UM2JWkngBHGovRJEQn4Kor7mT4gt9rUZqB5M29Y= -github.com/ethereum/go-ethereum v1.13.12/go.mod h1:hKL2Qcj1OvStXNSEDbucexqnEt1Wh4Cz329XsjAalZY= +github.com/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHEwTNA= +github.com/ethereum/c-kzg-4844 v1.0.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= +github.com/ethereum/go-ethereum v1.14.11 h1:8nFDCUUE67rPc6AKxFj7JKaOa2W/W1Rse3oS6LvvxEY= +github.com/ethereum/go-ethereum v1.14.11/go.mod h1:+l/fr42Mma+xBnhefL/+z11/hcmJ2egl+ScIVPjhc7E= +github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 h1:8NfxH2iXvJ60YRB8ChToFTUzl8awsc3cJ8CbLjGIl/A= +github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 h1:0JZ+dUmQeA8IIVUMzysrX4/AKuQwWhV2dYQuPZdvdSQ= github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= @@ -256,8 +266,6 @@ github.com/fergusstrange/embedded-postgres v1.29.0 h1:Uv8hdhoiaNMuH0w8UuGXDHr60V github.com/fergusstrange/embedded-postgres v1.29.0/go.mod h1:t/MLs0h9ukYM6FSt99R7InCHs1nW0ordoVCcnzmpTYw= github.com/ferranbt/fastssz v0.1.3 h1:ZI+z3JH05h4kgmFXdHuR1aWYsgrg7o+Fw7/NCzM16Mo= github.com/ferranbt/fastssz v0.1.3/go.mod h1:0Y9TEd/9XuFlh7mskMPfXiI2Dkw4Ddg9EyXt1W7MRvE= -github.com/fjl/memsize v0.0.2 h1:27txuSD9or+NZlnOWdKUxeBzTAUkWCVh+4Gf2dWFOzA= -github.com/fjl/memsize v0.0.2/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= @@ -270,12 +278,14 @@ github.com/gavv/httpexpect/v2 v2.16.0 h1:Ty2favARiTYTOkCRZGX7ojXXjGyNAIohM1lZ3vq github.com/gavv/httpexpect/v2 v2.16.0/go.mod h1:uJLaO+hQ25ukBJtQi750PsztObHybNllN+t+MbbW8PY= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/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/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= +github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/glendc/go-external-ip v0.1.0 h1:iX3xQ2Q26atAmLTbd++nUce2P5ht5P4uD4V7caSY/xg= github.com/glendc/go-external-ip v0.1.0/go.mod h1:CNx312s2FLAJoWNdJWZ2Fpf5O4oLsMFwuYviHjS4uJE= github.com/go-chi/chi/v5 v5.0.8 h1:lD+NLqFcAi1ovnVZpsnObHGW4xb4J8lNmoYVfECH1Y0= github.com/go-chi/chi/v5 v5.0.8/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= +github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-faker/faker/v4 v4.3.0 h1:UXOW7kn/Mwd0u6MR30JjUKVzguT20EB/hBOddAAO+DY= github.com/go-faker/faker/v4 v4.3.0/go.mod h1:F/bBy8GH9NxOxMInug5Gx4WYeG6fHJZ8Ol/dhcpRub4= github.com/go-faster/city v1.0.1 h1:4WAxSZ3V2Ws4QRDrscLEDcibJY8uf41H6AhXDrNDcGw= @@ -308,8 +318,8 @@ github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+ github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= -github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0= -github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= +github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= +github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= @@ -365,7 +375,6 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 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= @@ -442,13 +451,12 @@ github.com/herumi/bls-eth-go-binary v1.31.0 h1:9eeW3EA4epCb7FIHt2luENpAW69MvKGL5 github.com/herumi/bls-eth-go-binary v1.31.0/go.mod h1:luAnRm3OsMQeokhGzpYmc0ZKwawY7o87PUEP11Z7r7U= github.com/hokaccha/go-prettyjson v0.0.0-20211117102719-0474bc63780f h1:7LYC+Yfkj3CTRcShK0KOL/w6iTiKyqqBA9a41Wnggw8= github.com/hokaccha/go-prettyjson v0.0.0-20211117102719-0474bc63780f/go.mod h1:pFlLw2CfqZiIBOx6BuCeRLCrfxBJipTY0nIOF/VbGcI= -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/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6wn4Ej8vjuVGxeHdan+bRb2ebyv4= +github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/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.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= -github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= -github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +github.com/holiman/uint256 v1.3.1 h1:JfTzmih28bittyHM8z360dCjIA9dbPIBlcTI6lmctQs= +github.com/holiman/uint256 v1.3.1/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c= github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U= @@ -600,7 +608,6 @@ github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNU github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= -github.com/kilic/bls12-381 v0.1.0/go.mod h1:vDTTHJONJ6G+P2R74EhnyotQDTliQDnFEwhdmfzw1ig= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= @@ -678,6 +685,7 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= @@ -691,7 +699,6 @@ github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8Rv github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= -github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= @@ -700,6 +707,7 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= @@ -790,7 +798,10 @@ github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhM github.com/phpdave11/gofpdi v1.0.7/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ= github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= +github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pkg/diff v0.0.0-20200914180035-5b29258ca4f7/go.mod h1:zO8QMzTeZd5cpnIkz/Gn6iK0jDfGicM1nynOkkPIl28= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -814,13 +825,10 @@ github.com/prometheus/common v0.47.0 h1:p5Cz0FNHo7SnWOmWmoRozVcjEp0bIVU8cV7OShpj github.com/prometheus/common v0.47.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= -github.com/protolambda/bls12-381-util v0.0.0-20210720105258-a772f2aac13e/go.mod h1:MPZvj2Pr0N8/dXyTPS5REeg2sdLG7t8DRzC1rLv925w= -github.com/protolambda/messagediff v1.4.0/go.mod h1:LboJp0EwIbJsePYpzh5Op/9G1/4mIztMRYzzwR0dR2M= -github.com/protolambda/zrnt v0.30.0 h1:pHEn69ZgaDFGpLGGYG1oD7DvYI7RDirbMBPfbC+8p4g= -github.com/protolambda/zrnt v0.30.0/go.mod h1:qcdX9CXFeVNCQK/q0nswpzhd+31RHMk2Ax/2lMsJ4Jw= +github.com/protolambda/zrnt v0.32.2 h1:KZ48T+3UhsPXNdtE/5QEvGc9DGjUaRI17nJaoznoIaM= +github.com/protolambda/zrnt v0.32.2/go.mod h1:A0fezkp9Tt3GBLATSPIbuY4ywYESyAuc/FFmPKg8Lqs= github.com/protolambda/zssz v0.1.5 h1:7fjJjissZIIaa2QcvmhS/pZISMX21zVITt49sW1ouek= github.com/protolambda/zssz v0.1.5/go.mod h1:a4iwOX5FE7/JkKA+J/PH0Mjo9oXftN6P8NZyL28gpag= -github.com/protolambda/ztyp v0.2.2/go.mod h1:9bYgKGqg3wJqT9ac1gI2hnVb0STQq7p/1lapqrqY1dU= github.com/prysmaticlabs/fastssz v0.0.0-20221107182844-78142813af44 h1:c3p3UzV4vFA7xaCDphnDWOjpxcadrQ26l5b+ypsvyxo= github.com/prysmaticlabs/fastssz v0.0.0-20221107182844-78142813af44/go.mod h1:MA5zShstUwCQaE9faGHgCGvEWUbG87p4SAXINhmCkvg= github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7 h1:0tVE4tdWQK9ZpYygoV7+vS6QkDvQVySboMVEIxBJmXw= @@ -835,6 +843,7 @@ github.com/r3labs/sse/v2 v2.10.0 h1:hFEkLLFY4LDifoHdiCN/LlGBAdVJYsANaLqNYa1l/v0= github.com/r3labs/sse/v2 v2.10.0/go.mod h1:Igau6Whc+F17QUgML1fYe1VPZzTV6EMCnYktEmkNJ7I= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rocket-pool/go-merkletree v1.0.1-0.20220406020931-c262d9b976dd h1:p9KuetSKB9nte9I/MkkiM3pwKFVQgqxxPTQ0y56Ff6s= @@ -844,6 +853,7 @@ github.com/rocket-pool/rocketpool-go v1.8.3-0.20240618173422-783b8668f5b4/go.mod github.com/rocket-pool/smartnode v1.13.6 h1:dZCDEb5+ZFN7iU5/Qzxv16efS1zk/fLf6HiewNzjBfY= github.com/rocket-pool/smartnode v1.13.6/go.mod h1:mW/gljU+C02+JhrXN3dQfftaLnEqw8mIkTtkKOFIyJk= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U= @@ -910,8 +920,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -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/supranational/blst v0.3.13 h1:AYeSxdOMacwu7FBmpfloBz5pbFXDmJL33RuwnKtmTjk= +github.com/supranational/blst v0.3.13/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= github.com/tailscale/depaware v0.0.0-20210622194025-720c4b409502/go.mod h1:p9lPsd+cx33L3H9nNoecRRxPssFKUwwI50I3pZ0yT+8= @@ -931,13 +941,12 @@ github.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMW github.com/umbracle/gohashtree v0.0.2-alpha.0.20230207094856-5b775a815c10 h1:CQh33pStIp/E30b7TxDlXfM0145bn2e8boI30IxAhTg= github.com/umbracle/gohashtree v0.0.2-alpha.0.20230207094856-5b775a815c10/go.mod h1:x/Pa0FF5Te9kdrlZKJK82YmAkvL8+f989USgz6Jiw7M= github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.12 h1:igJgVw1JdKH+trcLWLeLwZjU9fEfPesQ+9/e4MQ44S8= 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/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.34.0 h1:d3AAQJ2DRcxJYHm7OXNXtXt2as1vMDfxeIcFvhmGGm4= -github.com/valyala/fasthttp v1.34.0/go.mod h1:epZA5N+7pY6ZaEKRmstzOuYJx9HI8DI1oaCGZpdH4h0= +github.com/valyala/fasthttp v1.40.0 h1:CRq/00MfruPGFLTQKY8b+8SfdK60TxNztjRMnH0t1Yc= +github.com/valyala/fasthttp v1.40.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I= github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= github.com/vertica/vertica-sql-go v1.3.3 h1:fL+FKEAEy5ONmsvya2WH5T8bhkvY27y/Ik3ReR2T+Qw= github.com/vertica/vertica-sql-go v1.3.3/go.mod h1:jnn2GFuv+O2Jcjktb7zyc4Utlbu9YVqpHH/lx63+1M4= @@ -1126,7 +1135,6 @@ golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1146,6 +1154,7 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -1242,8 +1251,8 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -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/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= +gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/backend/internal/contracts/Context.sol b/backend/internal/contracts/Context.sol new file mode 100644 index 000000000..4c7963cf9 --- /dev/null +++ b/backend/internal/contracts/Context.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) + +pragma solidity ^0.8.20; + +/** + * @dev Provides information about the current execution context, including the + * sender of the transaction and its data. While these are generally available + * via msg.sender and msg.data, they should not be accessed in such a direct + * manner, since when dealing with meta-transactions the account sending and + * paying for execution may not be the actual sender (as far as an application + * is concerned). + * + * This contracts is only required for intermediate, library-like contracts. + */ +abstract contract Context { + function _msgSender() internal view virtual returns (address) { + return msg.sender; + } + + function _msgData() internal view virtual returns (bytes calldata) { + return msg.data; + } + + function _contextSuffixLength() internal view virtual returns (uint256) { + return 0; + } +} \ No newline at end of file diff --git a/backend/internal/contracts/ERC20.sol b/backend/internal/contracts/ERC20.sol new file mode 100644 index 000000000..880da32cc --- /dev/null +++ b/backend/internal/contracts/ERC20.sol @@ -0,0 +1,312 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol) + +pragma solidity ^0.8.20; + +import {IERC20} from "IERC20.sol"; +import {IERC20Metadata} from "IERC20Metadata.sol"; +import {Context} from "Context.sol"; +import {IERC20Errors} from "draft-IERC6093.sol"; + +/** + * @dev Implementation of the {IERC20} interface. + * + * This implementation is agnostic to the way tokens are created. This means + * that a supply mechanism has to be added in a derived contract using {_mint}. + * + * TIP: For a detailed writeup see our guide + * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How + * to implement supply mechanisms]. + * + * The default value of {decimals} is 18. To change this, you should override + * this function so it returns a different value. + * + * We have followed general OpenZeppelin Contracts guidelines: functions revert + * instead returning `false` on failure. This behavior is nonetheless + * conventional and does not conflict with the expectations of ERC-20 + * applications. + */ +abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors { + mapping(address account => uint256) private _balances; + + mapping(address account => mapping(address spender => uint256)) private _allowances; + + uint256 private _totalSupply; + + string private _name; + string private _symbol; + + /** + * @dev Sets the values for {name} and {symbol}. + * + * All two of these values are immutable: they can only be set once during + * construction. + */ + constructor(string memory name_, string memory symbol_) { + _name = name_; + _symbol = symbol_; + } + + /** + * @dev Returns the name of the token. + */ + function name() public view virtual returns (string memory) { + return _name; + } + + /** + * @dev Returns the symbol of the token, usually a shorter version of the + * name. + */ + function symbol() public view virtual returns (string memory) { + return _symbol; + } + + /** + * @dev Returns the number of decimals used to get its user representation. + * For example, if `decimals` equals `2`, a balance of `505` tokens should + * be displayed to a user as `5.05` (`505 / 10 ** 2`). + * + * Tokens usually opt for a value of 18, imitating the relationship between + * Ether and Wei. This is the default value returned by this function, unless + * it's overridden. + * + * NOTE: This information is only used for _display_ purposes: it in + * no way affects any of the arithmetic of the contract, including + * {IERC20-balanceOf} and {IERC20-transfer}. + */ + function decimals() public view virtual returns (uint8) { + return 18; + } + + /** + * @dev See {IERC20-totalSupply}. + */ + function totalSupply() public view virtual returns (uint256) { + return _totalSupply; + } + + /** + * @dev See {IERC20-balanceOf}. + */ + function balanceOf(address account) public view virtual returns (uint256) { + return _balances[account]; + } + + /** + * @dev See {IERC20-transfer}. + * + * Requirements: + * + * - `to` cannot be the zero address. + * - the caller must have a balance of at least `value`. + */ + function transfer(address to, uint256 value) public virtual returns (bool) { + address owner = _msgSender(); + _transfer(owner, to, value); + return true; + } + + /** + * @dev See {IERC20-allowance}. + */ + function allowance(address owner, address spender) public view virtual returns (uint256) { + return _allowances[owner][spender]; + } + + /** + * @dev See {IERC20-approve}. + * + * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on + * `transferFrom`. This is semantically equivalent to an infinite approval. + * + * Requirements: + * + * - `spender` cannot be the zero address. + */ + function approve(address spender, uint256 value) public virtual returns (bool) { + address owner = _msgSender(); + _approve(owner, spender, value); + return true; + } + + /** + * @dev See {IERC20-transferFrom}. + * + * Skips emitting an {Approval} event indicating an allowance update. This is not + * required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve]. + * + * NOTE: Does not update the allowance if the current allowance + * is the maximum `uint256`. + * + * Requirements: + * + * - `from` and `to` cannot be the zero address. + * - `from` must have a balance of at least `value`. + * - the caller must have allowance for ``from``'s tokens of at least + * `value`. + */ + function transferFrom(address from, address to, uint256 value) public virtual returns (bool) { + address spender = _msgSender(); + _spendAllowance(from, spender, value); + _transfer(from, to, value); + return true; + } + + /** + * @dev Moves a `value` amount of tokens from `from` to `to`. + * + * This internal function is equivalent to {transfer}, and can be used to + * e.g. implement automatic token fees, slashing mechanisms, etc. + * + * Emits a {Transfer} event. + * + * NOTE: This function is not virtual, {_update} should be overridden instead. + */ + function _transfer(address from, address to, uint256 value) internal { + if (from == address(0)) { + revert ERC20InvalidSender(address(0)); + } + if (to == address(0)) { + revert ERC20InvalidReceiver(address(0)); + } + _update(from, to, value); + } + + /** + * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from` + * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding + * this function. + * + * Emits a {Transfer} event. + */ + function _update(address from, address to, uint256 value) internal virtual { + if (from == address(0)) { + // Overflow check required: The rest of the code assumes that totalSupply never overflows + _totalSupply += value; + } else { + uint256 fromBalance = _balances[from]; + if (fromBalance < value) { + revert ERC20InsufficientBalance(from, fromBalance, value); + } + unchecked { + // Overflow not possible: value <= fromBalance <= totalSupply. + _balances[from] = fromBalance - value; + } + } + + if (to == address(0)) { + unchecked { + // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply. + _totalSupply -= value; + } + } else { + unchecked { + // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256. + _balances[to] += value; + } + } + + emit Transfer(from, to, value); + } + + /** + * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0). + * Relies on the `_update` mechanism + * + * Emits a {Transfer} event with `from` set to the zero address. + * + * NOTE: This function is not virtual, {_update} should be overridden instead. + */ + function _mint(address account, uint256 value) internal { + if (account == address(0)) { + revert ERC20InvalidReceiver(address(0)); + } + _update(address(0), account, value); + } + + /** + * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply. + * Relies on the `_update` mechanism. + * + * Emits a {Transfer} event with `to` set to the zero address. + * + * NOTE: This function is not virtual, {_update} should be overridden instead + */ + function _burn(address account, uint256 value) internal { + if (account == address(0)) { + revert ERC20InvalidSender(address(0)); + } + _update(account, address(0), value); + } + + /** + * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens. + * + * This internal function is equivalent to `approve`, and can be used to + * e.g. set automatic allowances for certain subsystems, etc. + * + * Emits an {Approval} event. + * + * Requirements: + * + * - `owner` cannot be the zero address. + * - `spender` cannot be the zero address. + * + * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument. + */ + function _approve(address owner, address spender, uint256 value) internal { + _approve(owner, spender, value, true); + } + + /** + * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event. + * + * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by + * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any + * `Approval` event during `transferFrom` operations. + * + * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to + * true using the following override: + * + * ```solidity + * function _approve(address owner, address spender, uint256 value, bool) internal virtual override { + * super._approve(owner, spender, value, true); + * } + * ``` + * + * Requirements are the same as {_approve}. + */ + function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual { + if (owner == address(0)) { + revert ERC20InvalidApprover(address(0)); + } + if (spender == address(0)) { + revert ERC20InvalidSpender(address(0)); + } + _allowances[owner][spender] = value; + if (emitEvent) { + emit Approval(owner, spender, value); + } + } + + /** + * @dev Updates `owner` s allowance for `spender` based on spent `value`. + * + * Does not update the allowance value in case of infinite allowance. + * Revert if not enough allowance is available. + * + * Does not emit an {Approval} event. + */ + function _spendAllowance(address owner, address spender, uint256 value) internal virtual { + uint256 currentAllowance = allowance(owner, spender); + if (currentAllowance != type(uint256).max) { + if (currentAllowance < value) { + revert ERC20InsufficientAllowance(spender, currentAllowance, value); + } + unchecked { + _approve(owner, spender, currentAllowance - value, false); + } + } + } +} \ No newline at end of file diff --git a/backend/internal/contracts/IERC20.sol b/backend/internal/contracts/IERC20.sol new file mode 100644 index 000000000..bcd73a9b1 --- /dev/null +++ b/backend/internal/contracts/IERC20.sol @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol) + +pragma solidity ^0.8.20; + +/** + * @dev Interface of the ERC-20 standard as defined in the ERC. + */ +interface IERC20 { + /** + * @dev Emitted when `value` tokens are moved from one account (`from`) to + * another (`to`). + * + * Note that `value` may be zero. + */ + event Transfer(address indexed from, address indexed to, uint256 value); + + /** + * @dev Emitted when the allowance of a `spender` for an `owner` is set by + * a call to {approve}. `value` is the new allowance. + */ + event Approval(address indexed owner, address indexed spender, uint256 value); + + /** + * @dev Returns the value of tokens in existence. + */ + function totalSupply() external view returns (uint256); + + /** + * @dev Returns the value of tokens owned by `account`. + */ + function balanceOf(address account) external view returns (uint256); + + /** + * @dev Moves a `value` amount of tokens from the caller's account to `to`. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transfer(address to, uint256 value) external returns (bool); + + /** + * @dev Returns the remaining number of tokens that `spender` will be + * allowed to spend on behalf of `owner` through {transferFrom}. This is + * zero by default. + * + * This value changes when {approve} or {transferFrom} are called. + */ + function allowance(address owner, address spender) external view returns (uint256); + + /** + * @dev Sets a `value` amount of tokens as the allowance of `spender` over the + * caller's tokens. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * IMPORTANT: Beware that changing an allowance with this method brings the risk + * that someone may use both the old and the new allowance by unfortunate + * transaction ordering. One possible solution to mitigate this race + * condition is to first reduce the spender's allowance to 0 and set the + * desired value afterwards: + * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + * + * Emits an {Approval} event. + */ + function approve(address spender, uint256 value) external returns (bool); + + /** + * @dev Moves a `value` amount of tokens from `from` to `to` using the + * allowance mechanism. `value` is then deducted from the caller's + * allowance. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transferFrom(address from, address to, uint256 value) external returns (bool); +} \ No newline at end of file diff --git a/backend/internal/contracts/IERC20Metadata.sol b/backend/internal/contracts/IERC20Metadata.sol new file mode 100644 index 000000000..cc608c03b --- /dev/null +++ b/backend/internal/contracts/IERC20Metadata.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol) + +pragma solidity ^0.8.20; + +import {IERC20} from "IERC20.sol"; + +/** + * @dev Interface for the optional metadata functions from the ERC-20 standard. + */ +interface IERC20Metadata is IERC20 { + /** + * @dev Returns the name of the token. + */ + function name() external view returns (string memory); + + /** + * @dev Returns the symbol of the token. + */ + function symbol() external view returns (string memory); + + /** + * @dev Returns the decimals places of the token. + */ + function decimals() external view returns (uint8); +} \ No newline at end of file diff --git a/backend/internal/contracts/IMulticall3.sol b/backend/internal/contracts/IMulticall3.sol new file mode 100644 index 000000000..585ba4a3e --- /dev/null +++ b/backend/internal/contracts/IMulticall3.sol @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; +pragma experimental ABIEncoderV2; + +interface IMulticall3 { + struct Call { + address target; + bytes callData; + } + + struct Call3 { + address target; + bool allowFailure; + bytes callData; + } + + struct Call3Value { + address target; + bool allowFailure; + uint256 value; + bytes callData; + } + + struct Result { + bool success; + bytes returnData; + } + + function aggregate(Call[] calldata calls) + external + payable + returns (uint256 blockNumber, bytes[] memory returnData); + + function aggregate3(Call3[] calldata calls) external view returns (Result[] memory returnData); + + function aggregate3Value(Call3Value[] calldata calls) + external + view + returns (Result[] memory returnData); + + function blockAndAggregate(Call[] calldata calls) + external + view + returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData); + + function getBasefee() external view returns (uint256 basefee); + + function getBlockHash(uint256 blockNumber) external view returns (bytes32 blockHash); + + function getBlockNumber() external view returns (uint256 blockNumber); + + function getChainId() external view returns (uint256 chainid); + + function getCurrentBlockCoinbase() external view returns (address coinbase); + + function getCurrentBlockDifficulty() external view returns (uint256 difficulty); + + function getCurrentBlockGasLimit() external view returns (uint256 gaslimit); + + function getCurrentBlockTimestamp() external view returns (uint256 timestamp); + + function getEthBalance(address addr) external view returns (uint256 balance); + + function getLastBlockHash() external view returns (bytes32 blockHash); + + function tryAggregate(bool requireSuccess, Call[] calldata calls) + external + view + returns (Result[] memory returnData); + + function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls) + external + view + returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData); +} diff --git a/backend/internal/contracts/Makefile b/backend/internal/contracts/Makefile new file mode 100644 index 000000000..b89a7cdf1 --- /dev/null +++ b/backend/internal/contracts/Makefile @@ -0,0 +1,30 @@ +############################################################################### +### Generate ABI ### +############################################################################### +generate-abi: clean ## Generate contract ABI Go code + solc --evm-version paris --optimize -o bin/contract --bin --abi --overwrite IERC20.sol + solc --evm-version paris --optimize -o bin/contract --bin --abi --overwrite Token.sol + solc --evm-version paris --optimize -o bin/contract --bin --abi --overwrite Multicall3.sol + solc --evm-version paris --optimize -o bin/contract --bin --abi --overwrite IMulticall3.sol + + abigen --abi=./bin/contract/IERC20.abi --type IERC20 --pkg=contracts --out=./ierc20.go + abigen --abi=./bin/contract/Token.abi --bin=./bin/contract/Token.bin -type Token --pkg=contracts --out=./token.go + abigen --abi=./bin/contract/Multicall3.abi --bin=./bin/contract/Multicall3.bin --type Multicall --pkg=contracts --out=./multicall.go + abigen --abi=./bin/contract/IMulticall3.abi --type IMulticall3 --pkg=contracts --out=./imulticall3.go + +############################################################################### +### Clean ### +############################################################################### +clean: + @echo "Cleaning..." + @rm -rf bin + +############################################################################### +### Help ### +############################################################################### +help: + @echo "Available commands:" + @echo " make generate-abi : Generate contract ABI Go code" + @echo " make clean : Clean the build" + @echo " make help : Print this help message" +.PHONY: help \ No newline at end of file diff --git a/backend/internal/contracts/Multicall3.sol b/backend/internal/contracts/Multicall3.sol new file mode 100644 index 000000000..a1f5e851c --- /dev/null +++ b/backend/internal/contracts/Multicall3.sol @@ -0,0 +1,216 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; + +/// @title Multicall3 +/// @notice Aggregate results from multiple function calls +/// @dev Multicall & Multicall2 backwards-compatible +/// @dev Aggregate methods are marked `payable` to save 24 gas per call +/// @author Michael Elliot +/// @author Joshua Levine +/// @author Nick Johnson +/// @author Andreas Bigger +/// @author Matt Solomon +contract Multicall3 { + struct Call { + address target; + bytes callData; + } + + struct Call3 { + address target; + bool allowFailure; + bytes callData; + } + + struct Call3Value { + address target; + bool allowFailure; + uint256 value; + bytes callData; + } + + struct Result { + bool success; + bytes returnData; + } + + /// @notice Backwards-compatible call aggregation with Multicall + /// @param calls An array of Call structs + /// @return blockNumber The block number where the calls were executed + /// @return returnData An array of bytes containing the responses + function aggregate(Call[] calldata calls) public payable returns (uint256 blockNumber, bytes[] memory returnData) { + blockNumber = block.number; + uint256 length = calls.length; + returnData = new bytes[](length); + Call calldata call; + for (uint256 i = 0; i < length;) { + bool success; + call = calls[i]; + (success, returnData[i]) = call.target.call(call.callData); + require(success, "Multicall3: call failed"); + unchecked { ++i; } + } + } + + /// @notice Backwards-compatible with Multicall2 + /// @notice Aggregate calls without requiring success + /// @param requireSuccess If true, require all calls to succeed + /// @param calls An array of Call structs + /// @return returnData An array of Result structs + function tryAggregate(bool requireSuccess, Call[] calldata calls) public payable returns (Result[] memory returnData) { + uint256 length = calls.length; + returnData = new Result[](length); + Call calldata call; + for (uint256 i = 0; i < length;) { + Result memory result = returnData[i]; + call = calls[i]; + (result.success, result.returnData) = call.target.call(call.callData); + if (requireSuccess) require(result.success, "Multicall3: call failed"); + unchecked { ++i; } + } + } + + /// @notice Backwards-compatible with Multicall2 + /// @notice Aggregate calls and allow failures using tryAggregate + /// @param calls An array of Call structs + /// @return blockNumber The block number where the calls were executed + /// @return blockHash The hash of the block where the calls were executed + /// @return returnData An array of Result structs + function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls) public payable returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData) { + blockNumber = block.number; + blockHash = blockhash(block.number); + returnData = tryAggregate(requireSuccess, calls); + } + + /// @notice Backwards-compatible with Multicall2 + /// @notice Aggregate calls and allow failures using tryAggregate + /// @param calls An array of Call structs + /// @return blockNumber The block number where the calls were executed + /// @return blockHash The hash of the block where the calls were executed + /// @return returnData An array of Result structs + function blockAndAggregate(Call[] calldata calls) public payable returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData) { + (blockNumber, blockHash, returnData) = tryBlockAndAggregate(true, calls); + } + + /// @notice Aggregate calls, ensuring each returns success if required + /// @param calls An array of Call3 structs + /// @return returnData An array of Result structs + function aggregate3(Call3[] calldata calls) public payable returns (Result[] memory returnData) { + uint256 length = calls.length; + returnData = new Result[](length); + Call3 calldata calli; + for (uint256 i = 0; i < length;) { + Result memory result = returnData[i]; + calli = calls[i]; + (result.success, result.returnData) = calli.target.call(calli.callData); + assembly { + // Revert if the call fails and failure is not allowed + // `allowFailure := calldataload(add(calli, 0x20))` and `success := mload(result)` + if iszero(or(calldataload(add(calli, 0x20)), mload(result))) { + // set "Error(string)" signature: bytes32(bytes4(keccak256("Error(string)"))) + mstore(0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000) + // set data offset + mstore(0x04, 0x0000000000000000000000000000000000000000000000000000000000000020) + // set length of revert string + mstore(0x24, 0x0000000000000000000000000000000000000000000000000000000000000017) + // set revert string: bytes32(abi.encodePacked("Multicall3: call failed")) + mstore(0x44, 0x4d756c746963616c6c333a2063616c6c206661696c6564000000000000000000) + revert(0x00, 0x64) + } + } + unchecked { ++i; } + } + } + + /// @notice Aggregate calls with a msg value + /// @notice Reverts if msg.value is less than the sum of the call values + /// @param calls An array of Call3Value structs + /// @return returnData An array of Result structs + function aggregate3Value(Call3Value[] calldata calls) public payable returns (Result[] memory returnData) { + uint256 valAccumulator; + uint256 length = calls.length; + returnData = new Result[](length); + Call3Value calldata calli; + for (uint256 i = 0; i < length;) { + Result memory result = returnData[i]; + calli = calls[i]; + uint256 val = calli.value; + // Humanity will be a Type V Kardashev Civilization before this overflows - andreas + // ~ 10^25 Wei in existence << ~ 10^76 size uint fits in a uint256 + unchecked { valAccumulator += val; } + (result.success, result.returnData) = calli.target.call{value: val}(calli.callData); + assembly { + // Revert if the call fails and failure is not allowed + // `allowFailure := calldataload(add(calli, 0x20))` and `success := mload(result)` + if iszero(or(calldataload(add(calli, 0x20)), mload(result))) { + // set "Error(string)" signature: bytes32(bytes4(keccak256("Error(string)"))) + mstore(0x00, 0x08c379a000000000000000000000000000000000000000000000000000000000) + // set data offset + mstore(0x04, 0x0000000000000000000000000000000000000000000000000000000000000020) + // set length of revert string + mstore(0x24, 0x0000000000000000000000000000000000000000000000000000000000000017) + // set revert string: bytes32(abi.encodePacked("Multicall3: call failed")) + mstore(0x44, 0x4d756c746963616c6c333a2063616c6c206661696c6564000000000000000000) + revert(0x00, 0x84) + } + } + unchecked { ++i; } + } + // Finally, make sure the msg.value = SUM(call[0...i].value) + require(msg.value == valAccumulator, "Multicall3: value mismatch"); + } + + /// @notice Returns the block hash for the given block number + /// @param blockNumber The block number + function getBlockHash(uint256 blockNumber) public view returns (bytes32 blockHash) { + blockHash = blockhash(blockNumber); + } + + /// @notice Returns the block number + function getBlockNumber() public view returns (uint256 blockNumber) { + blockNumber = block.number; + } + + /// @notice Returns the block coinbase + function getCurrentBlockCoinbase() public view returns (address coinbase) { + coinbase = block.coinbase; + } + + /// @notice Returns the block difficulty + function getCurrentBlockDifficulty() public view returns (uint256 difficulty) { + difficulty = block.difficulty; + } + + /// @notice Returns the block gas limit + function getCurrentBlockGasLimit() public view returns (uint256 gaslimit) { + gaslimit = block.gaslimit; + } + + /// @notice Returns the block timestamp + function getCurrentBlockTimestamp() public view returns (uint256 timestamp) { + timestamp = block.timestamp; + } + + /// @notice Returns the (ETH) balance of a given address + function getEthBalance(address addr) public view returns (uint256 balance) { + balance = addr.balance; + } + + /// @notice Returns the block hash of the last block + function getLastBlockHash() public view returns (bytes32 blockHash) { + unchecked { + blockHash = blockhash(block.number - 1); + } + } + + /// @notice Gets the base fee of the given block + /// @notice Can revert if the BASEFEE opcode is not implemented by the given chain + function getBasefee() public view returns (uint256 basefee) { + basefee = block.basefee; + } + + /// @notice Returns the chain id + function getChainId() public view returns (uint256 chainid) { + chainid = block.chainid; + } +} \ No newline at end of file diff --git a/backend/internal/contracts/README.md b/backend/internal/contracts/README.md new file mode 100644 index 000000000..a92b0ce3e --- /dev/null +++ b/backend/internal/contracts/README.md @@ -0,0 +1,28 @@ +# Contract ABI + +To generate the ABI interface in go you will need to install `solc` and `abigen`. + +- solc is available [here](https://docs.soliditylang.org/en/latest/installing-solidity.html) + +- and `abigen` wan be installed through go directly +``` +go install github.com/ethereum/go-ethereum/cmd/abigen@latest +``` + +You can then run `make generate-abi`. + +## Sources and Modification + +### ERC20, IERC20, IERC20METADATA, draft-IERC6093, Context +* https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol +* https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol +* https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/extensions/IERC20Metadata.sol +* https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/interfaces/draft-IERC6093.sol +* https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Context.sol + +### Token +* original contract, simple implementation of the abstract contract `ERC20` with a `mint` function + +### Multicall3, IMulticall3 +* https://github.com/mds1/multicall/blob/main/src/Multicall3.sol +* `IMulticall3` change `payable` functions to `view` to simplify go interaction, it is only suitable for reading \ No newline at end of file diff --git a/backend/internal/contracts/Token.sol b/backend/internal/contracts/Token.sol new file mode 100644 index 000000000..f9886f578 --- /dev/null +++ b/backend/internal/contracts/Token.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.20; + +import {ERC20} from "./ERC20.sol"; + +contract Token is ERC20 { + constructor(string memory name_, string memory symbol_) ERC20(name_, symbol_) {} + + function mint(address account, uint256 value) public { + _mint(account, value); + } +} + diff --git a/backend/internal/contracts/draft-IERC6093.sol b/backend/internal/contracts/draft-IERC6093.sol new file mode 100644 index 000000000..0703bf3e0 --- /dev/null +++ b/backend/internal/contracts/draft-IERC6093.sol @@ -0,0 +1,161 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol) +pragma solidity ^0.8.20; + +/** + * @dev Standard ERC-20 Errors + * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens. + */ +interface IERC20Errors { + /** + * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. + * @param sender Address whose tokens are being transferred. + * @param balance Current balance for the interacting account. + * @param needed Minimum amount required to perform a transfer. + */ + error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); + + /** + * @dev Indicates a failure with the token `sender`. Used in transfers. + * @param sender Address whose tokens are being transferred. + */ + error ERC20InvalidSender(address sender); + + /** + * @dev Indicates a failure with the token `receiver`. Used in transfers. + * @param receiver Address to which tokens are being transferred. + */ + error ERC20InvalidReceiver(address receiver); + + /** + * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. + * @param spender Address that may be allowed to operate on tokens without being their owner. + * @param allowance Amount of tokens a `spender` is allowed to operate with. + * @param needed Minimum amount required to perform a transfer. + */ + error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); + + /** + * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. + * @param approver Address initiating an approval operation. + */ + error ERC20InvalidApprover(address approver); + + /** + * @dev Indicates a failure with the `spender` to be approved. Used in approvals. + * @param spender Address that may be allowed to operate on tokens without being their owner. + */ + error ERC20InvalidSpender(address spender); +} + +/** + * @dev Standard ERC-721 Errors + * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens. + */ +interface IERC721Errors { + /** + * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20. + * Used in balance queries. + * @param owner Address of the current owner of a token. + */ + error ERC721InvalidOwner(address owner); + + /** + * @dev Indicates a `tokenId` whose `owner` is the zero address. + * @param tokenId Identifier number of a token. + */ + error ERC721NonexistentToken(uint256 tokenId); + + /** + * @dev Indicates an error related to the ownership over a particular token. Used in transfers. + * @param sender Address whose tokens are being transferred. + * @param tokenId Identifier number of a token. + * @param owner Address of the current owner of a token. + */ + error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner); + + /** + * @dev Indicates a failure with the token `sender`. Used in transfers. + * @param sender Address whose tokens are being transferred. + */ + error ERC721InvalidSender(address sender); + + /** + * @dev Indicates a failure with the token `receiver`. Used in transfers. + * @param receiver Address to which tokens are being transferred. + */ + error ERC721InvalidReceiver(address receiver); + + /** + * @dev Indicates a failure with the `operator`’s approval. Used in transfers. + * @param operator Address that may be allowed to operate on tokens without being their owner. + * @param tokenId Identifier number of a token. + */ + error ERC721InsufficientApproval(address operator, uint256 tokenId); + + /** + * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. + * @param approver Address initiating an approval operation. + */ + error ERC721InvalidApprover(address approver); + + /** + * @dev Indicates a failure with the `operator` to be approved. Used in approvals. + * @param operator Address that may be allowed to operate on tokens without being their owner. + */ + error ERC721InvalidOperator(address operator); +} + +/** + * @dev Standard ERC-1155 Errors + * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens. + */ +interface IERC1155Errors { + /** + * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. + * @param sender Address whose tokens are being transferred. + * @param balance Current balance for the interacting account. + * @param needed Minimum amount required to perform a transfer. + * @param tokenId Identifier number of a token. + */ + error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId); + + /** + * @dev Indicates a failure with the token `sender`. Used in transfers. + * @param sender Address whose tokens are being transferred. + */ + error ERC1155InvalidSender(address sender); + + /** + * @dev Indicates a failure with the token `receiver`. Used in transfers. + * @param receiver Address to which tokens are being transferred. + */ + error ERC1155InvalidReceiver(address receiver); + + /** + * @dev Indicates a failure with the `operator`’s approval. Used in transfers. + * @param operator Address that may be allowed to operate on tokens without being their owner. + * @param owner Address of the current owner of a token. + */ + error ERC1155MissingApprovalForAll(address operator, address owner); + + /** + * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. + * @param approver Address initiating an approval operation. + */ + error ERC1155InvalidApprover(address approver); + + /** + * @dev Indicates a failure with the `operator` to be approved. Used in approvals. + * @param operator Address that may be allowed to operate on tokens without being their owner. + */ + error ERC1155InvalidOperator(address operator); + + /** + * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation. + * Used in batch transfers. + * @param idsLength Length of the array of token identifiers + * @param valuesLength Length of the array of token amounts + */ + error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength); +} \ No newline at end of file diff --git a/backend/internal/contracts/ierc20.go b/backend/internal/contracts/ierc20.go new file mode 100644 index 000000000..af60a9d2d --- /dev/null +++ b/backend/internal/contracts/ierc20.go @@ -0,0 +1,645 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package contracts + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// IERC20MetaData contains all meta data concerning the IERC20 contract. +var IERC20MetaData = &bind.MetaData{ + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", +} + +// IERC20ABI is the input ABI used to generate the binding from. +// Deprecated: Use IERC20MetaData.ABI instead. +var IERC20ABI = IERC20MetaData.ABI + +// IERC20 is an auto generated Go binding around an Ethereum contract. +type IERC20 struct { + IERC20Caller // Read-only binding to the contract + IERC20Transactor // Write-only binding to the contract + IERC20Filterer // Log filterer for contract events +} + +// IERC20Caller is an auto generated read-only Go binding around an Ethereum contract. +type IERC20Caller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// IERC20Transactor is an auto generated write-only Go binding around an Ethereum contract. +type IERC20Transactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// IERC20Filterer is an auto generated log filtering Go binding around an Ethereum contract events. +type IERC20Filterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// IERC20Session is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type IERC20Session struct { + Contract *IERC20 // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// IERC20CallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type IERC20CallerSession struct { + Contract *IERC20Caller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// IERC20TransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type IERC20TransactorSession struct { + Contract *IERC20Transactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// IERC20Raw is an auto generated low-level Go binding around an Ethereum contract. +type IERC20Raw struct { + Contract *IERC20 // Generic contract binding to access the raw methods on +} + +// IERC20CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type IERC20CallerRaw struct { + Contract *IERC20Caller // Generic read-only contract binding to access the raw methods on +} + +// IERC20TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type IERC20TransactorRaw struct { + Contract *IERC20Transactor // Generic write-only contract binding to access the raw methods on +} + +// NewIERC20 creates a new instance of IERC20, bound to a specific deployed contract. +func NewIERC20(address common.Address, backend bind.ContractBackend) (*IERC20, error) { + contract, err := bindIERC20(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &IERC20{IERC20Caller: IERC20Caller{contract: contract}, IERC20Transactor: IERC20Transactor{contract: contract}, IERC20Filterer: IERC20Filterer{contract: contract}}, nil +} + +// NewIERC20Caller creates a new read-only instance of IERC20, bound to a specific deployed contract. +func NewIERC20Caller(address common.Address, caller bind.ContractCaller) (*IERC20Caller, error) { + contract, err := bindIERC20(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &IERC20Caller{contract: contract}, nil +} + +// NewIERC20Transactor creates a new write-only instance of IERC20, bound to a specific deployed contract. +func NewIERC20Transactor(address common.Address, transactor bind.ContractTransactor) (*IERC20Transactor, error) { + contract, err := bindIERC20(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &IERC20Transactor{contract: contract}, nil +} + +// NewIERC20Filterer creates a new log filterer instance of IERC20, bound to a specific deployed contract. +func NewIERC20Filterer(address common.Address, filterer bind.ContractFilterer) (*IERC20Filterer, error) { + contract, err := bindIERC20(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &IERC20Filterer{contract: contract}, nil +} + +// bindIERC20 binds a generic wrapper to an already deployed contract. +func bindIERC20(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := IERC20MetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_IERC20 *IERC20Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _IERC20.Contract.IERC20Caller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_IERC20 *IERC20Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IERC20.Contract.IERC20Transactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_IERC20 *IERC20Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _IERC20.Contract.IERC20Transactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_IERC20 *IERC20CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _IERC20.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_IERC20 *IERC20TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IERC20.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_IERC20 *IERC20TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _IERC20.Contract.contract.Transact(opts, method, params...) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_IERC20 *IERC20Caller) Allowance(opts *bind.CallOpts, owner common.Address, spender common.Address) (*big.Int, error) { + var out []interface{} + err := _IERC20.contract.Call(opts, &out, "allowance", owner, spender) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_IERC20 *IERC20Session) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _IERC20.Contract.Allowance(&_IERC20.CallOpts, owner, spender) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_IERC20 *IERC20CallerSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _IERC20.Contract.Allowance(&_IERC20.CallOpts, owner, spender) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_IERC20 *IERC20Caller) BalanceOf(opts *bind.CallOpts, account common.Address) (*big.Int, error) { + var out []interface{} + err := _IERC20.contract.Call(opts, &out, "balanceOf", account) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_IERC20 *IERC20Session) BalanceOf(account common.Address) (*big.Int, error) { + return _IERC20.Contract.BalanceOf(&_IERC20.CallOpts, account) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_IERC20 *IERC20CallerSession) BalanceOf(account common.Address) (*big.Int, error) { + return _IERC20.Contract.BalanceOf(&_IERC20.CallOpts, account) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_IERC20 *IERC20Caller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _IERC20.contract.Call(opts, &out, "totalSupply") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_IERC20 *IERC20Session) TotalSupply() (*big.Int, error) { + return _IERC20.Contract.TotalSupply(&_IERC20.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_IERC20 *IERC20CallerSession) TotalSupply() (*big.Int, error) { + return _IERC20.Contract.TotalSupply(&_IERC20.CallOpts) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 value) returns(bool) +func (_IERC20 *IERC20Transactor) Approve(opts *bind.TransactOpts, spender common.Address, value *big.Int) (*types.Transaction, error) { + return _IERC20.contract.Transact(opts, "approve", spender, value) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 value) returns(bool) +func (_IERC20 *IERC20Session) Approve(spender common.Address, value *big.Int) (*types.Transaction, error) { + return _IERC20.Contract.Approve(&_IERC20.TransactOpts, spender, value) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 value) returns(bool) +func (_IERC20 *IERC20TransactorSession) Approve(spender common.Address, value *big.Int) (*types.Transaction, error) { + return _IERC20.Contract.Approve(&_IERC20.TransactOpts, spender, value) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 value) returns(bool) +func (_IERC20 *IERC20Transactor) Transfer(opts *bind.TransactOpts, to common.Address, value *big.Int) (*types.Transaction, error) { + return _IERC20.contract.Transact(opts, "transfer", to, value) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 value) returns(bool) +func (_IERC20 *IERC20Session) Transfer(to common.Address, value *big.Int) (*types.Transaction, error) { + return _IERC20.Contract.Transfer(&_IERC20.TransactOpts, to, value) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 value) returns(bool) +func (_IERC20 *IERC20TransactorSession) Transfer(to common.Address, value *big.Int) (*types.Transaction, error) { + return _IERC20.Contract.Transfer(&_IERC20.TransactOpts, to, value) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) +func (_IERC20 *IERC20Transactor) TransferFrom(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _IERC20.contract.Transact(opts, "transferFrom", from, to, value) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) +func (_IERC20 *IERC20Session) TransferFrom(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _IERC20.Contract.TransferFrom(&_IERC20.TransactOpts, from, to, value) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) +func (_IERC20 *IERC20TransactorSession) TransferFrom(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _IERC20.Contract.TransferFrom(&_IERC20.TransactOpts, from, to, value) +} + +// IERC20ApprovalIterator is returned from FilterApproval and is used to iterate over the raw logs and unpacked data for Approval events raised by the IERC20 contract. +type IERC20ApprovalIterator struct { + Event *IERC20Approval // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *IERC20ApprovalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(IERC20Approval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(IERC20Approval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *IERC20ApprovalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *IERC20ApprovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// IERC20Approval represents a Approval event raised by the IERC20 contract. +type IERC20Approval struct { + Owner common.Address + Spender common.Address + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterApproval is a free log retrieval operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_IERC20 *IERC20Filterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*IERC20ApprovalIterator, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _IERC20.contract.FilterLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return &IERC20ApprovalIterator{contract: _IERC20.contract, event: "Approval", logs: logs, sub: sub}, nil +} + +// WatchApproval is a free log subscription operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_IERC20 *IERC20Filterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *IERC20Approval, owner []common.Address, spender []common.Address) (event.Subscription, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _IERC20.contract.WatchLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(IERC20Approval) + if err := _IERC20.contract.UnpackLog(event, "Approval", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseApproval is a log parse operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_IERC20 *IERC20Filterer) ParseApproval(log types.Log) (*IERC20Approval, error) { + event := new(IERC20Approval) + if err := _IERC20.contract.UnpackLog(event, "Approval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// IERC20TransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the IERC20 contract. +type IERC20TransferIterator struct { + Event *IERC20Transfer // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *IERC20TransferIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(IERC20Transfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(IERC20Transfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *IERC20TransferIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *IERC20TransferIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// IERC20Transfer represents a Transfer event raised by the IERC20 contract. +type IERC20Transfer struct { + From common.Address + To common.Address + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTransfer is a free log retrieval operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_IERC20 *IERC20Filterer) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*IERC20TransferIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _IERC20.contract.FilterLogs(opts, "Transfer", fromRule, toRule) + if err != nil { + return nil, err + } + return &IERC20TransferIterator{contract: _IERC20.contract, event: "Transfer", logs: logs, sub: sub}, nil +} + +// WatchTransfer is a free log subscription operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_IERC20 *IERC20Filterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *IERC20Transfer, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _IERC20.contract.WatchLogs(opts, "Transfer", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(IERC20Transfer) + if err := _IERC20.contract.UnpackLog(event, "Transfer", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseTransfer is a log parse operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_IERC20 *IERC20Filterer) ParseTransfer(log types.Log) (*IERC20Transfer, error) { + event := new(IERC20Transfer) + if err := _IERC20.contract.UnpackLog(event, "Transfer", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/backend/internal/contracts/imulticall3.go b/backend/internal/contracts/imulticall3.go new file mode 100644 index 000000000..1b447910f --- /dev/null +++ b/backend/internal/contracts/imulticall3.go @@ -0,0 +1,732 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package contracts + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// IMulticall3Call is an auto generated low-level Go binding around an user-defined struct. +type IMulticall3Call struct { + Target common.Address + CallData []byte +} + +// IMulticall3Call3 is an auto generated low-level Go binding around an user-defined struct. +type IMulticall3Call3 struct { + Target common.Address + AllowFailure bool + CallData []byte +} + +// IMulticall3Call3Value is an auto generated low-level Go binding around an user-defined struct. +type IMulticall3Call3Value struct { + Target common.Address + AllowFailure bool + Value *big.Int + CallData []byte +} + +// IMulticall3Result is an auto generated low-level Go binding around an user-defined struct. +type IMulticall3Result struct { + Success bool + ReturnData []byte +} + +// IMulticall3MetaData contains all meta data concerning the IMulticall3 contract. +var IMulticall3MetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"structIMulticall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"aggregate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"returnData\",\"type\":\"bytes[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowFailure\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"structIMulticall3.Call3[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"aggregate3\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"structIMulticall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowFailure\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"structIMulticall3.Call3Value[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"aggregate3Value\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"structIMulticall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"structIMulticall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"blockAndAggregate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"structIMulticall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBasefee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"basefee\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"name\":\"getBlockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChainId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainid\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockCoinbase\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"coinbase\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockDifficulty\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"difficulty\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockGasLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"gaslimit\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"getEthBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLastBlockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"requireSuccess\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"structIMulticall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"tryAggregate\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"structIMulticall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"requireSuccess\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"structIMulticall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"tryBlockAndAggregate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"structIMulticall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", +} + +// IMulticall3ABI is the input ABI used to generate the binding from. +// Deprecated: Use IMulticall3MetaData.ABI instead. +var IMulticall3ABI = IMulticall3MetaData.ABI + +// IMulticall3 is an auto generated Go binding around an Ethereum contract. +type IMulticall3 struct { + IMulticall3Caller // Read-only binding to the contract + IMulticall3Transactor // Write-only binding to the contract + IMulticall3Filterer // Log filterer for contract events +} + +// IMulticall3Caller is an auto generated read-only Go binding around an Ethereum contract. +type IMulticall3Caller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// IMulticall3Transactor is an auto generated write-only Go binding around an Ethereum contract. +type IMulticall3Transactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// IMulticall3Filterer is an auto generated log filtering Go binding around an Ethereum contract events. +type IMulticall3Filterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// IMulticall3Session is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type IMulticall3Session struct { + Contract *IMulticall3 // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// IMulticall3CallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type IMulticall3CallerSession struct { + Contract *IMulticall3Caller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// IMulticall3TransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type IMulticall3TransactorSession struct { + Contract *IMulticall3Transactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// IMulticall3Raw is an auto generated low-level Go binding around an Ethereum contract. +type IMulticall3Raw struct { + Contract *IMulticall3 // Generic contract binding to access the raw methods on +} + +// IMulticall3CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type IMulticall3CallerRaw struct { + Contract *IMulticall3Caller // Generic read-only contract binding to access the raw methods on +} + +// IMulticall3TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type IMulticall3TransactorRaw struct { + Contract *IMulticall3Transactor // Generic write-only contract binding to access the raw methods on +} + +// NewIMulticall3 creates a new instance of IMulticall3, bound to a specific deployed contract. +func NewIMulticall3(address common.Address, backend bind.ContractBackend) (*IMulticall3, error) { + contract, err := bindIMulticall3(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &IMulticall3{IMulticall3Caller: IMulticall3Caller{contract: contract}, IMulticall3Transactor: IMulticall3Transactor{contract: contract}, IMulticall3Filterer: IMulticall3Filterer{contract: contract}}, nil +} + +// NewIMulticall3Caller creates a new read-only instance of IMulticall3, bound to a specific deployed contract. +func NewIMulticall3Caller(address common.Address, caller bind.ContractCaller) (*IMulticall3Caller, error) { + contract, err := bindIMulticall3(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &IMulticall3Caller{contract: contract}, nil +} + +// NewIMulticall3Transactor creates a new write-only instance of IMulticall3, bound to a specific deployed contract. +func NewIMulticall3Transactor(address common.Address, transactor bind.ContractTransactor) (*IMulticall3Transactor, error) { + contract, err := bindIMulticall3(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &IMulticall3Transactor{contract: contract}, nil +} + +// NewIMulticall3Filterer creates a new log filterer instance of IMulticall3, bound to a specific deployed contract. +func NewIMulticall3Filterer(address common.Address, filterer bind.ContractFilterer) (*IMulticall3Filterer, error) { + contract, err := bindIMulticall3(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &IMulticall3Filterer{contract: contract}, nil +} + +// bindIMulticall3 binds a generic wrapper to an already deployed contract. +func bindIMulticall3(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := IMulticall3MetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_IMulticall3 *IMulticall3Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _IMulticall3.Contract.IMulticall3Caller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_IMulticall3 *IMulticall3Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IMulticall3.Contract.IMulticall3Transactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_IMulticall3 *IMulticall3Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _IMulticall3.Contract.IMulticall3Transactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_IMulticall3 *IMulticall3CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _IMulticall3.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_IMulticall3 *IMulticall3TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IMulticall3.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_IMulticall3 *IMulticall3TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _IMulticall3.Contract.contract.Transact(opts, method, params...) +} + +// Aggregate3 is a free data retrieval call binding the contract method 0x82ad56cb. +// +// Solidity: function aggregate3((address,bool,bytes)[] calls) view returns((bool,bytes)[] returnData) +func (_IMulticall3 *IMulticall3Caller) Aggregate3(opts *bind.CallOpts, calls []IMulticall3Call3) ([]IMulticall3Result, error) { + var out []interface{} + err := _IMulticall3.contract.Call(opts, &out, "aggregate3", calls) + + if err != nil { + return *new([]IMulticall3Result), err + } + + out0 := *abi.ConvertType(out[0], new([]IMulticall3Result)).(*[]IMulticall3Result) + + return out0, err + +} + +// Aggregate3 is a free data retrieval call binding the contract method 0x82ad56cb. +// +// Solidity: function aggregate3((address,bool,bytes)[] calls) view returns((bool,bytes)[] returnData) +func (_IMulticall3 *IMulticall3Session) Aggregate3(calls []IMulticall3Call3) ([]IMulticall3Result, error) { + return _IMulticall3.Contract.Aggregate3(&_IMulticall3.CallOpts, calls) +} + +// Aggregate3 is a free data retrieval call binding the contract method 0x82ad56cb. +// +// Solidity: function aggregate3((address,bool,bytes)[] calls) view returns((bool,bytes)[] returnData) +func (_IMulticall3 *IMulticall3CallerSession) Aggregate3(calls []IMulticall3Call3) ([]IMulticall3Result, error) { + return _IMulticall3.Contract.Aggregate3(&_IMulticall3.CallOpts, calls) +} + +// Aggregate3Value is a free data retrieval call binding the contract method 0x174dea71. +// +// Solidity: function aggregate3Value((address,bool,uint256,bytes)[] calls) view returns((bool,bytes)[] returnData) +func (_IMulticall3 *IMulticall3Caller) Aggregate3Value(opts *bind.CallOpts, calls []IMulticall3Call3Value) ([]IMulticall3Result, error) { + var out []interface{} + err := _IMulticall3.contract.Call(opts, &out, "aggregate3Value", calls) + + if err != nil { + return *new([]IMulticall3Result), err + } + + out0 := *abi.ConvertType(out[0], new([]IMulticall3Result)).(*[]IMulticall3Result) + + return out0, err + +} + +// Aggregate3Value is a free data retrieval call binding the contract method 0x174dea71. +// +// Solidity: function aggregate3Value((address,bool,uint256,bytes)[] calls) view returns((bool,bytes)[] returnData) +func (_IMulticall3 *IMulticall3Session) Aggregate3Value(calls []IMulticall3Call3Value) ([]IMulticall3Result, error) { + return _IMulticall3.Contract.Aggregate3Value(&_IMulticall3.CallOpts, calls) +} + +// Aggregate3Value is a free data retrieval call binding the contract method 0x174dea71. +// +// Solidity: function aggregate3Value((address,bool,uint256,bytes)[] calls) view returns((bool,bytes)[] returnData) +func (_IMulticall3 *IMulticall3CallerSession) Aggregate3Value(calls []IMulticall3Call3Value) ([]IMulticall3Result, error) { + return _IMulticall3.Contract.Aggregate3Value(&_IMulticall3.CallOpts, calls) +} + +// BlockAndAggregate is a free data retrieval call binding the contract method 0xc3077fa9. +// +// Solidity: function blockAndAggregate((address,bytes)[] calls) view returns(uint256 blockNumber, bytes32 blockHash, (bool,bytes)[] returnData) +func (_IMulticall3 *IMulticall3Caller) BlockAndAggregate(opts *bind.CallOpts, calls []IMulticall3Call) (struct { + BlockNumber *big.Int + BlockHash [32]byte + ReturnData []IMulticall3Result +}, error) { + var out []interface{} + err := _IMulticall3.contract.Call(opts, &out, "blockAndAggregate", calls) + + outstruct := new(struct { + BlockNumber *big.Int + BlockHash [32]byte + ReturnData []IMulticall3Result + }) + if err != nil { + return *outstruct, err + } + + outstruct.BlockNumber = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.BlockHash = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) + outstruct.ReturnData = *abi.ConvertType(out[2], new([]IMulticall3Result)).(*[]IMulticall3Result) + + return *outstruct, err + +} + +// BlockAndAggregate is a free data retrieval call binding the contract method 0xc3077fa9. +// +// Solidity: function blockAndAggregate((address,bytes)[] calls) view returns(uint256 blockNumber, bytes32 blockHash, (bool,bytes)[] returnData) +func (_IMulticall3 *IMulticall3Session) BlockAndAggregate(calls []IMulticall3Call) (struct { + BlockNumber *big.Int + BlockHash [32]byte + ReturnData []IMulticall3Result +}, error) { + return _IMulticall3.Contract.BlockAndAggregate(&_IMulticall3.CallOpts, calls) +} + +// BlockAndAggregate is a free data retrieval call binding the contract method 0xc3077fa9. +// +// Solidity: function blockAndAggregate((address,bytes)[] calls) view returns(uint256 blockNumber, bytes32 blockHash, (bool,bytes)[] returnData) +func (_IMulticall3 *IMulticall3CallerSession) BlockAndAggregate(calls []IMulticall3Call) (struct { + BlockNumber *big.Int + BlockHash [32]byte + ReturnData []IMulticall3Result +}, error) { + return _IMulticall3.Contract.BlockAndAggregate(&_IMulticall3.CallOpts, calls) +} + +// GetBasefee is a free data retrieval call binding the contract method 0x3e64a696. +// +// Solidity: function getBasefee() view returns(uint256 basefee) +func (_IMulticall3 *IMulticall3Caller) GetBasefee(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _IMulticall3.contract.Call(opts, &out, "getBasefee") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetBasefee is a free data retrieval call binding the contract method 0x3e64a696. +// +// Solidity: function getBasefee() view returns(uint256 basefee) +func (_IMulticall3 *IMulticall3Session) GetBasefee() (*big.Int, error) { + return _IMulticall3.Contract.GetBasefee(&_IMulticall3.CallOpts) +} + +// GetBasefee is a free data retrieval call binding the contract method 0x3e64a696. +// +// Solidity: function getBasefee() view returns(uint256 basefee) +func (_IMulticall3 *IMulticall3CallerSession) GetBasefee() (*big.Int, error) { + return _IMulticall3.Contract.GetBasefee(&_IMulticall3.CallOpts) +} + +// GetBlockHash is a free data retrieval call binding the contract method 0xee82ac5e. +// +// Solidity: function getBlockHash(uint256 blockNumber) view returns(bytes32 blockHash) +func (_IMulticall3 *IMulticall3Caller) GetBlockHash(opts *bind.CallOpts, blockNumber *big.Int) ([32]byte, error) { + var out []interface{} + err := _IMulticall3.contract.Call(opts, &out, "getBlockHash", blockNumber) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetBlockHash is a free data retrieval call binding the contract method 0xee82ac5e. +// +// Solidity: function getBlockHash(uint256 blockNumber) view returns(bytes32 blockHash) +func (_IMulticall3 *IMulticall3Session) GetBlockHash(blockNumber *big.Int) ([32]byte, error) { + return _IMulticall3.Contract.GetBlockHash(&_IMulticall3.CallOpts, blockNumber) +} + +// GetBlockHash is a free data retrieval call binding the contract method 0xee82ac5e. +// +// Solidity: function getBlockHash(uint256 blockNumber) view returns(bytes32 blockHash) +func (_IMulticall3 *IMulticall3CallerSession) GetBlockHash(blockNumber *big.Int) ([32]byte, error) { + return _IMulticall3.Contract.GetBlockHash(&_IMulticall3.CallOpts, blockNumber) +} + +// GetBlockNumber is a free data retrieval call binding the contract method 0x42cbb15c. +// +// Solidity: function getBlockNumber() view returns(uint256 blockNumber) +func (_IMulticall3 *IMulticall3Caller) GetBlockNumber(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _IMulticall3.contract.Call(opts, &out, "getBlockNumber") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetBlockNumber is a free data retrieval call binding the contract method 0x42cbb15c. +// +// Solidity: function getBlockNumber() view returns(uint256 blockNumber) +func (_IMulticall3 *IMulticall3Session) GetBlockNumber() (*big.Int, error) { + return _IMulticall3.Contract.GetBlockNumber(&_IMulticall3.CallOpts) +} + +// GetBlockNumber is a free data retrieval call binding the contract method 0x42cbb15c. +// +// Solidity: function getBlockNumber() view returns(uint256 blockNumber) +func (_IMulticall3 *IMulticall3CallerSession) GetBlockNumber() (*big.Int, error) { + return _IMulticall3.Contract.GetBlockNumber(&_IMulticall3.CallOpts) +} + +// GetChainId is a free data retrieval call binding the contract method 0x3408e470. +// +// Solidity: function getChainId() view returns(uint256 chainid) +func (_IMulticall3 *IMulticall3Caller) GetChainId(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _IMulticall3.contract.Call(opts, &out, "getChainId") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetChainId is a free data retrieval call binding the contract method 0x3408e470. +// +// Solidity: function getChainId() view returns(uint256 chainid) +func (_IMulticall3 *IMulticall3Session) GetChainId() (*big.Int, error) { + return _IMulticall3.Contract.GetChainId(&_IMulticall3.CallOpts) +} + +// GetChainId is a free data retrieval call binding the contract method 0x3408e470. +// +// Solidity: function getChainId() view returns(uint256 chainid) +func (_IMulticall3 *IMulticall3CallerSession) GetChainId() (*big.Int, error) { + return _IMulticall3.Contract.GetChainId(&_IMulticall3.CallOpts) +} + +// GetCurrentBlockCoinbase is a free data retrieval call binding the contract method 0xa8b0574e. +// +// Solidity: function getCurrentBlockCoinbase() view returns(address coinbase) +func (_IMulticall3 *IMulticall3Caller) GetCurrentBlockCoinbase(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _IMulticall3.contract.Call(opts, &out, "getCurrentBlockCoinbase") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetCurrentBlockCoinbase is a free data retrieval call binding the contract method 0xa8b0574e. +// +// Solidity: function getCurrentBlockCoinbase() view returns(address coinbase) +func (_IMulticall3 *IMulticall3Session) GetCurrentBlockCoinbase() (common.Address, error) { + return _IMulticall3.Contract.GetCurrentBlockCoinbase(&_IMulticall3.CallOpts) +} + +// GetCurrentBlockCoinbase is a free data retrieval call binding the contract method 0xa8b0574e. +// +// Solidity: function getCurrentBlockCoinbase() view returns(address coinbase) +func (_IMulticall3 *IMulticall3CallerSession) GetCurrentBlockCoinbase() (common.Address, error) { + return _IMulticall3.Contract.GetCurrentBlockCoinbase(&_IMulticall3.CallOpts) +} + +// GetCurrentBlockDifficulty is a free data retrieval call binding the contract method 0x72425d9d. +// +// Solidity: function getCurrentBlockDifficulty() view returns(uint256 difficulty) +func (_IMulticall3 *IMulticall3Caller) GetCurrentBlockDifficulty(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _IMulticall3.contract.Call(opts, &out, "getCurrentBlockDifficulty") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetCurrentBlockDifficulty is a free data retrieval call binding the contract method 0x72425d9d. +// +// Solidity: function getCurrentBlockDifficulty() view returns(uint256 difficulty) +func (_IMulticall3 *IMulticall3Session) GetCurrentBlockDifficulty() (*big.Int, error) { + return _IMulticall3.Contract.GetCurrentBlockDifficulty(&_IMulticall3.CallOpts) +} + +// GetCurrentBlockDifficulty is a free data retrieval call binding the contract method 0x72425d9d. +// +// Solidity: function getCurrentBlockDifficulty() view returns(uint256 difficulty) +func (_IMulticall3 *IMulticall3CallerSession) GetCurrentBlockDifficulty() (*big.Int, error) { + return _IMulticall3.Contract.GetCurrentBlockDifficulty(&_IMulticall3.CallOpts) +} + +// GetCurrentBlockGasLimit is a free data retrieval call binding the contract method 0x86d516e8. +// +// Solidity: function getCurrentBlockGasLimit() view returns(uint256 gaslimit) +func (_IMulticall3 *IMulticall3Caller) GetCurrentBlockGasLimit(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _IMulticall3.contract.Call(opts, &out, "getCurrentBlockGasLimit") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetCurrentBlockGasLimit is a free data retrieval call binding the contract method 0x86d516e8. +// +// Solidity: function getCurrentBlockGasLimit() view returns(uint256 gaslimit) +func (_IMulticall3 *IMulticall3Session) GetCurrentBlockGasLimit() (*big.Int, error) { + return _IMulticall3.Contract.GetCurrentBlockGasLimit(&_IMulticall3.CallOpts) +} + +// GetCurrentBlockGasLimit is a free data retrieval call binding the contract method 0x86d516e8. +// +// Solidity: function getCurrentBlockGasLimit() view returns(uint256 gaslimit) +func (_IMulticall3 *IMulticall3CallerSession) GetCurrentBlockGasLimit() (*big.Int, error) { + return _IMulticall3.Contract.GetCurrentBlockGasLimit(&_IMulticall3.CallOpts) +} + +// GetCurrentBlockTimestamp is a free data retrieval call binding the contract method 0x0f28c97d. +// +// Solidity: function getCurrentBlockTimestamp() view returns(uint256 timestamp) +func (_IMulticall3 *IMulticall3Caller) GetCurrentBlockTimestamp(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _IMulticall3.contract.Call(opts, &out, "getCurrentBlockTimestamp") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetCurrentBlockTimestamp is a free data retrieval call binding the contract method 0x0f28c97d. +// +// Solidity: function getCurrentBlockTimestamp() view returns(uint256 timestamp) +func (_IMulticall3 *IMulticall3Session) GetCurrentBlockTimestamp() (*big.Int, error) { + return _IMulticall3.Contract.GetCurrentBlockTimestamp(&_IMulticall3.CallOpts) +} + +// GetCurrentBlockTimestamp is a free data retrieval call binding the contract method 0x0f28c97d. +// +// Solidity: function getCurrentBlockTimestamp() view returns(uint256 timestamp) +func (_IMulticall3 *IMulticall3CallerSession) GetCurrentBlockTimestamp() (*big.Int, error) { + return _IMulticall3.Contract.GetCurrentBlockTimestamp(&_IMulticall3.CallOpts) +} + +// GetEthBalance is a free data retrieval call binding the contract method 0x4d2301cc. +// +// Solidity: function getEthBalance(address addr) view returns(uint256 balance) +func (_IMulticall3 *IMulticall3Caller) GetEthBalance(opts *bind.CallOpts, addr common.Address) (*big.Int, error) { + var out []interface{} + err := _IMulticall3.contract.Call(opts, &out, "getEthBalance", addr) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetEthBalance is a free data retrieval call binding the contract method 0x4d2301cc. +// +// Solidity: function getEthBalance(address addr) view returns(uint256 balance) +func (_IMulticall3 *IMulticall3Session) GetEthBalance(addr common.Address) (*big.Int, error) { + return _IMulticall3.Contract.GetEthBalance(&_IMulticall3.CallOpts, addr) +} + +// GetEthBalance is a free data retrieval call binding the contract method 0x4d2301cc. +// +// Solidity: function getEthBalance(address addr) view returns(uint256 balance) +func (_IMulticall3 *IMulticall3CallerSession) GetEthBalance(addr common.Address) (*big.Int, error) { + return _IMulticall3.Contract.GetEthBalance(&_IMulticall3.CallOpts, addr) +} + +// GetLastBlockHash is a free data retrieval call binding the contract method 0x27e86d6e. +// +// Solidity: function getLastBlockHash() view returns(bytes32 blockHash) +func (_IMulticall3 *IMulticall3Caller) GetLastBlockHash(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _IMulticall3.contract.Call(opts, &out, "getLastBlockHash") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetLastBlockHash is a free data retrieval call binding the contract method 0x27e86d6e. +// +// Solidity: function getLastBlockHash() view returns(bytes32 blockHash) +func (_IMulticall3 *IMulticall3Session) GetLastBlockHash() ([32]byte, error) { + return _IMulticall3.Contract.GetLastBlockHash(&_IMulticall3.CallOpts) +} + +// GetLastBlockHash is a free data retrieval call binding the contract method 0x27e86d6e. +// +// Solidity: function getLastBlockHash() view returns(bytes32 blockHash) +func (_IMulticall3 *IMulticall3CallerSession) GetLastBlockHash() ([32]byte, error) { + return _IMulticall3.Contract.GetLastBlockHash(&_IMulticall3.CallOpts) +} + +// TryAggregate is a free data retrieval call binding the contract method 0xbce38bd7. +// +// Solidity: function tryAggregate(bool requireSuccess, (address,bytes)[] calls) view returns((bool,bytes)[] returnData) +func (_IMulticall3 *IMulticall3Caller) TryAggregate(opts *bind.CallOpts, requireSuccess bool, calls []IMulticall3Call) ([]IMulticall3Result, error) { + var out []interface{} + err := _IMulticall3.contract.Call(opts, &out, "tryAggregate", requireSuccess, calls) + + if err != nil { + return *new([]IMulticall3Result), err + } + + out0 := *abi.ConvertType(out[0], new([]IMulticall3Result)).(*[]IMulticall3Result) + + return out0, err + +} + +// TryAggregate is a free data retrieval call binding the contract method 0xbce38bd7. +// +// Solidity: function tryAggregate(bool requireSuccess, (address,bytes)[] calls) view returns((bool,bytes)[] returnData) +func (_IMulticall3 *IMulticall3Session) TryAggregate(requireSuccess bool, calls []IMulticall3Call) ([]IMulticall3Result, error) { + return _IMulticall3.Contract.TryAggregate(&_IMulticall3.CallOpts, requireSuccess, calls) +} + +// TryAggregate is a free data retrieval call binding the contract method 0xbce38bd7. +// +// Solidity: function tryAggregate(bool requireSuccess, (address,bytes)[] calls) view returns((bool,bytes)[] returnData) +func (_IMulticall3 *IMulticall3CallerSession) TryAggregate(requireSuccess bool, calls []IMulticall3Call) ([]IMulticall3Result, error) { + return _IMulticall3.Contract.TryAggregate(&_IMulticall3.CallOpts, requireSuccess, calls) +} + +// TryBlockAndAggregate is a free data retrieval call binding the contract method 0x399542e9. +// +// Solidity: function tryBlockAndAggregate(bool requireSuccess, (address,bytes)[] calls) view returns(uint256 blockNumber, bytes32 blockHash, (bool,bytes)[] returnData) +func (_IMulticall3 *IMulticall3Caller) TryBlockAndAggregate(opts *bind.CallOpts, requireSuccess bool, calls []IMulticall3Call) (struct { + BlockNumber *big.Int + BlockHash [32]byte + ReturnData []IMulticall3Result +}, error) { + var out []interface{} + err := _IMulticall3.contract.Call(opts, &out, "tryBlockAndAggregate", requireSuccess, calls) + + outstruct := new(struct { + BlockNumber *big.Int + BlockHash [32]byte + ReturnData []IMulticall3Result + }) + if err != nil { + return *outstruct, err + } + + outstruct.BlockNumber = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.BlockHash = *abi.ConvertType(out[1], new([32]byte)).(*[32]byte) + outstruct.ReturnData = *abi.ConvertType(out[2], new([]IMulticall3Result)).(*[]IMulticall3Result) + + return *outstruct, err + +} + +// TryBlockAndAggregate is a free data retrieval call binding the contract method 0x399542e9. +// +// Solidity: function tryBlockAndAggregate(bool requireSuccess, (address,bytes)[] calls) view returns(uint256 blockNumber, bytes32 blockHash, (bool,bytes)[] returnData) +func (_IMulticall3 *IMulticall3Session) TryBlockAndAggregate(requireSuccess bool, calls []IMulticall3Call) (struct { + BlockNumber *big.Int + BlockHash [32]byte + ReturnData []IMulticall3Result +}, error) { + return _IMulticall3.Contract.TryBlockAndAggregate(&_IMulticall3.CallOpts, requireSuccess, calls) +} + +// TryBlockAndAggregate is a free data retrieval call binding the contract method 0x399542e9. +// +// Solidity: function tryBlockAndAggregate(bool requireSuccess, (address,bytes)[] calls) view returns(uint256 blockNumber, bytes32 blockHash, (bool,bytes)[] returnData) +func (_IMulticall3 *IMulticall3CallerSession) TryBlockAndAggregate(requireSuccess bool, calls []IMulticall3Call) (struct { + BlockNumber *big.Int + BlockHash [32]byte + ReturnData []IMulticall3Result +}, error) { + return _IMulticall3.Contract.TryBlockAndAggregate(&_IMulticall3.CallOpts, requireSuccess, calls) +} + +// Aggregate is a paid mutator transaction binding the contract method 0x252dba42. +// +// Solidity: function aggregate((address,bytes)[] calls) payable returns(uint256 blockNumber, bytes[] returnData) +func (_IMulticall3 *IMulticall3Transactor) Aggregate(opts *bind.TransactOpts, calls []IMulticall3Call) (*types.Transaction, error) { + return _IMulticall3.contract.Transact(opts, "aggregate", calls) +} + +// Aggregate is a paid mutator transaction binding the contract method 0x252dba42. +// +// Solidity: function aggregate((address,bytes)[] calls) payable returns(uint256 blockNumber, bytes[] returnData) +func (_IMulticall3 *IMulticall3Session) Aggregate(calls []IMulticall3Call) (*types.Transaction, error) { + return _IMulticall3.Contract.Aggregate(&_IMulticall3.TransactOpts, calls) +} + +// Aggregate is a paid mutator transaction binding the contract method 0x252dba42. +// +// Solidity: function aggregate((address,bytes)[] calls) payable returns(uint256 blockNumber, bytes[] returnData) +func (_IMulticall3 *IMulticall3TransactorSession) Aggregate(calls []IMulticall3Call) (*types.Transaction, error) { + return _IMulticall3.Contract.Aggregate(&_IMulticall3.TransactOpts, calls) +} diff --git a/backend/internal/contracts/multicall.go b/backend/internal/contracts/multicall.go new file mode 100644 index 000000000..0bb821cf0 --- /dev/null +++ b/backend/internal/contracts/multicall.go @@ -0,0 +1,666 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package contracts + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// Multicall3Call is an auto generated low-level Go binding around an user-defined struct. +type Multicall3Call struct { + Target common.Address + CallData []byte +} + +// Multicall3Call3 is an auto generated low-level Go binding around an user-defined struct. +type Multicall3Call3 struct { + Target common.Address + AllowFailure bool + CallData []byte +} + +// Multicall3Call3Value is an auto generated low-level Go binding around an user-defined struct. +type Multicall3Call3Value struct { + Target common.Address + AllowFailure bool + Value *big.Int + CallData []byte +} + +// Multicall3Result is an auto generated low-level Go binding around an user-defined struct. +type Multicall3Result struct { + Success bool + ReturnData []byte +} + +// MulticallMetaData contains all meta data concerning the Multicall contract. +var MulticallMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"structMulticall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"aggregate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"returnData\",\"type\":\"bytes[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowFailure\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"structMulticall3.Call3[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"aggregate3\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"structMulticall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowFailure\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"structMulticall3.Call3Value[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"aggregate3Value\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"structMulticall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"structMulticall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"blockAndAggregate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"structMulticall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBasefee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"basefee\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"name\":\"getBlockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBlockNumber\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getChainId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"chainid\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockCoinbase\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"coinbase\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockDifficulty\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"difficulty\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockGasLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"gaslimit\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"getEthBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLastBlockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"requireSuccess\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"structMulticall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"tryAggregate\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"structMulticall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bool\",\"name\":\"requireSuccess\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"structMulticall3.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"tryBlockAndAggregate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"internalType\":\"structMulticall3.Result[]\",\"name\":\"returnData\",\"type\":\"tuple[]\"}],\"stateMutability\":\"payable\",\"type\":\"function\"}]", + Bin: "0x6080604052348015600f57600080fd5b50610cd88061001f6000396000f3fe6080604052600436106100f35760003560e01c80634d2301cc1161008a578063a8b0574e11610059578063a8b0574e1461022f578063bce38bd71461024a578063c3077fa91461025d578063ee82ac5e1461027057600080fd5b80634d2301cc146101ce57806372425d9d146101f657806382ad56cb1461020957806386d516e81461021c57600080fd5b80633408e470116100c65780633408e47014610173578063399542e9146101865780633e64a696146101a857806342cbb15c146101bb57600080fd5b80630f28c97d146100f8578063174dea711461011a578063252dba421461013a57806327e86d6e1461015b575b600080fd5b34801561010457600080fd5b50425b6040519081526020015b60405180910390f35b61012d61012836600461098c565b61028f565b6040516101119190610a89565b61014d61014836600461098c565b61047d565b604051610111929190610aa3565b34801561016757600080fd5b50436000190140610107565b34801561017f57600080fd5b5046610107565b610199610194366004610b0f565b6105f1565b60405161011193929190610b69565b3480156101b457600080fd5b5048610107565b3480156101c757600080fd5b5043610107565b3480156101da57600080fd5b506101076101e9366004610b91565b6001600160a01b03163190565b34801561020257600080fd5b5044610107565b61012d61021736600461098c565b61060c565b34801561022857600080fd5b5045610107565b34801561023b57600080fd5b50604051418152602001610111565b61012d610258366004610b0f565b61078e565b61019961026b36600461098c565b610921565b34801561027c57600080fd5b5061010761028b366004610bba565b4090565b60606000828067ffffffffffffffff8111156102ad576102ad610bd3565b6040519080825280602002602001820160405280156102f357816020015b6040805180820190915260008152606060208201528152602001906001900390816102cb5790505b5092503660005b8281101561041f57600085828151811061031657610316610be9565b6020026020010151905087878381811061033257610332610be9565b90506020028101906103449190610bff565b60408101359586019590935061035d6020850185610b91565b6001600160a01b0316816103746060870187610c1f565b604051610382929190610c66565b60006040518083038185875af1925050503d80600081146103bf576040519150601f19603f3d011682016040523d82523d6000602084013e6103c4565b606091505b5060208085019190915290151580845290850135176104155762461bcd60e51b6000526020600452601760245276135d5b1d1a58d85b1b0cce8818d85b1b0819985a5b1959604a1b60445260846000fd5b50506001016102fa565b508234146104745760405162461bcd60e51b815260206004820152601a60248201527f4d756c746963616c6c333a2076616c7565206d69736d6174636800000000000060448201526064015b60405180910390fd5b50505092915050565b436060828067ffffffffffffffff81111561049a5761049a610bd3565b6040519080825280602002602001820160405280156104cd57816020015b60608152602001906001900390816104b85790505b5091503660005b828110156105e75760008787838181106104f0576104f0610be9565b90506020028101906105029190610c76565b92506105116020840184610b91565b6001600160a01b03166105276020850185610c1f565b604051610535929190610c66565b6000604051808303816000865af19150503d8060008114610572576040519150601f19603f3d011682016040523d82523d6000602084013e610577565b606091505b5086848151811061058a5761058a610be9565b60209081029190910101529050806105de5760405162461bcd60e51b8152602060048201526017602482015276135d5b1d1a58d85b1b0cce8818d85b1b0819985a5b1959604a1b604482015260640161046b565b506001016104d4565b5050509250929050565b438040606061060186868661078e565b905093509350939050565b6060818067ffffffffffffffff81111561062857610628610bd3565b60405190808252806020026020018201604052801561066e57816020015b6040805180820190915260008152606060208201528152602001906001900390816106465790505b5091503660005b8281101561047457600084828151811061069157610691610be9565b602002602001015190508686838181106106ad576106ad610be9565b90506020028101906106bf9190610c8c565b92506106ce6020840184610b91565b6001600160a01b03166106e46040850185610c1f565b6040516106f2929190610c66565b6000604051808303816000865af19150503d806000811461072f576040519150601f19603f3d011682016040523d82523d6000602084013e610734565b606091505b5060208084019190915290151580835290840135176107855762461bcd60e51b6000526020600452601760245276135d5b1d1a58d85b1b0cce8818d85b1b0819985a5b1959604a1b60445260646000fd5b50600101610675565b6060818067ffffffffffffffff8111156107aa576107aa610bd3565b6040519080825280602002602001820160405280156107f057816020015b6040805180820190915260008152606060208201528152602001906001900390816107c85790505b5091503660005b8281101561091757600084828151811061081357610813610be9565b6020026020010151905086868381811061082f5761082f610be9565b90506020028101906108419190610c76565b92506108506020840184610b91565b6001600160a01b03166108666020850185610c1f565b604051610874929190610c66565b6000604051808303816000865af19150503d80600081146108b1576040519150601f19603f3d011682016040523d82523d6000602084013e6108b6565b606091505b50602083015215158152871561090e57805161090e5760405162461bcd60e51b8152602060048201526017602482015276135d5b1d1a58d85b1b0cce8818d85b1b0819985a5b1959604a1b604482015260640161046b565b506001016107f7565b5050509392505050565b6000806060610932600186866105f1565b919790965090945092505050565b60008083601f84011261095257600080fd5b50813567ffffffffffffffff81111561096a57600080fd5b6020830191508360208260051b850101111561098557600080fd5b9250929050565b6000806020838503121561099f57600080fd5b823567ffffffffffffffff8111156109b657600080fd5b6109c285828601610940565b90969095509350505050565b6000815180845260005b818110156109f4576020818501810151868301820152016109d8565b506000602082860101526020601f19601f83011685010191505092915050565b600082825180855260208501945060208160051b8301016020850160005b83811015610a7d57601f1985840301885281518051151584526020810151905060406020850152610a6660408501826109ce565b6020998a0199909450929092019150600101610a32565b50909695505050505050565b602081526000610a9c6020830184610a14565b9392505050565b6000604082018483526040602084015280845180835260608501915060608160051b86010192506020860160005b82811015610b0257605f19878603018452610aed8583516109ce565b94506020938401939190910190600101610ad1565b5092979650505050505050565b600080600060408486031215610b2457600080fd5b83358015158114610b3457600080fd5b9250602084013567ffffffffffffffff811115610b5057600080fd5b610b5c86828701610940565b9497909650939450505050565b838152826020820152606060408201526000610b886060830184610a14565b95945050505050565b600060208284031215610ba357600080fd5b81356001600160a01b0381168114610a9c57600080fd5b600060208284031215610bcc57600080fd5b5035919050565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b60008235607e19833603018112610c1557600080fd5b9190910192915050565b6000808335601e19843603018112610c3657600080fd5b83018035915067ffffffffffffffff821115610c5157600080fd5b60200191503681900382131561098557600080fd5b8183823760009101908152919050565b60008235603e19833603018112610c1557600080fd5b60008235605e19833603018112610c1557600080fdfea2646970667358221220b68503dc0ac20ad5ddfa89a54f47d7c1052291793ed559cb82213962478f7d7364736f6c634300081b0033", +} + +// MulticallABI is the input ABI used to generate the binding from. +// Deprecated: Use MulticallMetaData.ABI instead. +var MulticallABI = MulticallMetaData.ABI + +// MulticallBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use MulticallMetaData.Bin instead. +var MulticallBin = MulticallMetaData.Bin + +// DeployMulticall deploys a new Ethereum contract, binding an instance of Multicall to it. +func DeployMulticall(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Multicall, error) { + parsed, err := MulticallMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(MulticallBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Multicall{MulticallCaller: MulticallCaller{contract: contract}, MulticallTransactor: MulticallTransactor{contract: contract}, MulticallFilterer: MulticallFilterer{contract: contract}}, nil +} + +// Multicall is an auto generated Go binding around an Ethereum contract. +type Multicall struct { + MulticallCaller // Read-only binding to the contract + MulticallTransactor // Write-only binding to the contract + MulticallFilterer // Log filterer for contract events +} + +// MulticallCaller is an auto generated read-only Go binding around an Ethereum contract. +type MulticallCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// MulticallTransactor is an auto generated write-only Go binding around an Ethereum contract. +type MulticallTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// MulticallFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type MulticallFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// MulticallSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type MulticallSession struct { + Contract *Multicall // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// MulticallCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type MulticallCallerSession struct { + Contract *MulticallCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// MulticallTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type MulticallTransactorSession struct { + Contract *MulticallTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// MulticallRaw is an auto generated low-level Go binding around an Ethereum contract. +type MulticallRaw struct { + Contract *Multicall // Generic contract binding to access the raw methods on +} + +// MulticallCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type MulticallCallerRaw struct { + Contract *MulticallCaller // Generic read-only contract binding to access the raw methods on +} + +// MulticallTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type MulticallTransactorRaw struct { + Contract *MulticallTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewMulticall creates a new instance of Multicall, bound to a specific deployed contract. +func NewMulticall(address common.Address, backend bind.ContractBackend) (*Multicall, error) { + contract, err := bindMulticall(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Multicall{MulticallCaller: MulticallCaller{contract: contract}, MulticallTransactor: MulticallTransactor{contract: contract}, MulticallFilterer: MulticallFilterer{contract: contract}}, nil +} + +// NewMulticallCaller creates a new read-only instance of Multicall, bound to a specific deployed contract. +func NewMulticallCaller(address common.Address, caller bind.ContractCaller) (*MulticallCaller, error) { + contract, err := bindMulticall(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &MulticallCaller{contract: contract}, nil +} + +// NewMulticallTransactor creates a new write-only instance of Multicall, bound to a specific deployed contract. +func NewMulticallTransactor(address common.Address, transactor bind.ContractTransactor) (*MulticallTransactor, error) { + contract, err := bindMulticall(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &MulticallTransactor{contract: contract}, nil +} + +// NewMulticallFilterer creates a new log filterer instance of Multicall, bound to a specific deployed contract. +func NewMulticallFilterer(address common.Address, filterer bind.ContractFilterer) (*MulticallFilterer, error) { + contract, err := bindMulticall(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &MulticallFilterer{contract: contract}, nil +} + +// bindMulticall binds a generic wrapper to an already deployed contract. +func bindMulticall(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := MulticallMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Multicall *MulticallRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Multicall.Contract.MulticallCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Multicall *MulticallRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Multicall.Contract.MulticallTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Multicall *MulticallRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Multicall.Contract.MulticallTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Multicall *MulticallCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Multicall.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Multicall *MulticallTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Multicall.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Multicall *MulticallTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Multicall.Contract.contract.Transact(opts, method, params...) +} + +// GetBasefee is a free data retrieval call binding the contract method 0x3e64a696. +// +// Solidity: function getBasefee() view returns(uint256 basefee) +func (_Multicall *MulticallCaller) GetBasefee(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Multicall.contract.Call(opts, &out, "getBasefee") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetBasefee is a free data retrieval call binding the contract method 0x3e64a696. +// +// Solidity: function getBasefee() view returns(uint256 basefee) +func (_Multicall *MulticallSession) GetBasefee() (*big.Int, error) { + return _Multicall.Contract.GetBasefee(&_Multicall.CallOpts) +} + +// GetBasefee is a free data retrieval call binding the contract method 0x3e64a696. +// +// Solidity: function getBasefee() view returns(uint256 basefee) +func (_Multicall *MulticallCallerSession) GetBasefee() (*big.Int, error) { + return _Multicall.Contract.GetBasefee(&_Multicall.CallOpts) +} + +// GetBlockHash is a free data retrieval call binding the contract method 0xee82ac5e. +// +// Solidity: function getBlockHash(uint256 blockNumber) view returns(bytes32 blockHash) +func (_Multicall *MulticallCaller) GetBlockHash(opts *bind.CallOpts, blockNumber *big.Int) ([32]byte, error) { + var out []interface{} + err := _Multicall.contract.Call(opts, &out, "getBlockHash", blockNumber) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetBlockHash is a free data retrieval call binding the contract method 0xee82ac5e. +// +// Solidity: function getBlockHash(uint256 blockNumber) view returns(bytes32 blockHash) +func (_Multicall *MulticallSession) GetBlockHash(blockNumber *big.Int) ([32]byte, error) { + return _Multicall.Contract.GetBlockHash(&_Multicall.CallOpts, blockNumber) +} + +// GetBlockHash is a free data retrieval call binding the contract method 0xee82ac5e. +// +// Solidity: function getBlockHash(uint256 blockNumber) view returns(bytes32 blockHash) +func (_Multicall *MulticallCallerSession) GetBlockHash(blockNumber *big.Int) ([32]byte, error) { + return _Multicall.Contract.GetBlockHash(&_Multicall.CallOpts, blockNumber) +} + +// GetBlockNumber is a free data retrieval call binding the contract method 0x42cbb15c. +// +// Solidity: function getBlockNumber() view returns(uint256 blockNumber) +func (_Multicall *MulticallCaller) GetBlockNumber(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Multicall.contract.Call(opts, &out, "getBlockNumber") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetBlockNumber is a free data retrieval call binding the contract method 0x42cbb15c. +// +// Solidity: function getBlockNumber() view returns(uint256 blockNumber) +func (_Multicall *MulticallSession) GetBlockNumber() (*big.Int, error) { + return _Multicall.Contract.GetBlockNumber(&_Multicall.CallOpts) +} + +// GetBlockNumber is a free data retrieval call binding the contract method 0x42cbb15c. +// +// Solidity: function getBlockNumber() view returns(uint256 blockNumber) +func (_Multicall *MulticallCallerSession) GetBlockNumber() (*big.Int, error) { + return _Multicall.Contract.GetBlockNumber(&_Multicall.CallOpts) +} + +// GetChainId is a free data retrieval call binding the contract method 0x3408e470. +// +// Solidity: function getChainId() view returns(uint256 chainid) +func (_Multicall *MulticallCaller) GetChainId(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Multicall.contract.Call(opts, &out, "getChainId") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetChainId is a free data retrieval call binding the contract method 0x3408e470. +// +// Solidity: function getChainId() view returns(uint256 chainid) +func (_Multicall *MulticallSession) GetChainId() (*big.Int, error) { + return _Multicall.Contract.GetChainId(&_Multicall.CallOpts) +} + +// GetChainId is a free data retrieval call binding the contract method 0x3408e470. +// +// Solidity: function getChainId() view returns(uint256 chainid) +func (_Multicall *MulticallCallerSession) GetChainId() (*big.Int, error) { + return _Multicall.Contract.GetChainId(&_Multicall.CallOpts) +} + +// GetCurrentBlockCoinbase is a free data retrieval call binding the contract method 0xa8b0574e. +// +// Solidity: function getCurrentBlockCoinbase() view returns(address coinbase) +func (_Multicall *MulticallCaller) GetCurrentBlockCoinbase(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Multicall.contract.Call(opts, &out, "getCurrentBlockCoinbase") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GetCurrentBlockCoinbase is a free data retrieval call binding the contract method 0xa8b0574e. +// +// Solidity: function getCurrentBlockCoinbase() view returns(address coinbase) +func (_Multicall *MulticallSession) GetCurrentBlockCoinbase() (common.Address, error) { + return _Multicall.Contract.GetCurrentBlockCoinbase(&_Multicall.CallOpts) +} + +// GetCurrentBlockCoinbase is a free data retrieval call binding the contract method 0xa8b0574e. +// +// Solidity: function getCurrentBlockCoinbase() view returns(address coinbase) +func (_Multicall *MulticallCallerSession) GetCurrentBlockCoinbase() (common.Address, error) { + return _Multicall.Contract.GetCurrentBlockCoinbase(&_Multicall.CallOpts) +} + +// GetCurrentBlockDifficulty is a free data retrieval call binding the contract method 0x72425d9d. +// +// Solidity: function getCurrentBlockDifficulty() view returns(uint256 difficulty) +func (_Multicall *MulticallCaller) GetCurrentBlockDifficulty(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Multicall.contract.Call(opts, &out, "getCurrentBlockDifficulty") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetCurrentBlockDifficulty is a free data retrieval call binding the contract method 0x72425d9d. +// +// Solidity: function getCurrentBlockDifficulty() view returns(uint256 difficulty) +func (_Multicall *MulticallSession) GetCurrentBlockDifficulty() (*big.Int, error) { + return _Multicall.Contract.GetCurrentBlockDifficulty(&_Multicall.CallOpts) +} + +// GetCurrentBlockDifficulty is a free data retrieval call binding the contract method 0x72425d9d. +// +// Solidity: function getCurrentBlockDifficulty() view returns(uint256 difficulty) +func (_Multicall *MulticallCallerSession) GetCurrentBlockDifficulty() (*big.Int, error) { + return _Multicall.Contract.GetCurrentBlockDifficulty(&_Multicall.CallOpts) +} + +// GetCurrentBlockGasLimit is a free data retrieval call binding the contract method 0x86d516e8. +// +// Solidity: function getCurrentBlockGasLimit() view returns(uint256 gaslimit) +func (_Multicall *MulticallCaller) GetCurrentBlockGasLimit(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Multicall.contract.Call(opts, &out, "getCurrentBlockGasLimit") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetCurrentBlockGasLimit is a free data retrieval call binding the contract method 0x86d516e8. +// +// Solidity: function getCurrentBlockGasLimit() view returns(uint256 gaslimit) +func (_Multicall *MulticallSession) GetCurrentBlockGasLimit() (*big.Int, error) { + return _Multicall.Contract.GetCurrentBlockGasLimit(&_Multicall.CallOpts) +} + +// GetCurrentBlockGasLimit is a free data retrieval call binding the contract method 0x86d516e8. +// +// Solidity: function getCurrentBlockGasLimit() view returns(uint256 gaslimit) +func (_Multicall *MulticallCallerSession) GetCurrentBlockGasLimit() (*big.Int, error) { + return _Multicall.Contract.GetCurrentBlockGasLimit(&_Multicall.CallOpts) +} + +// GetCurrentBlockTimestamp is a free data retrieval call binding the contract method 0x0f28c97d. +// +// Solidity: function getCurrentBlockTimestamp() view returns(uint256 timestamp) +func (_Multicall *MulticallCaller) GetCurrentBlockTimestamp(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Multicall.contract.Call(opts, &out, "getCurrentBlockTimestamp") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetCurrentBlockTimestamp is a free data retrieval call binding the contract method 0x0f28c97d. +// +// Solidity: function getCurrentBlockTimestamp() view returns(uint256 timestamp) +func (_Multicall *MulticallSession) GetCurrentBlockTimestamp() (*big.Int, error) { + return _Multicall.Contract.GetCurrentBlockTimestamp(&_Multicall.CallOpts) +} + +// GetCurrentBlockTimestamp is a free data retrieval call binding the contract method 0x0f28c97d. +// +// Solidity: function getCurrentBlockTimestamp() view returns(uint256 timestamp) +func (_Multicall *MulticallCallerSession) GetCurrentBlockTimestamp() (*big.Int, error) { + return _Multicall.Contract.GetCurrentBlockTimestamp(&_Multicall.CallOpts) +} + +// GetEthBalance is a free data retrieval call binding the contract method 0x4d2301cc. +// +// Solidity: function getEthBalance(address addr) view returns(uint256 balance) +func (_Multicall *MulticallCaller) GetEthBalance(opts *bind.CallOpts, addr common.Address) (*big.Int, error) { + var out []interface{} + err := _Multicall.contract.Call(opts, &out, "getEthBalance", addr) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// GetEthBalance is a free data retrieval call binding the contract method 0x4d2301cc. +// +// Solidity: function getEthBalance(address addr) view returns(uint256 balance) +func (_Multicall *MulticallSession) GetEthBalance(addr common.Address) (*big.Int, error) { + return _Multicall.Contract.GetEthBalance(&_Multicall.CallOpts, addr) +} + +// GetEthBalance is a free data retrieval call binding the contract method 0x4d2301cc. +// +// Solidity: function getEthBalance(address addr) view returns(uint256 balance) +func (_Multicall *MulticallCallerSession) GetEthBalance(addr common.Address) (*big.Int, error) { + return _Multicall.Contract.GetEthBalance(&_Multicall.CallOpts, addr) +} + +// GetLastBlockHash is a free data retrieval call binding the contract method 0x27e86d6e. +// +// Solidity: function getLastBlockHash() view returns(bytes32 blockHash) +func (_Multicall *MulticallCaller) GetLastBlockHash(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _Multicall.contract.Call(opts, &out, "getLastBlockHash") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// GetLastBlockHash is a free data retrieval call binding the contract method 0x27e86d6e. +// +// Solidity: function getLastBlockHash() view returns(bytes32 blockHash) +func (_Multicall *MulticallSession) GetLastBlockHash() ([32]byte, error) { + return _Multicall.Contract.GetLastBlockHash(&_Multicall.CallOpts) +} + +// GetLastBlockHash is a free data retrieval call binding the contract method 0x27e86d6e. +// +// Solidity: function getLastBlockHash() view returns(bytes32 blockHash) +func (_Multicall *MulticallCallerSession) GetLastBlockHash() ([32]byte, error) { + return _Multicall.Contract.GetLastBlockHash(&_Multicall.CallOpts) +} + +// Aggregate is a paid mutator transaction binding the contract method 0x252dba42. +// +// Solidity: function aggregate((address,bytes)[] calls) payable returns(uint256 blockNumber, bytes[] returnData) +func (_Multicall *MulticallTransactor) Aggregate(opts *bind.TransactOpts, calls []Multicall3Call) (*types.Transaction, error) { + return _Multicall.contract.Transact(opts, "aggregate", calls) +} + +// Aggregate is a paid mutator transaction binding the contract method 0x252dba42. +// +// Solidity: function aggregate((address,bytes)[] calls) payable returns(uint256 blockNumber, bytes[] returnData) +func (_Multicall *MulticallSession) Aggregate(calls []Multicall3Call) (*types.Transaction, error) { + return _Multicall.Contract.Aggregate(&_Multicall.TransactOpts, calls) +} + +// Aggregate is a paid mutator transaction binding the contract method 0x252dba42. +// +// Solidity: function aggregate((address,bytes)[] calls) payable returns(uint256 blockNumber, bytes[] returnData) +func (_Multicall *MulticallTransactorSession) Aggregate(calls []Multicall3Call) (*types.Transaction, error) { + return _Multicall.Contract.Aggregate(&_Multicall.TransactOpts, calls) +} + +// Aggregate3 is a paid mutator transaction binding the contract method 0x82ad56cb. +// +// Solidity: function aggregate3((address,bool,bytes)[] calls) payable returns((bool,bytes)[] returnData) +func (_Multicall *MulticallTransactor) Aggregate3(opts *bind.TransactOpts, calls []Multicall3Call3) (*types.Transaction, error) { + return _Multicall.contract.Transact(opts, "aggregate3", calls) +} + +// Aggregate3 is a paid mutator transaction binding the contract method 0x82ad56cb. +// +// Solidity: function aggregate3((address,bool,bytes)[] calls) payable returns((bool,bytes)[] returnData) +func (_Multicall *MulticallSession) Aggregate3(calls []Multicall3Call3) (*types.Transaction, error) { + return _Multicall.Contract.Aggregate3(&_Multicall.TransactOpts, calls) +} + +// Aggregate3 is a paid mutator transaction binding the contract method 0x82ad56cb. +// +// Solidity: function aggregate3((address,bool,bytes)[] calls) payable returns((bool,bytes)[] returnData) +func (_Multicall *MulticallTransactorSession) Aggregate3(calls []Multicall3Call3) (*types.Transaction, error) { + return _Multicall.Contract.Aggregate3(&_Multicall.TransactOpts, calls) +} + +// Aggregate3Value is a paid mutator transaction binding the contract method 0x174dea71. +// +// Solidity: function aggregate3Value((address,bool,uint256,bytes)[] calls) payable returns((bool,bytes)[] returnData) +func (_Multicall *MulticallTransactor) Aggregate3Value(opts *bind.TransactOpts, calls []Multicall3Call3Value) (*types.Transaction, error) { + return _Multicall.contract.Transact(opts, "aggregate3Value", calls) +} + +// Aggregate3Value is a paid mutator transaction binding the contract method 0x174dea71. +// +// Solidity: function aggregate3Value((address,bool,uint256,bytes)[] calls) payable returns((bool,bytes)[] returnData) +func (_Multicall *MulticallSession) Aggregate3Value(calls []Multicall3Call3Value) (*types.Transaction, error) { + return _Multicall.Contract.Aggregate3Value(&_Multicall.TransactOpts, calls) +} + +// Aggregate3Value is a paid mutator transaction binding the contract method 0x174dea71. +// +// Solidity: function aggregate3Value((address,bool,uint256,bytes)[] calls) payable returns((bool,bytes)[] returnData) +func (_Multicall *MulticallTransactorSession) Aggregate3Value(calls []Multicall3Call3Value) (*types.Transaction, error) { + return _Multicall.Contract.Aggregate3Value(&_Multicall.TransactOpts, calls) +} + +// BlockAndAggregate is a paid mutator transaction binding the contract method 0xc3077fa9. +// +// Solidity: function blockAndAggregate((address,bytes)[] calls) payable returns(uint256 blockNumber, bytes32 blockHash, (bool,bytes)[] returnData) +func (_Multicall *MulticallTransactor) BlockAndAggregate(opts *bind.TransactOpts, calls []Multicall3Call) (*types.Transaction, error) { + return _Multicall.contract.Transact(opts, "blockAndAggregate", calls) +} + +// BlockAndAggregate is a paid mutator transaction binding the contract method 0xc3077fa9. +// +// Solidity: function blockAndAggregate((address,bytes)[] calls) payable returns(uint256 blockNumber, bytes32 blockHash, (bool,bytes)[] returnData) +func (_Multicall *MulticallSession) BlockAndAggregate(calls []Multicall3Call) (*types.Transaction, error) { + return _Multicall.Contract.BlockAndAggregate(&_Multicall.TransactOpts, calls) +} + +// BlockAndAggregate is a paid mutator transaction binding the contract method 0xc3077fa9. +// +// Solidity: function blockAndAggregate((address,bytes)[] calls) payable returns(uint256 blockNumber, bytes32 blockHash, (bool,bytes)[] returnData) +func (_Multicall *MulticallTransactorSession) BlockAndAggregate(calls []Multicall3Call) (*types.Transaction, error) { + return _Multicall.Contract.BlockAndAggregate(&_Multicall.TransactOpts, calls) +} + +// TryAggregate is a paid mutator transaction binding the contract method 0xbce38bd7. +// +// Solidity: function tryAggregate(bool requireSuccess, (address,bytes)[] calls) payable returns((bool,bytes)[] returnData) +func (_Multicall *MulticallTransactor) TryAggregate(opts *bind.TransactOpts, requireSuccess bool, calls []Multicall3Call) (*types.Transaction, error) { + return _Multicall.contract.Transact(opts, "tryAggregate", requireSuccess, calls) +} + +// TryAggregate is a paid mutator transaction binding the contract method 0xbce38bd7. +// +// Solidity: function tryAggregate(bool requireSuccess, (address,bytes)[] calls) payable returns((bool,bytes)[] returnData) +func (_Multicall *MulticallSession) TryAggregate(requireSuccess bool, calls []Multicall3Call) (*types.Transaction, error) { + return _Multicall.Contract.TryAggregate(&_Multicall.TransactOpts, requireSuccess, calls) +} + +// TryAggregate is a paid mutator transaction binding the contract method 0xbce38bd7. +// +// Solidity: function tryAggregate(bool requireSuccess, (address,bytes)[] calls) payable returns((bool,bytes)[] returnData) +func (_Multicall *MulticallTransactorSession) TryAggregate(requireSuccess bool, calls []Multicall3Call) (*types.Transaction, error) { + return _Multicall.Contract.TryAggregate(&_Multicall.TransactOpts, requireSuccess, calls) +} + +// TryBlockAndAggregate is a paid mutator transaction binding the contract method 0x399542e9. +// +// Solidity: function tryBlockAndAggregate(bool requireSuccess, (address,bytes)[] calls) payable returns(uint256 blockNumber, bytes32 blockHash, (bool,bytes)[] returnData) +func (_Multicall *MulticallTransactor) TryBlockAndAggregate(opts *bind.TransactOpts, requireSuccess bool, calls []Multicall3Call) (*types.Transaction, error) { + return _Multicall.contract.Transact(opts, "tryBlockAndAggregate", requireSuccess, calls) +} + +// TryBlockAndAggregate is a paid mutator transaction binding the contract method 0x399542e9. +// +// Solidity: function tryBlockAndAggregate(bool requireSuccess, (address,bytes)[] calls) payable returns(uint256 blockNumber, bytes32 blockHash, (bool,bytes)[] returnData) +func (_Multicall *MulticallSession) TryBlockAndAggregate(requireSuccess bool, calls []Multicall3Call) (*types.Transaction, error) { + return _Multicall.Contract.TryBlockAndAggregate(&_Multicall.TransactOpts, requireSuccess, calls) +} + +// TryBlockAndAggregate is a paid mutator transaction binding the contract method 0x399542e9. +// +// Solidity: function tryBlockAndAggregate(bool requireSuccess, (address,bytes)[] calls) payable returns(uint256 blockNumber, bytes32 blockHash, (bool,bytes)[] returnData) +func (_Multicall *MulticallTransactorSession) TryBlockAndAggregate(requireSuccess bool, calls []Multicall3Call) (*types.Transaction, error) { + return _Multicall.Contract.TryBlockAndAggregate(&_Multicall.TransactOpts, requireSuccess, calls) +} diff --git a/backend/internal/contracts/token.go b/backend/internal/contracts/token.go new file mode 100644 index 000000000..559205c90 --- /dev/null +++ b/backend/internal/contracts/token.go @@ -0,0 +1,781 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package contracts + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// TokenMetaData contains all meta data concerning the Token contract. +var TokenMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"name_\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"symbol_\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"allowance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientAllowance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"needed\",\"type\":\"uint256\"}],\"name\":\"ERC20InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"approver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidApprover\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"}],\"name\":\"ERC20InvalidReceiver\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"ERC20InvalidSpender\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x608060405234801561001057600080fd5b50604051610a51380380610a5183398101604081905261002f9161010d565b8181600361003d83826101ff565b50600461004a82826101ff565b50505050506102bd565b634e487b7160e01b600052604160045260246000fd5b600082601f83011261007b57600080fd5b81516001600160401b0381111561009457610094610054565b604051601f8201601f19908116603f011681016001600160401b03811182821017156100c2576100c2610054565b6040528181528382016020018510156100da57600080fd5b60005b828110156100f9576020818601810151838301820152016100dd565b506000918101602001919091529392505050565b6000806040838503121561012057600080fd5b82516001600160401b0381111561013657600080fd5b6101428582860161006a565b602085015190935090506001600160401b0381111561016057600080fd5b61016c8582860161006a565b9150509250929050565b600181811c9082168061018a57607f821691505b6020821081036101aa57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156101fa57806000526020600020601f840160051c810160208510156101d75750805b601f840160051c820191505b818110156101f757600081556001016101e3565b50505b505050565b81516001600160401b0381111561021857610218610054565b61022c816102268454610176565b846101b0565b6020601f82116001811461026057600083156102485750848201515b600019600385901b1c1916600184901b1784556101f7565b600084815260208120601f198516915b828110156102905787850151825560209485019460019092019101610270565b50848210156102ae5786840151600019600387901b60f8161c191681555b50505050600190811b01905550565b610785806102cc6000396000f3fe608060405234801561001057600080fd5b506004361061009e5760003560e01c806340c10f191161006657806340c10f191461011857806370a082311461012d57806395d89b4114610156578063a9059cbb1461015e578063dd62ed3e1461017157600080fd5b806306fdde03146100a3578063095ea7b3146100c157806318160ddd146100e457806323b872dd146100f6578063313ce56714610109575b600080fd5b6100ab6101aa565b6040516100b891906105ce565b60405180910390f35b6100d46100cf366004610638565b61023c565b60405190151581526020016100b8565b6002545b6040519081526020016100b8565b6100d4610104366004610662565b610256565b604051601281526020016100b8565b61012b610126366004610638565b61027a565b005b6100e861013b36600461069f565b6001600160a01b031660009081526020819052604090205490565b6100ab610288565b6100d461016c366004610638565b610297565b6100e861017f3660046106c1565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6060600380546101b9906106f4565b80601f01602080910402602001604051908101604052809291908181526020018280546101e5906106f4565b80156102325780601f1061020757610100808354040283529160200191610232565b820191906000526020600020905b81548152906001019060200180831161021557829003601f168201915b5050505050905090565b60003361024a8185856102a5565b60019150505b92915050565b6000336102648582856102b7565b61026f85858561033a565b506001949350505050565b6102848282610399565b5050565b6060600480546101b9906106f4565b60003361024a81858561033a565b6102b283838360016103cf565b505050565b6001600160a01b038381166000908152600160209081526040808320938616835292905220546000198114610334578181101561032557604051637dc7a0d960e11b81526001600160a01b038416600482015260248101829052604481018390526064015b60405180910390fd5b610334848484840360006103cf565b50505050565b6001600160a01b03831661036457604051634b637e8f60e11b81526000600482015260240161031c565b6001600160a01b03821661038e5760405163ec442f0560e01b81526000600482015260240161031c565b6102b28383836104a4565b6001600160a01b0382166103c35760405163ec442f0560e01b81526000600482015260240161031c565b610284600083836104a4565b6001600160a01b0384166103f95760405163e602df0560e01b81526000600482015260240161031c565b6001600160a01b03831661042357604051634a1406b160e11b81526000600482015260240161031c565b6001600160a01b038085166000908152600160209081526040808320938716835292905220829055801561033457826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258460405161049691815260200190565b60405180910390a350505050565b6001600160a01b0383166104cf5780600260008282546104c4919061072e565b909155506105419050565b6001600160a01b038316600090815260208190526040902054818110156105225760405163391434e360e21b81526001600160a01b0385166004820152602481018290526044810183905260640161031c565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b03821661055d5760028054829003905561057c565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516105c191815260200190565b60405180910390a3505050565b602081526000825180602084015260005b818110156105fc57602081860181015160408684010152016105df565b506000604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b038116811461063357600080fd5b919050565b6000806040838503121561064b57600080fd5b6106548361061c565b946020939093013593505050565b60008060006060848603121561067757600080fd5b6106808461061c565b925061068e6020850161061c565b929592945050506040919091013590565b6000602082840312156106b157600080fd5b6106ba8261061c565b9392505050565b600080604083850312156106d457600080fd5b6106dd8361061c565b91506106eb6020840161061c565b90509250929050565b600181811c9082168061070857607f821691505b60208210810361072857634e487b7160e01b600052602260045260246000fd5b50919050565b8082018082111561025057634e487b7160e01b600052601160045260246000fdfea2646970667358221220f70bc1a244241ba5852ffed0bb824df84a979af391f1f5c96cad02e666c8071464736f6c634300081b0033", +} + +// TokenABI is the input ABI used to generate the binding from. +// Deprecated: Use TokenMetaData.ABI instead. +var TokenABI = TokenMetaData.ABI + +// TokenBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use TokenMetaData.Bin instead. +var TokenBin = TokenMetaData.Bin + +// DeployToken deploys a new Ethereum contract, binding an instance of Token to it. +func DeployToken(auth *bind.TransactOpts, backend bind.ContractBackend, name_ string, symbol_ string) (common.Address, *types.Transaction, *Token, error) { + parsed, err := TokenMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(TokenBin), backend, name_, symbol_) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Token{TokenCaller: TokenCaller{contract: contract}, TokenTransactor: TokenTransactor{contract: contract}, TokenFilterer: TokenFilterer{contract: contract}}, nil +} + +// Token is an auto generated Go binding around an Ethereum contract. +type Token struct { + TokenCaller // Read-only binding to the contract + TokenTransactor // Write-only binding to the contract + TokenFilterer // Log filterer for contract events +} + +// TokenCaller is an auto generated read-only Go binding around an Ethereum contract. +type TokenCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TokenTransactor is an auto generated write-only Go binding around an Ethereum contract. +type TokenTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TokenFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type TokenFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// TokenSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type TokenSession struct { + Contract *Token // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TokenCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type TokenCallerSession struct { + Contract *TokenCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// TokenTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type TokenTransactorSession struct { + Contract *TokenTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// TokenRaw is an auto generated low-level Go binding around an Ethereum contract. +type TokenRaw struct { + Contract *Token // Generic contract binding to access the raw methods on +} + +// TokenCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type TokenCallerRaw struct { + Contract *TokenCaller // Generic read-only contract binding to access the raw methods on +} + +// TokenTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type TokenTransactorRaw struct { + Contract *TokenTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewToken creates a new instance of Token, bound to a specific deployed contract. +func NewToken(address common.Address, backend bind.ContractBackend) (*Token, error) { + contract, err := bindToken(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Token{TokenCaller: TokenCaller{contract: contract}, TokenTransactor: TokenTransactor{contract: contract}, TokenFilterer: TokenFilterer{contract: contract}}, nil +} + +// NewTokenCaller creates a new read-only instance of Token, bound to a specific deployed contract. +func NewTokenCaller(address common.Address, caller bind.ContractCaller) (*TokenCaller, error) { + contract, err := bindToken(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &TokenCaller{contract: contract}, nil +} + +// NewTokenTransactor creates a new write-only instance of Token, bound to a specific deployed contract. +func NewTokenTransactor(address common.Address, transactor bind.ContractTransactor) (*TokenTransactor, error) { + contract, err := bindToken(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &TokenTransactor{contract: contract}, nil +} + +// NewTokenFilterer creates a new log filterer instance of Token, bound to a specific deployed contract. +func NewTokenFilterer(address common.Address, filterer bind.ContractFilterer) (*TokenFilterer, error) { + contract, err := bindToken(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &TokenFilterer{contract: contract}, nil +} + +// bindToken binds a generic wrapper to an already deployed contract. +func bindToken(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := TokenMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Token *TokenRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Token.Contract.TokenCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Token *TokenRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Token.Contract.TokenTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Token *TokenRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Token.Contract.TokenTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Token *TokenCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Token.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Token *TokenTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Token.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Token *TokenTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Token.Contract.contract.Transact(opts, method, params...) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_Token *TokenCaller) Allowance(opts *bind.CallOpts, owner common.Address, spender common.Address) (*big.Int, error) { + var out []interface{} + err := _Token.contract.Call(opts, &out, "allowance", owner, spender) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_Token *TokenSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _Token.Contract.Allowance(&_Token.CallOpts, owner, spender) +} + +// Allowance is a free data retrieval call binding the contract method 0xdd62ed3e. +// +// Solidity: function allowance(address owner, address spender) view returns(uint256) +func (_Token *TokenCallerSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _Token.Contract.Allowance(&_Token.CallOpts, owner, spender) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_Token *TokenCaller) BalanceOf(opts *bind.CallOpts, account common.Address) (*big.Int, error) { + var out []interface{} + err := _Token.contract.Call(opts, &out, "balanceOf", account) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_Token *TokenSession) BalanceOf(account common.Address) (*big.Int, error) { + return _Token.Contract.BalanceOf(&_Token.CallOpts, account) +} + +// BalanceOf is a free data retrieval call binding the contract method 0x70a08231. +// +// Solidity: function balanceOf(address account) view returns(uint256) +func (_Token *TokenCallerSession) BalanceOf(account common.Address) (*big.Int, error) { + return _Token.Contract.BalanceOf(&_Token.CallOpts, account) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_Token *TokenCaller) Decimals(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _Token.contract.Call(opts, &out, "decimals") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_Token *TokenSession) Decimals() (uint8, error) { + return _Token.Contract.Decimals(&_Token.CallOpts) +} + +// Decimals is a free data retrieval call binding the contract method 0x313ce567. +// +// Solidity: function decimals() view returns(uint8) +func (_Token *TokenCallerSession) Decimals() (uint8, error) { + return _Token.Contract.Decimals(&_Token.CallOpts) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_Token *TokenCaller) Name(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _Token.contract.Call(opts, &out, "name") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_Token *TokenSession) Name() (string, error) { + return _Token.Contract.Name(&_Token.CallOpts) +} + +// Name is a free data retrieval call binding the contract method 0x06fdde03. +// +// Solidity: function name() view returns(string) +func (_Token *TokenCallerSession) Name() (string, error) { + return _Token.Contract.Name(&_Token.CallOpts) +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_Token *TokenCaller) Symbol(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _Token.contract.Call(opts, &out, "symbol") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_Token *TokenSession) Symbol() (string, error) { + return _Token.Contract.Symbol(&_Token.CallOpts) +} + +// Symbol is a free data retrieval call binding the contract method 0x95d89b41. +// +// Solidity: function symbol() view returns(string) +func (_Token *TokenCallerSession) Symbol() (string, error) { + return _Token.Contract.Symbol(&_Token.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_Token *TokenCaller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Token.contract.Call(opts, &out, "totalSupply") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_Token *TokenSession) TotalSupply() (*big.Int, error) { + return _Token.Contract.TotalSupply(&_Token.CallOpts) +} + +// TotalSupply is a free data retrieval call binding the contract method 0x18160ddd. +// +// Solidity: function totalSupply() view returns(uint256) +func (_Token *TokenCallerSession) TotalSupply() (*big.Int, error) { + return _Token.Contract.TotalSupply(&_Token.CallOpts) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 value) returns(bool) +func (_Token *TokenTransactor) Approve(opts *bind.TransactOpts, spender common.Address, value *big.Int) (*types.Transaction, error) { + return _Token.contract.Transact(opts, "approve", spender, value) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 value) returns(bool) +func (_Token *TokenSession) Approve(spender common.Address, value *big.Int) (*types.Transaction, error) { + return _Token.Contract.Approve(&_Token.TransactOpts, spender, value) +} + +// Approve is a paid mutator transaction binding the contract method 0x095ea7b3. +// +// Solidity: function approve(address spender, uint256 value) returns(bool) +func (_Token *TokenTransactorSession) Approve(spender common.Address, value *big.Int) (*types.Transaction, error) { + return _Token.Contract.Approve(&_Token.TransactOpts, spender, value) +} + +// Mint is a paid mutator transaction binding the contract method 0x40c10f19. +// +// Solidity: function mint(address account, uint256 value) returns() +func (_Token *TokenTransactor) Mint(opts *bind.TransactOpts, account common.Address, value *big.Int) (*types.Transaction, error) { + return _Token.contract.Transact(opts, "mint", account, value) +} + +// Mint is a paid mutator transaction binding the contract method 0x40c10f19. +// +// Solidity: function mint(address account, uint256 value) returns() +func (_Token *TokenSession) Mint(account common.Address, value *big.Int) (*types.Transaction, error) { + return _Token.Contract.Mint(&_Token.TransactOpts, account, value) +} + +// Mint is a paid mutator transaction binding the contract method 0x40c10f19. +// +// Solidity: function mint(address account, uint256 value) returns() +func (_Token *TokenTransactorSession) Mint(account common.Address, value *big.Int) (*types.Transaction, error) { + return _Token.Contract.Mint(&_Token.TransactOpts, account, value) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 value) returns(bool) +func (_Token *TokenTransactor) Transfer(opts *bind.TransactOpts, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Token.contract.Transact(opts, "transfer", to, value) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 value) returns(bool) +func (_Token *TokenSession) Transfer(to common.Address, value *big.Int) (*types.Transaction, error) { + return _Token.Contract.Transfer(&_Token.TransactOpts, to, value) +} + +// Transfer is a paid mutator transaction binding the contract method 0xa9059cbb. +// +// Solidity: function transfer(address to, uint256 value) returns(bool) +func (_Token *TokenTransactorSession) Transfer(to common.Address, value *big.Int) (*types.Transaction, error) { + return _Token.Contract.Transfer(&_Token.TransactOpts, to, value) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) +func (_Token *TokenTransactor) TransferFrom(opts *bind.TransactOpts, from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Token.contract.Transact(opts, "transferFrom", from, to, value) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) +func (_Token *TokenSession) TransferFrom(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Token.Contract.TransferFrom(&_Token.TransactOpts, from, to, value) +} + +// TransferFrom is a paid mutator transaction binding the contract method 0x23b872dd. +// +// Solidity: function transferFrom(address from, address to, uint256 value) returns(bool) +func (_Token *TokenTransactorSession) TransferFrom(from common.Address, to common.Address, value *big.Int) (*types.Transaction, error) { + return _Token.Contract.TransferFrom(&_Token.TransactOpts, from, to, value) +} + +// TokenApprovalIterator is returned from FilterApproval and is used to iterate over the raw logs and unpacked data for Approval events raised by the Token contract. +type TokenApprovalIterator struct { + Event *TokenApproval // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenApprovalIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenApproval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenApproval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenApprovalIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenApprovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenApproval represents a Approval event raised by the Token contract. +type TokenApproval struct { + Owner common.Address + Spender common.Address + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterApproval is a free log retrieval operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_Token *TokenFilterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*TokenApprovalIterator, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _Token.contract.FilterLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return &TokenApprovalIterator{contract: _Token.contract, event: "Approval", logs: logs, sub: sub}, nil +} + +// WatchApproval is a free log subscription operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_Token *TokenFilterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *TokenApproval, owner []common.Address, spender []common.Address) (event.Subscription, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var spenderRule []interface{} + for _, spenderItem := range spender { + spenderRule = append(spenderRule, spenderItem) + } + + logs, sub, err := _Token.contract.WatchLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenApproval) + if err := _Token.contract.UnpackLog(event, "Approval", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseApproval is a log parse operation binding the contract event 0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925. +// +// Solidity: event Approval(address indexed owner, address indexed spender, uint256 value) +func (_Token *TokenFilterer) ParseApproval(log types.Log) (*TokenApproval, error) { + event := new(TokenApproval) + if err := _Token.contract.UnpackLog(event, "Approval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// TokenTransferIterator is returned from FilterTransfer and is used to iterate over the raw logs and unpacked data for Transfer events raised by the Token contract. +type TokenTransferIterator struct { + Event *TokenTransfer // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *TokenTransferIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(TokenTransfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(TokenTransfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *TokenTransferIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *TokenTransferIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// TokenTransfer represents a Transfer event raised by the Token contract. +type TokenTransfer struct { + From common.Address + To common.Address + Value *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTransfer is a free log retrieval operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_Token *TokenFilterer) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*TokenTransferIterator, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _Token.contract.FilterLogs(opts, "Transfer", fromRule, toRule) + if err != nil { + return nil, err + } + return &TokenTransferIterator{contract: _Token.contract, event: "Transfer", logs: logs, sub: sub}, nil +} + +// WatchTransfer is a free log subscription operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_Token *TokenFilterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *TokenTransfer, from []common.Address, to []common.Address) (event.Subscription, error) { + + var fromRule []interface{} + for _, fromItem := range from { + fromRule = append(fromRule, fromItem) + } + var toRule []interface{} + for _, toItem := range to { + toRule = append(toRule, toItem) + } + + logs, sub, err := _Token.contract.WatchLogs(opts, "Transfer", fromRule, toRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(TokenTransfer) + if err := _Token.contract.UnpackLog(event, "Transfer", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseTransfer is a log parse operation binding the contract event 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef. +// +// Solidity: event Transfer(address indexed from, address indexed to, uint256 value) +func (_Token *TokenFilterer) ParseTransfer(log types.Log) (*TokenTransfer, error) { + event := new(TokenTransfer) + if err := _Token.contract.UnpackLog(event, "Transfer", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/backend/internal/th/ethereum.go b/backend/internal/th/ethereum.go new file mode 100644 index 000000000..10c9a7953 --- /dev/null +++ b/backend/internal/th/ethereum.go @@ -0,0 +1,224 @@ +package th + +import ( + "context" + "crypto/ecdsa" + "math/big" + "testing" + + "github.com/Tangui-Bitfly/ethsimtracer" + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rpc" + + "github.com/gobitfly/beaconchain/internal/contracts" +) + +type EOA struct { + *bind.TransactOpts + PrivateKey *ecdsa.PrivateKey +} + +const simulatedChainID = 1337 + +var ( + OneEther = big.NewInt(params.Ether) + DefaultTokenBalance = big.NewInt(100) +) + +func CreateEOA(t *testing.T) *EOA { + t.Helper() + + priv, err := crypto.GenerateKey() + if err != nil { + t.Fatal(err) + } + opts, err := bind.NewKeyedTransactorWithChainID(priv, big.NewInt(simulatedChainID)) + if err != nil { + t.Fatal(err) + } + return &EOA{ + PrivateKey: priv, + TransactOpts: opts, + } +} + +type BlockchainBackend struct { + *ethsimtracer.Backend + BankAccount *EOA + ChainID int + Endpoint string + + rpc *rpc.Client +} + +func NewBackend(t *testing.T, accounts ...common.Address) *BlockchainBackend { + t.Helper() + + genesis := make(map[common.Address]types.Account) + for _, account := range accounts { + genesis[account] = types.Account{Balance: OneEther} + } + bankAccount := CreateEOA(t) + genesis[bankAccount.From] = types.Account{Balance: new(big.Int).Mul(big.NewInt(1000), OneEther)} + + log.SetDefault(log.NewLogger(log.DiscardHandler())) + // TODO use random port + bk := ethsimtracer.NewBackend(genesis, func(nodeConf *node.Config, ethConf *ethconfig.Config) { + nodeConf.HTTPModules = append(nodeConf.HTTPModules, "debug", "eth") + nodeConf.HTTPHost = "127.0.0.1" + nodeConf.HTTPPort = 4242 + }) + endpoint := "http://127.0.0.1:4242" + client, err := rpc.Dial(endpoint) + if err != nil { + t.Fatal(err) + } + return &BlockchainBackend{ + Backend: bk, + BankAccount: bankAccount, + ChainID: simulatedChainID, + Endpoint: endpoint, + rpc: client, + } +} + +func (b *BlockchainBackend) Client() *ethclient.Client { + return ethclient.NewClient(b.rpc) +} + +func (b *BlockchainBackend) FundOneEther(t *testing.T, to common.Address) string { + t.Helper() + + signedTx := b.MakeTx(t, b.BankAccount, &to, OneEther, nil) + if err := b.Client().SendTransaction(context.Background(), signedTx); err != nil { + t.Fatal(err) + } + + b.Commit() + return signedTx.Hash().Hex() +} + +func (b *BlockchainBackend) Fund(t *testing.T, to common.Address, amount *big.Int) string { + t.Helper() + + signedTx := b.MakeTx(t, b.BankAccount, &to, amount, nil) + if err := b.Client().SendTransaction(context.Background(), signedTx); err != nil { + t.Fatal(err) + } + b.Commit() + return signedTx.Hash().Hex() +} + +func (b *BlockchainBackend) MakeTx(t *testing.T, sender *EOA, to *common.Address, value *big.Int, data []byte) *types.Transaction { + t.Helper() + + signedTx, err := types.SignTx(b.MakeUnsignedTx(t, sender.From, to, value, data), types.LatestSignerForChainID(big.NewInt(int64(b.ChainID))), sender.PrivateKey) + if err != nil { + t.Errorf("could not sign tx: %v", err) + } + return signedTx +} + +func (b *BlockchainBackend) MakeUnsignedTx(t *testing.T, from common.Address, to *common.Address, value *big.Int, data []byte) *types.Transaction { + t.Helper() + + head, _ := b.Backend.Client().HeaderByNumber(context.Background(), nil) + gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(params.GWei)) + chainid, _ := b.Backend.Client().ChainID(context.Background()) + nonce, err := b.Backend.Client().PendingNonceAt(context.Background(), from) + if err != nil { + t.Fatal(err) + } + return types.NewTx(&types.DynamicFeeTx{ + ChainID: chainid, + Nonce: nonce, + GasTipCap: big.NewInt(params.GWei), + GasFeeCap: gasPrice, + Gas: 100000, + To: to, + Value: value, + Data: data, + }) +} + +func (b *BlockchainBackend) DeployContract(t *testing.T, contractData []byte) common.Address { + t.Helper() + + head, _ := b.Backend.Client().HeaderByNumber(context.Background(), nil) + gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(params.GWei)) + chainid, _ := b.Backend.Client().ChainID(context.Background()) + nonce, err := b.Backend.Client().PendingNonceAt(context.Background(), b.BankAccount.From) + if err != nil { + t.Fatal(err) + } + tx := types.NewTx(&types.DynamicFeeTx{ + ChainID: chainid, + Nonce: nonce, + GasTipCap: big.NewInt(params.GWei), + GasFeeCap: gasPrice, + Gas: 2000000, + Data: contractData, + }) + + signedTx, err := types.SignTx(tx, types.LatestSignerForChainID(big.NewInt(int64(b.ChainID))), b.BankAccount.PrivateKey) + if err != nil { + t.Errorf("could not sign tx: %v", err) + } + + if err := b.Client().SendTransaction(context.Background(), signedTx); err != nil { + t.Fatal(err) + } + b.Commit() + + receipt, err := b.Client().TransactionReceipt(context.Background(), signedTx.Hash()) + if err != nil { + t.Fatal(err) + } + if receipt == nil { + t.Fatal("empty receipt") + } + if (receipt.ContractAddress == common.Address{}) { + t.Fatal("expected actual deployed contracts address") + } + + return receipt.ContractAddress +} + +func (b *BlockchainBackend) DeployToken(t *testing.T, name string, symbol string, accounts ...common.Address) (common.Address, *contracts.Token) { + t.Helper() + address, _, token, err := contracts.DeployToken(b.BankAccount.TransactOpts, b.Client(), name, symbol) + if err != nil { + t.Fatal(err) + } + b.Commit() + + for _, account := range accounts { + _, err := token.Mint(b.BankAccount.TransactOpts, account, DefaultTokenBalance) + if err != nil { + t.Fatal(err) + } + b.Commit() + } + return address, token +} + +func (b *BlockchainBackend) CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) { + return b.Client().CallContract(ctx, call, blockNumber) +} + +func (b *BlockchainBackend) SendTransaction(ctx context.Context, tx *types.Transaction) error { + return b.Client().SendTransaction(ctx, tx) +} + +func (b *BlockchainBackend) Commit() { + b.Backend.Commit() +} diff --git a/backend/pkg/commons/db2/store/bigtable.go b/backend/pkg/commons/db2/database/bigtable.go similarity index 82% rename from backend/pkg/commons/db2/store/bigtable.go rename to backend/pkg/commons/db2/database/bigtable.go index 7388215bf..707f22388 100644 --- a/backend/pkg/commons/db2/store/bigtable.go +++ b/backend/pkg/commons/db2/database/bigtable.go @@ -1,4 +1,4 @@ -package store +package database import ( "context" @@ -18,65 +18,65 @@ const ( ) type TableWrapper struct { - *BigTableStore + *BigTable table string family string } -func Wrap(db *BigTableStore, table string, family string) TableWrapper { +func Wrap(db *BigTable, table string, family string) TableWrapper { return TableWrapper{ - BigTableStore: db, - table: table, - family: family, + BigTable: db, + table: table, + family: family, } } func (w TableWrapper) Add(key, column string, data []byte, allowDuplicate bool) error { - return w.BigTableStore.Add(w.table, w.family, key, column, data, allowDuplicate) + return w.BigTable.Add(w.table, w.family, key, column, data, allowDuplicate) } func (w TableWrapper) Read(prefix string) ([][]byte, error) { - return w.BigTableStore.Read(w.table, w.family, prefix) + return w.BigTable.Read(w.table, w.family, prefix) } func (w TableWrapper) GetLatestValue(key string) ([]byte, error) { - return w.BigTableStore.GetLatestValue(w.table, w.family, key) + return w.BigTable.GetLatestValue(w.table, w.family, key) } func (w TableWrapper) GetRow(key string) (map[string][]byte, error) { - return w.BigTableStore.GetRow(w.table, key) + return w.BigTable.GetRow(w.table, key) } func (w TableWrapper) GetRowKeys(prefix string) ([]string, error) { - return w.BigTableStore.GetRowKeys(w.table, prefix) + return w.BigTable.GetRowKeys(w.table, prefix) } func (w TableWrapper) BulkAdd(itemsByKey map[string][]Item) error { - return w.BigTableStore.BulkAdd(w.table, itemsByKey) + return w.BigTable.BulkAdd(w.table, itemsByKey) } func (w TableWrapper) GetRowsRange(high, low string) ([]Row, error) { - return w.BigTableStore.GetRowsRange(w.table, high, low) + return w.BigTable.GetRowsRange(w.table, high, low) } -// BigTableStore is a wrapper around Google Cloud Bigtable for storing and retrieving data -type BigTableStore struct { +// BigTable is a wrapper around Google Cloud Bigtable for storing and retrieving data +type BigTable struct { client *bigtable.Client admin *bigtable.AdminClient } -func NewBigTableWithClient(ctx context.Context, client *bigtable.Client, adminClient *bigtable.AdminClient, tablesAndFamilies map[string][]string) (*BigTableStore, error) { +func NewBigTableWithClient(ctx context.Context, client *bigtable.Client, adminClient *bigtable.AdminClient, tablesAndFamilies map[string][]string) (*BigTable, error) { // Initialize the Bigtable table and column family if err := initTable(ctx, adminClient, tablesAndFamilies); err != nil { return nil, err } - return &BigTableStore{client: client, admin: adminClient}, nil + return &BigTable{client: client, admin: adminClient}, nil } -// NewBigTable initializes a new BigTableStore -// It returns a BigTableStore and an error if any part of the setup fails -func NewBigTable(project, instance string, tablesAndFamilies map[string][]string) (*BigTableStore, error) { +// NewBigTable initializes a new BigTable +// It returns a BigTable and an error if any part of the setup fails +func NewBigTable(project, instance string, tablesAndFamilies map[string][]string) (*BigTable, error) { ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() @@ -142,7 +142,7 @@ type Item struct { Data []byte } -func (b BigTableStore) BulkAdd(table string, itemsByKey map[string][]Item) error { +func (b BigTable) BulkAdd(table string, itemsByKey map[string][]Item) error { tbl := b.client.Open(table) ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() @@ -171,7 +171,7 @@ func (b BigTableStore) BulkAdd(table string, itemsByKey map[string][]Item) error // Add inserts a new row with the given key, column, and data into the Bigtable // It applies a mutation that stores data in the receiver column family // It returns error if the operation fails -func (b BigTableStore) Add(table, family string, key string, column string, data []byte, allowDuplicate bool) error { +func (b BigTable) Add(table, family string, key string, column string, data []byte, allowDuplicate bool) error { // Open the transfer table for data operations tbl := b.client.Open(table) ctx, cancel := context.WithTimeout(context.Background(), timeout) @@ -193,7 +193,7 @@ func (b BigTableStore) Add(table, family string, key string, column string, data // Read retrieves all rows from the Bigtable's receiver column family // It returns the data in the form of a 2D byte slice and an error if the operation fails -func (b BigTableStore) Read(table, family, prefix string) ([][]byte, error) { +func (b BigTable) Read(table, family, prefix string) ([][]byte, error) { // Open the transfer table for reading tbl := b.client.Open(table) ctx, cancel := context.WithTimeout(context.Background(), timeout) @@ -215,7 +215,7 @@ func (b BigTableStore) Read(table, family, prefix string) ([][]byte, error) { return data, nil } -func (b BigTableStore) GetLatestValue(table, family, key string) ([]byte, error) { +func (b BigTable) GetLatestValue(table, family, key string) ([]byte, error) { // Open the transfer table for reading tbl := b.client.Open(table) ctx, cancel := context.WithTimeout(context.Background(), timeout) @@ -234,7 +234,7 @@ func (b BigTableStore) GetLatestValue(table, family, key string) ([]byte, error) return data, nil } -func (b BigTableStore) GetRow(table, key string) (map[string][]byte, error) { +func (b BigTable) GetRow(table, key string) (map[string][]byte, error) { // Open the transfer table for reading tbl := b.client.Open(table) ctx, cancel := context.WithTimeout(context.Background(), timeout) @@ -265,7 +265,7 @@ type Row struct { Values map[string][]byte } -func (b BigTableStore) GetRowsRange(table, high, low string) ([]Row, error) { +func (b BigTable) GetRowsRange(table, high, low string) ([]Row, error) { tbl := b.client.Open(table) ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() @@ -296,7 +296,7 @@ func (b BigTableStore) GetRowsRange(table, high, low string) ([]Row, error) { return data, nil } -func (b BigTableStore) GetRowKeys(table, prefix string) ([]string, error) { +func (b BigTable) GetRowKeys(table, prefix string) ([]string, error) { // Open the transfer table for reading tbl := b.client.Open(table) ctx, cancel := context.WithTimeout(context.Background(), timeout) @@ -316,7 +316,7 @@ func (b BigTableStore) GetRowKeys(table, prefix string) ([]string, error) { return data, nil } -func (b BigTableStore) Clear() error { +func (b BigTable) Clear() error { ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() @@ -332,9 +332,9 @@ func (b BigTableStore) Clear() error { return nil } -// Close shuts down the BigTableStore by closing the Bigtable client connection +// Close shuts down the BigTable by closing the Bigtable client connection // It returns an error if the operation fails -func (b BigTableStore) Close() error { +func (b BigTable) Close() error { if err := b.client.Close(); err != nil && status.Code(err) != codes.Canceled { return fmt.Errorf("could not close client: %v", err) } diff --git a/backend/pkg/commons/db2/store/bigtable_test.go b/backend/pkg/commons/db2/database/bigtable_test.go similarity index 89% rename from backend/pkg/commons/db2/store/bigtable_test.go rename to backend/pkg/commons/db2/database/bigtable_test.go index 0d233aa9a..e7ea3b6e6 100644 --- a/backend/pkg/commons/db2/store/bigtable_test.go +++ b/backend/pkg/commons/db2/database/bigtable_test.go @@ -1,4 +1,4 @@ -package store +package database import ( "context" @@ -6,10 +6,10 @@ import ( "strings" "testing" - "github.com/gobitfly/beaconchain/pkg/commons/db2/storetest" + "github.com/gobitfly/beaconchain/pkg/commons/db2/databasetest" ) -func TestBigTableStore(t *testing.T) { +func TestBigTable(t *testing.T) { type item struct { key string column string @@ -76,12 +76,12 @@ func TestBigTableStore(t *testing.T) { }, } tables := map[string][]string{"testTable": {"testFamily"}} - client, admin := storetest.NewBigTable(t) - store, err := NewBigTableWithClient(context.Background(), client, admin, tables) + client, admin := databasetest.NewBigTable(t) + bt, err := NewBigTableWithClient(context.Background(), client, admin, tables) if err != nil { t.Fatal(err) } - db := Wrap(store, "testTable", "testFamily") + db := Wrap(bt, "testTable", "testFamily") for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -172,12 +172,12 @@ func TestBigTableStore(t *testing.T) { func TestRangeIncludeLimits(t *testing.T) { tables := map[string][]string{"testTable": {"testFamily"}} - client, admin := storetest.NewBigTable(t) - store, err := NewBigTableWithClient(context.Background(), client, admin, tables) + client, admin := databasetest.NewBigTable(t) + bt, err := NewBigTableWithClient(context.Background(), client, admin, tables) if err != nil { t.Fatal(err) } - db := Wrap(store, "testTable", "testFamily") + db := Wrap(bt, "testTable", "testFamily") _ = db.Add("1:999999999999", "", []byte("0"), false) _ = db.Add("1:999999999998", "", []byte("1"), false) diff --git a/backend/pkg/commons/db2/store/remote.go b/backend/pkg/commons/db2/database/remote.go similarity index 94% rename from backend/pkg/commons/db2/store/remote.go rename to backend/pkg/commons/db2/database/remote.go index 25f2b0a0e..6d298bd57 100644 --- a/backend/pkg/commons/db2/store/remote.go +++ b/backend/pkg/commons/db2/database/remote.go @@ -1,4 +1,4 @@ -package store +package database import ( "bytes" @@ -14,11 +14,11 @@ const ( ) type RemoteServer struct { - store Store + db Database } -func NewRemoteStore(store Store) RemoteServer { - return RemoteServer{store: store} +func NewRemote(db Database) RemoteServer { + return RemoteServer{db: db} } func (api RemoteServer) Routes() http.Handler { @@ -42,7 +42,7 @@ func (api RemoteServer) GetRowsRange(w http.ResponseWriter, r *http.Request) { _, _ = w.Write([]byte(err.Error())) return } - rows, err := api.store.GetRowsRange(args.High, args.Low) + rows, err := api.db.GetRowsRange(args.High, args.Low) if err != nil { w.WriteHeader(http.StatusInternalServerError) _, _ = w.Write([]byte(err.Error())) @@ -69,7 +69,7 @@ func (api RemoteServer) GetRow(w http.ResponseWriter, r *http.Request) { _, _ = w.Write([]byte(err.Error())) return } - row, err := api.store.GetRow(args.Key) + row, err := api.db.GetRow(args.Key) if err != nil { w.WriteHeader(http.StatusInternalServerError) _, _ = w.Write([]byte(err.Error())) diff --git a/backend/pkg/commons/db2/store/store.go b/backend/pkg/commons/db2/database/store.go similarity index 76% rename from backend/pkg/commons/db2/store/store.go rename to backend/pkg/commons/db2/database/store.go index 6bea25407..3b5d15faa 100644 --- a/backend/pkg/commons/db2/store/store.go +++ b/backend/pkg/commons/db2/database/store.go @@ -1,6 +1,6 @@ -package store +package database -type Store interface { +type Database interface { Add(key, column string, data []byte, allowDuplicate bool) error BulkAdd(itemsByKey map[string][]Item) error Read(prefix string) ([][]byte, error) @@ -13,6 +13,6 @@ type Store interface { } var ( - _ Store = (*TableWrapper)(nil) - _ Store = (*RemoteClient)(nil) + _ Database = (*TableWrapper)(nil) + _ Database = (*RemoteClient)(nil) ) diff --git a/backend/pkg/commons/db2/storetest/bigtable.go b/backend/pkg/commons/db2/databasetest/bigtable.go similarity index 97% rename from backend/pkg/commons/db2/storetest/bigtable.go rename to backend/pkg/commons/db2/databasetest/bigtable.go index 9c3780ead..89b92cf52 100644 --- a/backend/pkg/commons/db2/storetest/bigtable.go +++ b/backend/pkg/commons/db2/databasetest/bigtable.go @@ -1,4 +1,4 @@ -package storetest +package databasetest import ( "context" diff --git a/backend/pkg/commons/db2/jsonrpc/jsonrpc.go b/backend/pkg/commons/db2/jsonrpc/jsonrpc.go new file mode 100644 index 000000000..223fd209e --- /dev/null +++ b/backend/pkg/commons/db2/jsonrpc/jsonrpc.go @@ -0,0 +1,20 @@ +package jsonrpc + +import ( + "encoding/json" +) + +type Message struct { + Version string `json:"jsonrpc,omitempty"` + ID json.RawMessage `json:"id,omitempty"` + Method string `json:"method,omitempty"` + Params json.RawMessage `json:"params,omitempty"` + Error *Error `json:"error,omitempty"` + Result json.RawMessage `json:"result,omitempty"` +} + +type Error struct { + Code int `json:"code"` + Message string `json:"message"` + Data interface{} `json:"data,omitempty"` +} diff --git a/backend/pkg/commons/db2/parser.go b/backend/pkg/commons/db2/parser.go index 3e3c374ef..a040357fa 100644 --- a/backend/pkg/commons/db2/parser.go +++ b/backend/pkg/commons/db2/parser.go @@ -8,6 +8,9 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + + "github.com/gobitfly/beaconchain/pkg/commons/db2/jsonrpc" + "github.com/gobitfly/beaconchain/pkg/commons/db2/raw" ) type GethTrace struct { @@ -31,13 +34,13 @@ type GethTraceCall struct { Calls []*GethTraceCall } -var EthParse = func(rawBlock *FullBlockRawData) (*types.Block, []*types.Receipt, []*GethTrace, error) { - var blockResp, receiptsResp, tracesResp jsonrpcMessage +var EthParse = func(rawBlock *raw.FullBlockData) (*types.Block, []*types.Receipt, []*GethTrace, error) { + var blockResp, receiptsResp, tracesResp jsonrpc.Message _ = json.Unmarshal(rawBlock.Receipts, &receiptsResp) _ = json.Unmarshal(rawBlock.Block, &blockResp) _ = json.Unmarshal(rawBlock.Traces, &tracesResp) - var unclesResp []jsonrpcMessage + var unclesResp []jsonrpc.Message _ = json.Unmarshal(rawBlock.Uncles, &unclesResp) block, err := parseEthBlock(blockResp.Result, unclesResp) @@ -74,6 +77,7 @@ type rpcBlock struct { Transactions []rpcTransaction `json:"transactions"` UncleHashes []common.Hash `json:"uncles"` Withdrawals []*types.Withdrawal `json:"withdrawals,omitempty"` + Requests []*types.Request `json:"requests,omitempty"` } type rpcTransaction struct { @@ -96,8 +100,8 @@ type txExtraInfo struct { // parseEthBlock is a copy of ethclient.Client.getBlock // modified to work the with raw db -// https://github.com/ethereum/go-ethereum/blob/v1.13.12/ethclient/ethclient.go#L129 -func parseEthBlock(raw json.RawMessage, rawUncles []jsonrpcMessage) (*types.Block, error) { +// https://github.com/ethereum/go-ethereum/blob/v1.14.11/ethclient/ethclient.go#L129 +func parseEthBlock(raw json.RawMessage, rawUncles []jsonrpc.Message) (*types.Block, error) { // Decode header and transactions. var head *types.Header if err := json.Unmarshal(raw, &head); err != nil { @@ -142,7 +146,13 @@ func parseEthBlock(raw json.RawMessage, rawUncles []jsonrpcMessage) (*types.Bloc } txs[i] = tx.tx } - return types.NewBlockWithHeader(head).WithBody(txs, uncles).WithWithdrawals(body.Withdrawals), nil + return types.NewBlockWithHeader(head).WithBody( + types.Body{ + Transactions: txs, + Uncles: uncles, + Withdrawals: body.Withdrawals, + Requests: body.Requests, + }), nil } // SenderFromDBSigner is a types.Signer that remembers the sender address returned by the RPC diff --git a/backend/pkg/commons/db2/parser_test.go b/backend/pkg/commons/db2/parser_test.go new file mode 100644 index 000000000..7b842a24d --- /dev/null +++ b/backend/pkg/commons/db2/parser_test.go @@ -0,0 +1,84 @@ +package db2 + +import ( + "context" + "math/big" + "os" + "reflect" + "testing" + + "github.com/ethereum/go-ethereum/rpc" + + "github.com/gobitfly/beaconchain/pkg/commons/db2/database" + "github.com/gobitfly/beaconchain/pkg/commons/db2/raw" + "github.com/gobitfly/beaconchain/pkg/commons/db2/rawtest" +) + +func TestRawWithBackend(t *testing.T) { + raw, backend := rawtest.NewRandSeededStore(t) + blocks, err := raw.ReadBlocksByNumber(uint64(backend.ChainID), 0, 10) + if err != nil { + t.Fatal(err) + } + for _, b := range blocks { + expectedBlock, err := backend.Client().BlockByNumber(context.Background(), big.NewInt(b.BlockNumber)) + if err != nil { + t.Fatal(err) + } + expectedReceipts, err := backend.Client().BlockReceipts(context.Background(), rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(b.BlockNumber))) + if err != nil { + t.Fatal(err) + } + block, receipts, _, err := EthParse(b) + if err != nil { + t.Fatal(err) + } + if got, want := block.Number().String(), expectedBlock.Number().String(); got != want { + t.Errorf("got %v, want %v", got, want) + } + if got, want := block.Hash().String(), expectedBlock.Hash().String(); got != want { + t.Errorf("got %v, want %v", got, want) + } + if got, want := block.TxHash().String(), expectedBlock.TxHash().String(); got != want { + t.Errorf("got %v, want %v", got, want) + } + if got, want := block.UncleHash().String(), expectedBlock.UncleHash().String(); got != want { + t.Errorf("got %v, want %v", got, want) + } + if got, want := block.ReceiptHash().String(), expectedBlock.ReceiptHash().String(); got != want { + t.Errorf("got %v, want %v", got, want) + } + if len(expectedReceipts) != 0 { + if got, want := receipts, expectedReceipts; !reflect.DeepEqual(got, want) { + t.Errorf("got %v, want %v", got, want) + } + } + } +} + +func TestRawRemoteRealCondition(t *testing.T) { + remote := os.Getenv("REMOTE_URL") + if remote == "" { + t.Skip("skipping test, set REMOTE_URL") + } + + client := database.NewRemoteClient(remote) + db := raw.NewStore(client) + block, err := db.ReadBlockByNumber(1, 6008149) + if err != nil { + panic(err) + } + + ethBlock, receipts, traces, err := EthParse(block) + if err != nil { + t.Errorf("failed to parse block: %v", err) + } + for i, transaction := range ethBlock.Transactions() { + if got, want := receipts[i].TxHash, transaction.Hash(); got != want { + t.Errorf("got %v, want %v", got, want) + } + if got, want := traces[i].TxHash, transaction.Hash().Hex(); got != want { + t.Errorf("got %v, want %v", got, want) + } + } +} diff --git a/backend/pkg/commons/db2/cache.go b/backend/pkg/commons/db2/raw/cache.go similarity index 65% rename from backend/pkg/commons/db2/cache.go rename to backend/pkg/commons/db2/raw/cache.go index c086b4eb5..3e3e3b8de 100644 --- a/backend/pkg/commons/db2/cache.go +++ b/backend/pkg/commons/db2/raw/cache.go @@ -1,4 +1,4 @@ -package db2 +package raw import ( "encoding/json" @@ -17,8 +17,8 @@ type MinimalBlock struct { } `json:"result"` } -type CachedRawStore struct { - db RawStoreReader +type CachedStore struct { + store StoreReader // sync.Map with manual delete have better perf than freecache because we can handle this way a ttl < 1s cache sync.Map @@ -26,14 +26,14 @@ type CachedRawStore struct { mapLock sync.Mutex // to make the map safe concurrently } -func WithCache(reader RawStoreReader) *CachedRawStore { - return &CachedRawStore{ - db: reader, +func WithCache(reader StoreReader) *CachedStore { + return &CachedStore{ + store: reader, locks: make(map[string]*sync.RWMutex), } } -func (c *CachedRawStore) lockBy(key string) func() { +func (c *CachedStore) lockBy(key string) func() { c.mapLock.Lock() defer c.mapLock.Unlock() @@ -48,7 +48,7 @@ func (c *CachedRawStore) lockBy(key string) func() { return lock.RUnlock } -func (c *CachedRawStore) ReadBlockByNumber(chainID uint64, number int64) (*FullBlockRawData, error) { +func (c *CachedStore) ReadBlockByNumber(chainID uint64, number int64) (*FullBlockData, error) { key := blockKey(chainID, number) unlock := c.lockBy(key) @@ -58,17 +58,17 @@ func (c *CachedRawStore) ReadBlockByNumber(chainID uint64, number int64) (*FullB if ok { // once read ensure to delete it from the cache go c.unCacheBlockAfter(key, "", oneBlockTTL) - return v.(*FullBlockRawData), nil + return v.(*FullBlockData), nil } // TODO make warning not found in cache - block, err := c.db.ReadBlockByNumber(chainID, number) + block, err := c.store.ReadBlockByNumber(chainID, number) if block != nil { c.cacheBlock(block, oneBlockTTL) } return block, err } -func (c *CachedRawStore) cacheBlock(block *FullBlockRawData, ttl time.Duration) { +func (c *CachedStore) cacheBlock(block *FullBlockData, ttl time.Duration) { key := blockKey(block.ChainID, block.BlockNumber) c.cache.Store(key, block) @@ -82,7 +82,7 @@ func (c *CachedRawStore) cacheBlock(block *FullBlockRawData, ttl time.Duration) go c.unCacheBlockAfter(key, mini.Result.Hash, ttl) } -func (c *CachedRawStore) unCacheBlockAfter(key, hash string, ttl time.Duration) { +func (c *CachedStore) unCacheBlockAfter(key, hash string, ttl time.Duration) { time.Sleep(ttl) c.cache.Delete(key) c.mapLock.Lock() @@ -93,22 +93,22 @@ func (c *CachedRawStore) unCacheBlockAfter(key, hash string, ttl time.Duration) delete(c.locks, key) } -func (c *CachedRawStore) ReadBlockByHash(chainID uint64, hash string) (*FullBlockRawData, error) { +func (c *CachedStore) ReadBlockByHash(chainID uint64, hash string) (*FullBlockData, error) { v, ok := c.cache.Load(hash) if !ok { - return c.db.ReadBlockByHash(chainID, hash) + return c.store.ReadBlockByHash(chainID, hash) } v, ok = c.cache.Load(blockKey(chainID, v.(int64))) if !ok { - return c.db.ReadBlockByHash(chainID, hash) + return c.store.ReadBlockByHash(chainID, hash) } - return v.(*FullBlockRawData), nil + return v.(*FullBlockData), nil } -func (c *CachedRawStore) ReadBlocksByNumber(chainID uint64, start, end int64) ([]*FullBlockRawData, error) { - blocks, err := c.db.ReadBlocksByNumber(chainID, start, end) +func (c *CachedStore) ReadBlocksByNumber(chainID uint64, start, end int64) ([]*FullBlockData, error) { + blocks, err := c.store.ReadBlocksByNumber(chainID, start, end) if err != nil { return nil, err } diff --git a/backend/pkg/commons/db2/client.go b/backend/pkg/commons/db2/raw/client.go similarity index 63% rename from backend/pkg/commons/db2/client.go rename to backend/pkg/commons/db2/raw/client.go index c723867f7..04a0a465a 100644 --- a/backend/pkg/commons/db2/client.go +++ b/backend/pkg/commons/db2/raw/client.go @@ -1,4 +1,4 @@ -package db2 +package raw import ( "bytes" @@ -12,16 +12,17 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/gobitfly/beaconchain/pkg/commons/db2/store" + "github.com/gobitfly/beaconchain/pkg/commons/db2/database" + "github.com/gobitfly/beaconchain/pkg/commons/db2/jsonrpc" ) var ErrNotFoundInCache = fmt.Errorf("cannot find hash in cache") var ErrMethodNotSupported = fmt.Errorf("method not supported") -type RawStoreReader interface { - ReadBlockByNumber(chainID uint64, number int64) (*FullBlockRawData, error) - ReadBlockByHash(chainID uint64, hash string) (*FullBlockRawData, error) - ReadBlocksByNumber(chainID uint64, start, end int64) ([]*FullBlockRawData, error) +type StoreReader interface { + ReadBlockByNumber(chainID uint64, number int64) (*FullBlockData, error) + ReadBlockByHash(chainID uint64, hash string) (*FullBlockData, error) + ReadBlocksByNumber(chainID uint64, start, end int64) ([]*FullBlockData, error) } type WithFallback struct { @@ -47,26 +48,26 @@ func (r WithFallback) RoundTrip(request *http.Request) (*http.Response, error) { if !errors.As(err, &e1) && !errors.Is(err, ErrNotFoundInCache) && !errors.Is(err, ErrMethodNotSupported) && - !errors.Is(err, store.ErrNotFound) { + !errors.Is(err, database.ErrNotFound) { return nil, err } return r.fallback.RoundTrip(request) } -type BigTableEthRaw struct { - db RawStoreReader +type StoreRoundTripper struct { + store StoreReader chainID uint64 } -func NewBigTableEthRaw(db RawStoreReader, chainID uint64) *BigTableEthRaw { - return &BigTableEthRaw{ - db: db, +func NewBigTableEthRaw(store StoreReader, chainID uint64) *StoreRoundTripper { + return &StoreRoundTripper{ + store: store, chainID: chainID, } } -func (r *BigTableEthRaw) RoundTrip(request *http.Request) (*http.Response, error) { +func (r *StoreRoundTripper) RoundTrip(request *http.Request) (*http.Response, error) { body, err := io.ReadAll(request.Body) if err != nil { return nil, err @@ -74,17 +75,17 @@ func (r *BigTableEthRaw) RoundTrip(request *http.Request) (*http.Response, error defer func() { request.Body = io.NopCloser(bytes.NewBuffer(body)) }() - var messages []*jsonrpcMessage + var messages []*jsonrpc.Message var isSingle bool if err := json.NewDecoder(bytes.NewReader(body)).Decode(&messages); err != nil { isSingle = true - message := new(jsonrpcMessage) + message := new(jsonrpc.Message) if err := json.NewDecoder(bytes.NewReader(body)).Decode(message); err != nil { return nil, err } messages = append(messages, message) } - var resps []*jsonrpcMessage + var resps []*jsonrpc.Message for _, message := range messages { resp, err := r.handle(request.Context(), message) if err != nil { @@ -100,7 +101,7 @@ func (r *BigTableEthRaw) RoundTrip(request *http.Request) (*http.Response, error }, nil } -func (r *BigTableEthRaw) handle(ctx context.Context, message *jsonrpcMessage) (*jsonrpcMessage, error) { +func (r *StoreRoundTripper) handle(ctx context.Context, message *jsonrpc.Message) (*jsonrpc.Message, error) { var args []interface{} err := json.Unmarshal(message.Params, &args) if err != nil { @@ -155,7 +156,7 @@ func (r *BigTableEthRaw) handle(ctx context.Context, message *jsonrpcMessage) (* default: return nil, ErrMethodNotSupported } - var resp jsonrpcMessage + var resp jsonrpc.Message _ = json.Unmarshal(respBody, &resp) if len(respBody) == 0 { resp.Version = message.Version @@ -165,7 +166,7 @@ func (r *BigTableEthRaw) handle(ctx context.Context, message *jsonrpcMessage) (* return &resp, nil } -func makeBody(isSingle bool, messages []*jsonrpcMessage) (io.ReadCloser, error) { +func makeBody(isSingle bool, messages []*jsonrpc.Message) (io.ReadCloser, error) { var b []byte var err error if isSingle { @@ -179,39 +180,39 @@ func makeBody(isSingle bool, messages []*jsonrpcMessage) (io.ReadCloser, error) return io.NopCloser(bytes.NewReader(b)), nil } -func (r *BigTableEthRaw) BlockByNumber(ctx context.Context, number *big.Int) ([]byte, error) { - block, err := r.db.ReadBlockByNumber(r.chainID, number.Int64()) +func (r *StoreRoundTripper) BlockByNumber(ctx context.Context, number *big.Int) ([]byte, error) { + block, err := r.store.ReadBlockByNumber(r.chainID, number.Int64()) if err != nil { return nil, err } return block.Block, nil } -func (r *BigTableEthRaw) BlockReceipts(ctx context.Context, number *big.Int) ([]byte, error) { - block, err := r.db.ReadBlockByNumber(r.chainID, number.Int64()) +func (r *StoreRoundTripper) BlockReceipts(ctx context.Context, number *big.Int) ([]byte, error) { + block, err := r.store.ReadBlockByNumber(r.chainID, number.Int64()) if err != nil { return nil, err } return block.Receipts, nil } -func (r *BigTableEthRaw) TraceBlockByNumber(ctx context.Context, number *big.Int) ([]byte, error) { - block, err := r.db.ReadBlockByNumber(r.chainID, number.Int64()) +func (r *StoreRoundTripper) TraceBlockByNumber(ctx context.Context, number *big.Int) ([]byte, error) { + block, err := r.store.ReadBlockByNumber(r.chainID, number.Int64()) if err != nil { return nil, err } return block.Traces, nil } -func (r *BigTableEthRaw) UncleByBlockNumberAndIndex(ctx context.Context, number *big.Int, index int64) ([]byte, error) { - block, err := r.db.ReadBlockByNumber(r.chainID, number.Int64()) +func (r *StoreRoundTripper) UncleByBlockNumberAndIndex(ctx context.Context, number *big.Int, index int64) ([]byte, error) { + block, err := r.store.ReadBlockByNumber(r.chainID, number.Int64()) if err != nil { return nil, err } - var uncles []*jsonrpcMessage + var uncles []*jsonrpc.Message if err := json.Unmarshal(block.Uncles, &uncles); err != nil { - var uncle *jsonrpcMessage + var uncle *jsonrpc.Message if err := json.Unmarshal(block.Uncles, &uncle); err != nil { return nil, fmt.Errorf("cannot unmarshal uncle: %w", err) } @@ -220,15 +221,15 @@ func (r *BigTableEthRaw) UncleByBlockNumberAndIndex(ctx context.Context, number return json.Marshal(uncles[index]) } -func (r *BigTableEthRaw) UncleByBlockHashAndIndex(ctx context.Context, hash string, index int64) ([]byte, error) { - block, err := r.db.ReadBlockByHash(r.chainID, hash) +func (r *StoreRoundTripper) UncleByBlockHashAndIndex(ctx context.Context, hash string, index int64) ([]byte, error) { + block, err := r.store.ReadBlockByHash(r.chainID, hash) if err != nil { return nil, err } - var uncles []*jsonrpcMessage + var uncles []*jsonrpc.Message if err := json.Unmarshal(block.Uncles, &uncles); err != nil { - var uncle *jsonrpcMessage + var uncle *jsonrpc.Message if err := json.Unmarshal(block.Uncles, &uncle); err != nil { return nil, fmt.Errorf("cannot unmarshal uncle: %w", err) } @@ -236,20 +237,3 @@ func (r *BigTableEthRaw) UncleByBlockHashAndIndex(ctx context.Context, hash stri } return json.Marshal(uncles[index]) } - -// A value of this type can a JSON-RPC request, notification, successful response or -// error response. Which one it is depends on the fields. -type jsonrpcMessage struct { - Version string `json:"jsonrpc,omitempty"` - ID json.RawMessage `json:"id,omitempty"` - Method string `json:"method,omitempty"` - Params json.RawMessage `json:"params,omitempty"` - Error *jsonError `json:"error,omitempty"` - Result json.RawMessage `json:"result,omitempty"` -} - -type jsonError struct { - Code int `json:"code"` - Message string `json:"message"` - Data interface{} `json:"data,omitempty"` -} diff --git a/backend/pkg/commons/db2/client_test.go b/backend/pkg/commons/db2/raw/client_test.go similarity index 90% rename from backend/pkg/commons/db2/client_test.go rename to backend/pkg/commons/db2/raw/client_test.go index 9c2138ee1..5dd8511ee 100644 --- a/backend/pkg/commons/db2/client_test.go +++ b/backend/pkg/commons/db2/raw/client_test.go @@ -1,4 +1,4 @@ -package db2 +package raw import ( "context" @@ -12,8 +12,8 @@ import ( "github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/rpc" - "github.com/gobitfly/beaconchain/pkg/commons/db2/store" - "github.com/gobitfly/beaconchain/pkg/commons/db2/storetest" + "github.com/gobitfly/beaconchain/pkg/commons/db2/database" + "github.com/gobitfly/beaconchain/pkg/commons/db2/databasetest" ) const ( @@ -43,12 +43,12 @@ func TestBigTableClientRealCondition(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - bg, err := store.NewBigTable(project, instance, nil) + bg, err := database.NewBigTable(project, instance, nil) if err != nil { t.Fatal(err) } - rawStore := NewRawStore(store.Wrap(bg, BlocksRawTable, "")) + rawStore := NewStore(database.Wrap(bg, BlocksRawTable, "")) rpcClient, err := rpc.DialOptions(context.Background(), "http://foo.bar", rpc.WithHTTPClient(&http.Client{ Transport: NewBigTableEthRaw(rawStore, chainID), })) @@ -125,12 +125,12 @@ func BenchmarkRawBigTable(b *testing.B) { b.Skip("skipping test, set BIGTABLE_PROJECT and BIGTABLE_INSTANCE") } - bt, err := store.NewBigTable(project, instance, nil) + bt, err := database.NewBigTable(project, instance, nil) if err != nil { b.Fatal(err) } - rawStore := WithCache(NewRawStore(store.Wrap(bt, BlocksRawTable, ""))) + rawStore := WithCache(NewStore(database.Wrap(bt, BlocksRawTable, ""))) rpcClient, err := rpc.DialOptions(context.Background(), "http://foo.bar", rpc.WithHTTPClient(&http.Client{ Transport: NewBigTableEthRaw(rawStore, chainID), })) @@ -153,7 +153,7 @@ func BenchmarkAll(b *testing.B) { func TestBigTableClient(t *testing.T) { tests := []struct { name string - block FullBlockRawData + block FullBlockData }{ { name: "test block", @@ -165,16 +165,16 @@ func TestBigTableClient(t *testing.T) { }, } - client, admin := storetest.NewBigTable(t) - bg, err := store.NewBigTableWithClient(context.Background(), client, admin, RawSchema) + client, admin := databasetest.NewBigTable(t) + bg, err := database.NewBigTableWithClient(context.Background(), client, admin, Schema) if err != nil { t.Fatal(err) } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - rawStore := NewRawStore(store.Wrap(bg, BlocksRawTable, "")) - if err := rawStore.AddBlocks([]FullBlockRawData{tt.block}); err != nil { + rawStore := NewStore(database.Wrap(bg, BlocksRawTable, "")) + if err := rawStore.AddBlocks([]FullBlockData{tt.block}); err != nil { t.Fatal(err) } @@ -221,7 +221,7 @@ func TestBigTableClientWithFallback(t *testing.T) { tests := []struct { name string - block FullBlockRawData + block FullBlockData }{ { name: "test block", @@ -229,15 +229,15 @@ func TestBigTableClientWithFallback(t *testing.T) { }, } - client, admin := storetest.NewBigTable(t) - bg, err := store.NewBigTableWithClient(context.Background(), client, admin, RawSchema) + client, admin := databasetest.NewBigTable(t) + bt, err := database.NewBigTableWithClient(context.Background(), client, admin, Schema) if err != nil { t.Fatal(err) } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - rawStore := NewRawStore(store.Wrap(bg, BlocksRawTable, "")) + rawStore := NewStore(database.Wrap(bt, BlocksRawTable, "")) rpcClient, err := rpc.DialOptions(context.Background(), node, rpc.WithHTTPClient(&http.Client{ Transport: NewWithFallback(NewBigTableEthRaw(rawStore, tt.block.ChainID), http.DefaultTransport), diff --git a/backend/pkg/commons/db2/compress.go b/backend/pkg/commons/db2/raw/compress.go similarity index 98% rename from backend/pkg/commons/db2/compress.go rename to backend/pkg/commons/db2/raw/compress.go index 1c92672f2..b5010bdb7 100644 --- a/backend/pkg/commons/db2/compress.go +++ b/backend/pkg/commons/db2/raw/compress.go @@ -1,4 +1,4 @@ -package db2 +package raw import ( "bytes" diff --git a/backend/pkg/commons/db2/raw.go b/backend/pkg/commons/db2/raw/raw.go similarity index 60% rename from backend/pkg/commons/db2/raw.go rename to backend/pkg/commons/db2/raw/raw.go index a0795c6cc..45b2008c8 100644 --- a/backend/pkg/commons/db2/raw.go +++ b/backend/pkg/commons/db2/raw/raw.go @@ -1,11 +1,11 @@ -package db2 +package raw import ( "fmt" "math/big" "strings" - "github.com/gobitfly/beaconchain/pkg/commons/db2/store" + "github.com/gobitfly/beaconchain/pkg/commons/db2/database" "github.com/gobitfly/beaconchain/pkg/commons/hexutil" "github.com/gobitfly/beaconchain/pkg/commons/log" ) @@ -15,39 +15,39 @@ type compressor interface { decompress(src []byte) ([]byte, error) } -type RawStore struct { - store store.Store +type Store struct { + db database.Database compressor compressor } -func NewRawStore(store store.Store) RawStore { - return RawStore{ - store: store, +func NewStore(store database.Database) Store { + return Store{ + db: store, compressor: gzipCompressor{}, } } -func (db RawStore) AddBlocks(blocks []FullBlockRawData) error { - itemsByKey := make(map[string][]store.Item) +func (store Store) AddBlocks(blocks []FullBlockData) error { + itemsByKey := make(map[string][]database.Item) for _, fullBlock := range blocks { if len(fullBlock.Block) == 0 || len(fullBlock.BlockTxs) != 0 && len(fullBlock.Traces) == 0 { return fmt.Errorf("block %d: empty data", fullBlock.BlockNumber) } key := blockKey(fullBlock.ChainID, fullBlock.BlockNumber) - block, err := db.compressor.compress(fullBlock.Block) + block, err := store.compressor.compress(fullBlock.Block) if err != nil { return fmt.Errorf("cannot compress block %d: %w", fullBlock.BlockNumber, err) } - receipts, err := db.compressor.compress(fullBlock.Receipts) + receipts, err := store.compressor.compress(fullBlock.Receipts) if err != nil { return fmt.Errorf("cannot compress receipts %d: %w", fullBlock.BlockNumber, err) } - traces, err := db.compressor.compress(fullBlock.Traces) + traces, err := store.compressor.compress(fullBlock.Traces) if err != nil { return fmt.Errorf("cannot compress traces %d: %w", fullBlock.BlockNumber, err) } - itemsByKey[key] = []store.Item{ + itemsByKey[key] = []database.Item{ { Family: BT_COLUMNFAMILY_BLOCK, Column: BT_COLUMN_BLOCK, @@ -69,56 +69,56 @@ func (db RawStore) AddBlocks(blocks []FullBlockRawData) error { log.Warn(fmt.Sprintf("empty receipts at block %d lRec %d lTxs %d", fullBlock.BlockNumber, len(fullBlock.Receipts), len(fullBlock.BlockTxs))) } if fullBlock.BlockUnclesCount > 0 { - uncles, err := db.compressor.compress(fullBlock.Uncles) + uncles, err := store.compressor.compress(fullBlock.Uncles) if err != nil { return fmt.Errorf("cannot compress block %d: %w", fullBlock.BlockNumber, err) } - itemsByKey[key] = append(itemsByKey[key], store.Item{ + itemsByKey[key] = append(itemsByKey[key], database.Item{ Family: BT_COLUMNFAMILY_UNCLES, Column: BT_COLUMN_UNCLES, Data: uncles, }) } } - return db.store.BulkAdd(itemsByKey) + return store.db.BulkAdd(itemsByKey) } -func (db RawStore) ReadBlockByNumber(chainID uint64, number int64) (*FullBlockRawData, error) { - return db.readBlock(chainID, number) +func (store Store) ReadBlockByNumber(chainID uint64, number int64) (*FullBlockData, error) { + return store.readBlock(chainID, number) } -func (db RawStore) ReadBlockByHash(chainID uint64, hash string) (*FullBlockRawData, error) { - // todo use sql db to retrieve hash +func (store Store) ReadBlockByHash(chainID uint64, hash string) (*FullBlockData, error) { + // todo use sql store to retrieve hash return nil, fmt.Errorf("ReadBlockByHash not implemented") } -func (db RawStore) readBlock(chainID uint64, number int64) (*FullBlockRawData, error) { +func (store Store) readBlock(chainID uint64, number int64) (*FullBlockData, error) { key := blockKey(chainID, number) - data, err := db.store.GetRow(key) + data, err := store.db.GetRow(key) if err != nil { return nil, err } - return db.parseRow(chainID, number, data) + return store.parseRow(chainID, number, data) } -func (db RawStore) parseRow(chainID uint64, number int64, data map[string][]byte) (*FullBlockRawData, error) { - block, err := db.compressor.decompress(data[fmt.Sprintf("%s:%s", BT_COLUMNFAMILY_BLOCK, BT_COLUMN_BLOCK)]) +func (store Store) parseRow(chainID uint64, number int64, data map[string][]byte) (*FullBlockData, error) { + block, err := store.compressor.decompress(data[fmt.Sprintf("%s:%s", BT_COLUMNFAMILY_BLOCK, BT_COLUMN_BLOCK)]) if err != nil { return nil, fmt.Errorf("cannot decompress block %d: %w", number, err) } - receipts, err := db.compressor.decompress(data[fmt.Sprintf("%s:%s", BT_COLUMNFAMILY_RECEIPTS, BT_COLUMN_RECEIPTS)]) + receipts, err := store.compressor.decompress(data[fmt.Sprintf("%s:%s", BT_COLUMNFAMILY_RECEIPTS, BT_COLUMN_RECEIPTS)]) if err != nil { return nil, fmt.Errorf("cannot decompress receipts %d: %w", number, err) } - traces, err := db.compressor.decompress(data[fmt.Sprintf("%s:%s", BT_COLUMNFAMILY_TRACES, BT_COLUMN_TRACES)]) + traces, err := store.compressor.decompress(data[fmt.Sprintf("%s:%s", BT_COLUMNFAMILY_TRACES, BT_COLUMN_TRACES)]) if err != nil { return nil, fmt.Errorf("cannot decompress traces %d: %w", number, err) } - uncles, err := db.compressor.decompress(data[fmt.Sprintf("%s:%s", BT_COLUMNFAMILY_UNCLES, BT_COLUMN_UNCLES)]) + uncles, err := store.compressor.decompress(data[fmt.Sprintf("%s:%s", BT_COLUMNFAMILY_UNCLES, BT_COLUMN_UNCLES)]) if err != nil { return nil, fmt.Errorf("cannot decompress uncles %d: %w", number, err) } - return &FullBlockRawData{ + return &FullBlockData{ ChainID: chainID, BlockNumber: number, BlockHash: nil, @@ -131,14 +131,14 @@ func (db RawStore) parseRow(chainID uint64, number int64, data map[string][]byte }, nil } -func (db RawStore) ReadBlocksByNumber(chainID uint64, start, end int64) ([]*FullBlockRawData, error) { - rows, err := db.store.GetRowsRange(blockKey(chainID, start), blockKey(chainID, end)) +func (store Store) ReadBlocksByNumber(chainID uint64, start, end int64) ([]*FullBlockData, error) { + rows, err := store.db.GetRowsRange(blockKey(chainID, start), blockKey(chainID, end)) if err != nil { return nil, err } - blocks := make([]*FullBlockRawData, 0, end-start+1) + blocks := make([]*FullBlockData, 0, end-start+1) for _, row := range rows { - block, err := db.parseRow(chainID, blockKeyToNumber(chainID, row.Key), row.Values) + block, err := store.parseRow(chainID, blockKeyToNumber(chainID, row.Key), row.Values) if err != nil { return nil, err } @@ -158,7 +158,7 @@ func blockKeyToNumber(chainID uint64, key string) int64 { return MAX_EL_BLOCK_NUMBER - reversed.Int64() } -type FullBlockRawData struct { +type FullBlockData struct { ChainID uint64 BlockNumber int64 diff --git a/backend/pkg/commons/db2/raw_test.go b/backend/pkg/commons/db2/raw/raw_test.go similarity index 90% rename from backend/pkg/commons/db2/raw_test.go rename to backend/pkg/commons/db2/raw/raw_test.go index 0d8f59a94..06354a1e9 100644 --- a/backend/pkg/commons/db2/raw_test.go +++ b/backend/pkg/commons/db2/raw/raw_test.go @@ -1,36 +1,34 @@ -package db2 +package raw import ( - "bytes" "context" - "os" "testing" "github.com/ethereum/go-ethereum/common" - "github.com/gobitfly/beaconchain/pkg/commons/db2/store" - "github.com/gobitfly/beaconchain/pkg/commons/db2/storetest" + "github.com/gobitfly/beaconchain/pkg/commons/db2/database" + "github.com/gobitfly/beaconchain/pkg/commons/db2/databasetest" ) func TestRaw(t *testing.T) { - client, admin := storetest.NewBigTable(t) + client, admin := databasetest.NewBigTable(t) - s, err := store.NewBigTableWithClient(context.Background(), client, admin, RawSchema) + s, err := database.NewBigTableWithClient(context.Background(), client, admin, Schema) if err != nil { t.Fatal(err) } - db := RawStore{ - store: store.Wrap(s, BlocksRawTable, ""), + store := Store{ + db: database.Wrap(s, BlocksRawTable, ""), compressor: noOpCompressor{}, } block := testFullBlock - if err := db.AddBlocks([]FullBlockRawData{block}); err != nil { + if err := store.AddBlocks([]FullBlockData{block}); err != nil { t.Fatal(err) } - res, err := db.ReadBlockByNumber(block.ChainID, block.BlockNumber) + res, err := store.ReadBlockByNumber(block.ChainID, block.BlockNumber) if err != nil { t.Fatal(err) } @@ -47,58 +45,9 @@ func TestRaw(t *testing.T) { if got, want := string(res.Uncles), testUncles; got != want { t.Errorf("got %v, want %v", got, want) } - - ethBlock, receipts, traces, err := EthParse(res) - if err != nil { - t.Errorf("failed to parse block: %v", err) - } - if got, want := block.BlockHash, ethBlock.Hash().Bytes(); !bytes.Equal(got, want) { - t.Errorf("got %x, want %x", got, want) - } - if got, want := len(receipts), len(ethBlock.Transactions()); got != want { - t.Errorf("got %v, want %v", got, want) - } - if got, want := len(traces), len(ethBlock.Transactions()); got != want { - t.Errorf("got %v, want %v", got, want) - } - for i, transaction := range ethBlock.Transactions() { - if got, want := receipts[i].TxHash, transaction.Hash(); got != want { - t.Errorf("got %v, want %v", got, want) - } - if got, want := traces[i].TxHash, transaction.Hash().Hex(); got != want { - t.Errorf("got %v, want %v", got, want) - } - } -} - -func TestRawRemoteRealCondition(t *testing.T) { - remote := os.Getenv("REMOTE_URL") - if remote == "" { - t.Skip("skipping test, set REMOTE_URL") - } - - client := store.NewRemoteClient(remote) - db := NewRawStore(client) - block, err := db.readBlock(1, 6008149) - if err != nil { - panic(err) - } - - ethBlock, receipts, traces, err := EthParse(block) - if err != nil { - t.Errorf("failed to parse block: %v", err) - } - for i, transaction := range ethBlock.Transactions() { - if got, want := receipts[i].TxHash, transaction.Hash(); got != want { - t.Errorf("got %v, want %v", got, want) - } - if got, want := traces[i].TxHash, transaction.Hash().Hex(); got != want { - t.Errorf("got %v, want %v", got, want) - } - } } -var testFullBlock = FullBlockRawData{ +var testFullBlock = FullBlockData{ ChainID: 1, BlockNumber: testBlockNumber, BlockHash: common.HexToHash(testBlockHash).Bytes(), @@ -109,7 +58,7 @@ var testFullBlock = FullBlockRawData{ Uncles: []byte(testUncles), } -var testTwoUnclesFullBlock = FullBlockRawData{ +var testTwoUnclesFullBlock = FullBlockData{ ChainID: 1, BlockNumber: testTwoUnclesBlockNumber, BlockUnclesCount: 2, diff --git a/backend/pkg/commons/db2/tables.go b/backend/pkg/commons/db2/raw/tables.go similarity index 83% rename from backend/pkg/commons/db2/tables.go rename to backend/pkg/commons/db2/raw/tables.go index da877b811..7cb44872f 100644 --- a/backend/pkg/commons/db2/tables.go +++ b/backend/pkg/commons/db2/raw/tables.go @@ -1,6 +1,6 @@ -package db2 +package raw -const BlocksRawTable = "blocks-RawSchema" +const BlocksRawTable = "blocks-Schema" const BT_COLUMNFAMILY_BLOCK = "b" const BT_COLUMN_BLOCK = "b" @@ -13,7 +13,7 @@ const BT_COLUMN_UNCLES = "u" const MAX_EL_BLOCK_NUMBER = int64(1_000_000_000_000 - 1) -var RawSchema = map[string][]string{ +var Schema = map[string][]string{ BlocksRawTable: { BT_COLUMNFAMILY_BLOCK, BT_COLUMNFAMILY_RECEIPTS, diff --git a/backend/pkg/commons/db2/rawtest/raw.go b/backend/pkg/commons/db2/rawtest/raw.go new file mode 100644 index 000000000..a3359ad55 --- /dev/null +++ b/backend/pkg/commons/db2/rawtest/raw.go @@ -0,0 +1,75 @@ +package rawtest + +import ( + "context" + "fmt" + "io" + "net/http" + "strings" + "testing" + + "github.com/gobitfly/beaconchain/internal/th" + "github.com/gobitfly/beaconchain/pkg/commons/db2/database" + "github.com/gobitfly/beaconchain/pkg/commons/db2/databasetest" + "github.com/gobitfly/beaconchain/pkg/commons/db2/raw" +) + +func NewRandSeededStore(t *testing.T) (raw.Store, *th.BlockchainBackend) { + client, admin := databasetest.NewBigTable(t) + bt, err := database.NewBigTableWithClient(context.Background(), client, admin, raw.Schema) + if err != nil { + t.Fatal(err) + } + + db := raw.NewStore(database.Wrap(bt, raw.BlocksRawTable, "")) + + backend := th.NewBackend(t) + for i := 0; i < 10; i++ { + temp := th.CreateEOA(t) + backend.FundOneEther(t, temp.From) + } + lastBlock, err := backend.Client().BlockNumber(context.Background()) + if err != nil { + t.Fatal(err) + } + var blocks []raw.FullBlockData + for i := uint64(0); i <= lastBlock; i++ { + blocks = append(blocks, makeRawBlock(backend.Endpoint, uint64(backend.ChainID), i)) + } + if err := db.AddBlocks(blocks); err != nil { + t.Fatal(err) + } + + return db, backend +} + +func makeRawBlock(endpoint string, chainID uint64, block uint64) raw.FullBlockData { + getReceipts := `{"jsonrpc":"2.0","method":"eth_getBlockReceipts","params":["0x%x"],"id":%d}` + getBlock := `{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["0x%x", true],"id":%d}` + getTraces := `{"jsonrpc":"2.0","method":"debug_traceBlockByNumber","params":["0x%x", {"tracer": "callTracer"}],"id":%d}` + id := 1 + + return raw.FullBlockData{ + ChainID: chainID, + BlockNumber: int64(block), + BlockHash: nil, + BlockUnclesCount: 0, + BlockTxs: nil, + Block: httpCall(endpoint, fmt.Sprintf(getBlock, block, id)), + Receipts: httpCall(endpoint, fmt.Sprintf(getReceipts, block, id)), + Traces: httpCall(endpoint, fmt.Sprintf(getTraces, block, id)), + Uncles: nil, + } +} + +func httpCall(endpoint string, body string) []byte { + resp, err := http.Post(endpoint, "application/json", strings.NewReader(body)) + if err != nil { + panic(err) + } + b, err := io.ReadAll(resp.Body) + if err != nil { + panic(err) + } + return b +}