diff --git a/cmd/serve.go b/cmd/serve.go
index ec662cfc..0bd3e29b 100644
--- a/cmd/serve.go
+++ b/cmd/serve.go
@@ -25,7 +25,6 @@ import (
"sync"
"time"
-
"github.com/cerc-io/ipld-eth-server/v4/pkg/log"
"github.com/ethereum/go-ethereum/rpc"
"github.com/mailgun/groupcache/v2"
diff --git a/docker-compose.yml b/docker-compose.yml
index 2051ec71..768f4e57 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -5,7 +5,7 @@ services:
restart: on-failure
depends_on:
- ipld-eth-db
- image: git.vdb.to/cerc-io/ipld-eth-db/ipld-eth-db:v4.2.3-alpha
+ image: git.vdb.to/cerc-io/ipld-eth-db/ipld-eth-db:v5.0.0-alpha
environment:
DATABASE_USER: "vdbm"
DATABASE_NAME: "vulcanize_testing"
diff --git a/go.mod b/go.mod
index ca0fd5f6..649fb16a 100644
--- a/go.mod
+++ b/go.mod
@@ -6,9 +6,10 @@ require (
github.com/cerc-io/eth-ipfs-state-validator/v4 v4.0.10-alpha
github.com/cerc-io/go-eth-state-node-iterator v1.1.9
github.com/cerc-io/ipfs-ethdb/v4 v4.0.10-alpha
+ github.com/cerc-io/ipld-eth-statedb v0.0.3-alpha
github.com/ethereum/go-ethereum v1.10.26
+ github.com/google/uuid v1.3.0
github.com/graph-gophers/graphql-go v1.3.0
- github.com/ipfs/go-block-format v0.0.3
github.com/ipfs/go-cid v0.2.0
github.com/ipfs/go-ipfs-blockstore v1.2.0
github.com/ipfs/go-ipfs-ds-help v1.1.0
@@ -17,7 +18,6 @@ require (
github.com/lib/pq v1.10.6
github.com/machinebox/graphql v0.2.2
github.com/mailgun/groupcache/v2 v2.3.0
- github.com/multiformats/go-multihash v0.2.0
github.com/onsi/ginkgo v1.16.5
github.com/onsi/gomega v1.19.0
github.com/prometheus/client_golang v1.12.1
@@ -77,7 +77,6 @@ require (
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/gopacket v1.1.19 // indirect
- github.com/google/uuid v1.3.0 // indirect
github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/graphql-go/graphql v0.7.9 // indirect
@@ -97,6 +96,7 @@ require (
github.com/ipfs/bbloom v0.0.4 // indirect
github.com/ipfs/go-bitfield v1.0.0 // indirect
github.com/ipfs/go-bitswap v0.8.0 // indirect
+ github.com/ipfs/go-block-format v0.0.3 // indirect
github.com/ipfs/go-blockservice v0.4.0 // indirect
github.com/ipfs/go-cidutil v0.1.0 // indirect
github.com/ipfs/go-datastore v0.5.1 // indirect
@@ -139,14 +139,14 @@ require (
github.com/ipld/go-codec-dagpb v1.4.0 // indirect
github.com/ipld/go-ipld-prime v0.17.0 // indirect
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
- github.com/jackc/pgconn v1.12.1 // indirect
+ github.com/jackc/pgconn v1.14.0 // indirect
github.com/jackc/pgio v1.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
- github.com/jackc/pgproto3/v2 v2.3.0 // indirect
- github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect
- github.com/jackc/pgtype v1.11.0 // indirect
- github.com/jackc/pgx/v4 v4.16.1 // indirect
- github.com/jackc/puddle v1.2.1 // indirect
+ github.com/jackc/pgproto3/v2 v2.3.2 // indirect
+ github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
+ github.com/jackc/pgtype v1.14.0 // indirect
+ github.com/jackc/pgx/v4 v4.18.1 // indirect
+ github.com/jackc/puddle v1.3.0 // indirect
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect
github.com/jbenet/goprocess v0.1.4 // indirect
@@ -211,6 +211,7 @@ require (
github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect
github.com/multiformats/go-multibase v0.1.0 // indirect
github.com/multiformats/go-multicodec v0.5.0 // indirect
+ github.com/multiformats/go-multihash v0.2.0 // indirect
github.com/multiformats/go-multistream v0.3.3 // indirect
github.com/multiformats/go-varint v0.0.6 // indirect
github.com/nxadm/tail v1.4.8 // indirect
@@ -244,8 +245,8 @@ require (
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4 // indirect
- github.com/stretchr/objx v0.2.0 // indirect
- github.com/stretchr/testify v1.7.2 // indirect
+ github.com/stretchr/objx v0.5.0 // indirect
+ github.com/stretchr/testify v1.8.1 // indirect
github.com/subosito/gotenv v1.2.0 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect
github.com/thoas/go-funk v0.9.2 // indirect
@@ -275,14 +276,14 @@ require (
go.uber.org/multierr v1.8.0 // indirect
go.uber.org/zap v1.21.0 // indirect
go4.org v0.0.0-20200411211856-f5505b9728dd // indirect
- golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 // indirect
- golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect
- golang.org/x/net v0.0.0-20220607020251-c690dde0001d // indirect
- golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
- golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
- golang.org/x/text v0.3.7 // indirect
+ golang.org/x/crypto v0.6.0 // indirect
+ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
+ golang.org/x/net v0.6.0 // indirect
+ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
+ golang.org/x/sys v0.5.0 // indirect
+ golang.org/x/text v0.7.0 // indirect
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
- golang.org/x/tools v0.1.10 // indirect
+ golang.org/x/tools v0.1.12 // indirect
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df // indirect
google.golang.org/protobuf v1.28.0 // indirect
gopkg.in/ini.v1 v1.66.4 // indirect
diff --git a/go.sum b/go.sum
index 7d885c28..fde36a00 100644
--- a/go.sum
+++ b/go.sum
@@ -153,6 +153,8 @@ github.com/cerc-io/go-ethereum v1.10.26-statediff-4.2.2-alpha h1:gesMZEbNU+fcAMc
github.com/cerc-io/go-ethereum v1.10.26-statediff-4.2.2-alpha/go.mod h1:lKBVBWksSwBDR/5D9CAxaGQzDPIS3ueWb6idy7X1Shg=
github.com/cerc-io/ipfs-ethdb/v4 v4.0.10-alpha h1:5iqNXeitkj3g7FxyKK/Pz+1HN7Ac9JZzCRj3Lv+uHiw=
github.com/cerc-io/ipfs-ethdb/v4 v4.0.10-alpha/go.mod h1:dPscFRMvTWPKnoZ4U0D9v4bsrw6XdH7sOp8hUrVzOWA=
+github.com/cerc-io/ipld-eth-statedb v0.0.3-alpha h1:7NCJpF2XmOzD0gmQUkvCf00mylkJ/gBfULhsELV2Awk=
+github.com/cerc-io/ipld-eth-statedb v0.0.3-alpha/go.mod h1:Vx8auhxWh7V3qMgx8qo3bdp3ftSiytvXqffEmXvgpIA=
github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
@@ -769,8 +771,9 @@ github.com/jackc/pgconn v1.7.0/go.mod h1:sF/lPpNEMEOp+IYhyQGdAvrG20gWf6A1tKlr0v7
github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY=
github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
-github.com/jackc/pgconn v1.12.1 h1:rsDFzIpRk7xT4B8FufgpCCeyjdNpKyghZeSefViE5W8=
github.com/jackc/pgconn v1.12.1/go.mod h1:ZkhRC59Llhrq3oSfrikvwQ5NaxYExr6twkdkMLaKono=
+github.com/jackc/pgconn v1.14.0 h1:vrbA9Ud87g6JdFWkHTJXppVce58qPIdP7N8y0Ml/A7Q=
+github.com/jackc/pgconn v1.14.0/go.mod h1:9mBNlny0UvkgJdCDvdVHYSjI+8tD2rnKK69Wz8ti++E=
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
@@ -789,11 +792,13 @@ github.com/jackc/pgproto3/v2 v2.0.2/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwX
github.com/jackc/pgproto3/v2 v2.0.5/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
-github.com/jackc/pgproto3/v2 v2.3.0 h1:brH0pCGBDkBW07HWlN/oSBXrmo3WB0UvZd1pIuDcL8Y=
github.com/jackc/pgproto3/v2 v2.3.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
+github.com/jackc/pgproto3/v2 v2.3.2 h1:7eY55bdBeCz1F2fTzSz69QC+pG46jYq9/jtSPiJ5nn0=
+github.com/jackc/pgproto3/v2 v2.3.2/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
-github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg=
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
+github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
+github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
@@ -803,8 +808,9 @@ github.com/jackc/pgtype v1.3.1-0.20200510190516-8cd94a14c75a/go.mod h1:vaogEUkAL
github.com/jackc/pgtype v1.3.1-0.20200606141011-f6355165a91c/go.mod h1:cvk9Bgu/VzJ9/lxTO5R5sf80p0DiucVtN7ZxvaC4GmQ=
github.com/jackc/pgtype v1.4.2/go.mod h1:JCULISAZBFGrHaOXIIFiyfzW5VY0GRitRr8NeJsrdig=
github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM=
-github.com/jackc/pgtype v1.11.0 h1:u4uiGPz/1hryuXzyaBhSk6dnIyyG2683olG2OV+UUgs=
github.com/jackc/pgtype v1.11.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
+github.com/jackc/pgtype v1.14.0 h1:y+xUdabmyMkJLyApYuPj38mW+aAIqCe5uuBB51rH3Vw=
+github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
github.com/jackc/pgx v3.6.2+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
@@ -815,16 +821,18 @@ github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6
github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg=
github.com/jackc/pgx/v4 v4.8.1/go.mod h1:4HOLxrl8wToZJReD04/yB20GDwf4KBYETvlHciCnwW0=
github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs=
-github.com/jackc/pgx/v4 v4.16.1 h1:JzTglcal01DrghUqt+PmzWsZx/Yh7SC/CTQmSBMTd0Y=
github.com/jackc/pgx/v4 v4.16.1/go.mod h1:SIhx0D5hoADaiXZVyv+3gSm3LCIIINTVO0PficsvWGQ=
+github.com/jackc/pgx/v4 v4.18.1 h1:YP7G1KABtKpB5IHrO9vYwSrCOhs7p3uqhvhhQBptya0=
+github.com/jackc/pgx/v4 v4.18.1/go.mod h1:FydWkUyadDmdNH/mHnGob881GawxeEm7TcMCzkb+qQE=
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v1.1.2/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
-github.com/jackc/puddle v1.2.1 h1:gI8os0wpRXFd4FiAY2dWiqRK037tjj3t7rKFeO4X5iw=
github.com/jackc/puddle v1.2.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jackc/puddle v1.3.0 h1:eHK/5clGOatcjX3oWGBO/MpxpbHzSwud5EWTSCI+MX0=
+github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA=
github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
@@ -1734,8 +1742,10 @@ github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
@@ -1744,8 +1754,10 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
@@ -1829,6 +1841,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
@@ -1956,8 +1969,8 @@ golang.org/x/crypto v0.0.0-20210813211128-0a44fdfbc16e/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
-golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
+golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -2002,8 +2015,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o=
-golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -2067,8 +2080,10 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220517181318-183a9ca12b87/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.0.0-20220607020251-c690dde0001d h1:4SFsTMi4UahlKoloni7L4eYzhFRifURQLw+yv0QDCx8=
golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -2093,8 +2108,9 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -2197,11 +2213,14 @@ golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220517195934-5e4e11fc645e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -2210,8 +2229,9 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -2290,8 +2310,8 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20=
-golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
+golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/pkg/debug/backend.go b/pkg/debug/backend.go
index bf4a1b40..258d1708 100644
--- a/pkg/debug/backend.go
+++ b/pkg/debug/backend.go
@@ -42,6 +42,7 @@ type Backend struct {
}
// StateAtBlock retrieves the state database associated with a certain block
+// We can't sub in our ipld-eth-statedb here because to match the expected interface we need to return *state.StateDB not vm.StateDB
func (b *Backend) StateAtBlock(ctx context.Context, block *types.Block, reexec uint64, base *state.StateDB, checkLive, preferDisk bool) (*state.StateDB, error) {
rpcBlockNumber := rpc.BlockNumber(block.NumberU64())
statedb, _, err := b.StateAndHeaderByNumberOrHash(ctx, rpc.BlockNumberOrHashWithNumber(rpcBlockNumber))
diff --git a/pkg/eth/api.go b/pkg/eth/api.go
index 0e923cca..fa932e48 100644
--- a/pkg/eth/api.go
+++ b/pkg/eth/api.go
@@ -28,13 +28,13 @@ import (
"time"
"github.com/cerc-io/ipld-eth-server/v4/pkg/log"
+ ipld_eth_statedb "github.com/cerc-io/ipld-eth-statedb"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth/filters"
@@ -720,7 +720,7 @@ func (pea *PublicEthAPI) localGetLogs(crit filters.FilterCriteria) ([]*types.Log
// If we have a blockHash to filter on, fire off single retrieval query
if crit.BlockHash != nil {
- filteredLogs, err := pea.B.Retriever.RetrieveFilteredLog(tx, filter, 0, crit.BlockHash)
+ filteredLogs, err := pea.B.Retriever.RetrieveFilteredLogs(tx, filter, 0, crit.BlockHash)
if err != nil {
return nil, err
}
@@ -748,7 +748,7 @@ func (pea *PublicEthAPI) localGetLogs(crit filters.FilterCriteria) ([]*types.Log
end := endingBlock.Int64()
var logs []*types.Log
for i := start; i <= end; i++ {
- filteredLogs, err := pea.B.Retriever.RetrieveFilteredLog(tx, filter, i, nil)
+ filteredLogs, err := pea.B.Retriever.RetrieveFilteredLogs(tx, filter, i, nil)
if err != nil {
return nil, err
}
@@ -875,6 +875,7 @@ func (pea *PublicEthAPI) GetProof(ctx context.Context, address common.Address, s
return nil, err
}
+// this continues to use ipfs-ethdb based geth StateDB as it requires trie access
func (pea *PublicEthAPI) localGetProof(ctx context.Context, address common.Address, storageKeys []string, blockNrOrHash rpc.BlockNumberOrHash) (*AccountResult, error) {
state, _, err := pea.B.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
if state == nil || err != nil {
@@ -977,7 +978,7 @@ type OverrideAccount struct {
type StateOverride map[common.Address]OverrideAccount
// Apply overrides the fields of specified accounts into the given state.
-func (diff *StateOverride) Apply(state *state.StateDB) error {
+func (diff *StateOverride) Apply(state *ipld_eth_statedb.StateDB) error {
if diff == nil {
return nil
}
@@ -1054,7 +1055,7 @@ func DoCall(ctx context.Context, b *Backend, args CallArgs, blockNrOrHash rpc.Bl
log.Debugxf(ctx, "Executing EVM call finished %s runtime %s", time.Now().String(), time.Since(start).String())
}(time.Now())
- state, header, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash)
+ state, header, err := b.IPLDStateDBAndHeaderByNumberOrHash(ctx, blockNrOrHash)
if state == nil || err != nil {
return nil, err
}
diff --git a/pkg/eth/backend.go b/pkg/eth/backend.go
index 6d92f994..11c79342 100644
--- a/pkg/eth/backend.go
+++ b/pkg/eth/backend.go
@@ -23,12 +23,13 @@ import (
"errors"
"fmt"
"math/big"
- "strconv"
"time"
validator "github.com/cerc-io/eth-ipfs-state-validator/v4/pkg"
ipfsethdb "github.com/cerc-io/ipfs-ethdb/v4/postgres"
"github.com/cerc-io/ipld-eth-server/v4/pkg/log"
+ "github.com/cerc-io/ipld-eth-server/v4/pkg/shared"
+ ipld_eth_statedb "github.com/cerc-io/ipld-eth-statedb"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/consensus"
@@ -45,12 +46,8 @@ import (
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc"
ethServerShared "github.com/ethereum/go-ethereum/statediff/indexer/shared"
- sdtrie "github.com/ethereum/go-ethereum/statediff/trie_helpers"
- sdtypes "github.com/ethereum/go-ethereum/statediff/types"
"github.com/ethereum/go-ethereum/trie"
"github.com/jmoiron/sqlx"
-
- "github.com/cerc-io/ipld-eth-server/v4/pkg/shared"
)
var (
@@ -61,43 +58,6 @@ var (
errMultipleHeadersForHash = errors.New("more than one headers for the given hash")
errTxHashNotFound = errors.New("transaction for hash not found")
errTxHashInMultipleBlocks = errors.New("transaction for hash found in more than one canonical block")
-
- // errMissingSignature is returned if a block's extra-data section doesn't seem
- // to contain a 65 byte secp256k1 signature.
-)
-
-const (
- RetrieveCanonicalBlockHashByNumber = `SELECT block_hash
- FROM canonical_header_hash($1) AS block_hash
- WHERE block_hash IS NOT NULL`
- RetrieveCanonicalHeaderByNumber = `SELECT cid, data FROM eth.header_cids
- INNER JOIN public.blocks ON (
- header_cids.mh_key = blocks.key
- AND header_cids.block_number = blocks.block_number
- )
- WHERE block_hash = (SELECT canonical_header_hash($1))`
- RetrieveTD = `SELECT CAST(td as Text) FROM eth.header_cids
- WHERE header_cids.block_hash = $1`
- RetrieveRPCTransaction = `SELECT blocks.data, header_id, transaction_cids.block_number, index
- FROM public.blocks, eth.transaction_cids
- WHERE blocks.key = transaction_cids.mh_key
- AND blocks.block_number = transaction_cids.block_number
- AND transaction_cids.tx_hash = $1
- AND transaction_cids.header_id = (SELECT canonical_header_hash(transaction_cids.block_number))`
- RetrieveCodeHashByLeafKeyAndBlockHash = `SELECT code_hash FROM eth.state_accounts, eth.state_cids, eth.header_cids
- WHERE state_accounts.header_id = state_cids.header_id
- AND state_accounts.state_path = state_cids.state_path
- AND state_accounts.block_number = state_cids.block_number
- AND state_cids.header_id = header_cids.block_hash
- AND state_cids.block_number = header_cids.block_number
- AND state_leaf_key = $1
- AND header_cids.block_number <= (SELECT block_number
- FROM eth.header_cids
- WHERE block_hash = $2)
- AND header_cids.block_hash = (SELECT canonical_header_hash(header_cids.block_number))
- ORDER BY header_cids.block_number DESC
- LIMIT 1`
- RetrieveCodeByMhKey = `SELECT data FROM public.blocks WHERE key = $1`
)
const (
@@ -109,12 +69,13 @@ type Backend struct {
DB *sqlx.DB
// postgres db interfaces
- Retriever *CIDRetriever
- IPLDRetriever *IPLDRetriever
+ Retriever *Retriever
// ethereum interfaces
EthDB ethdb.Database
StateDatabase state.Database
+ // We'll use this state.Database for eth_call and any place we don't need trie access
+ IpldStateDatabase ipld_eth_statedb.StateDatabase
Config *Config
}
@@ -135,7 +96,7 @@ func NewEthBackend(db *sqlx.DB, c *Config) (*Backend, error) {
groupName = StateDBGroupCacheName
}
- r := NewCIDRetriever(db)
+ r := NewRetriever(db)
ethDB := ipfsethdb.NewDatabase(db, ipfsethdb.CacheConfig{
Name: groupName,
Size: gcc.StateDB.CacheSizeInMB * 1024 * 1024,
@@ -143,14 +104,17 @@ func NewEthBackend(db *sqlx.DB, c *Config) (*Backend, error) {
})
logStateDBStatsOnTimer(ethDB.(*ipfsethdb.Database), gcc)
-
+ ipldStateDB, err := ipld_eth_statedb.NewStateDatabaseWithSqlxPool(db)
+ if err != nil {
+ return nil, err
+ }
return &Backend{
- DB: db,
- Retriever: r,
- IPLDRetriever: NewIPLDRetriever(db),
- EthDB: ethDB,
- StateDatabase: state.NewDatabase(ethDB),
- Config: c,
+ DB: db,
+ Retriever: r,
+ EthDB: ethDB,
+ StateDatabase: state.NewDatabase(ethDB),
+ IpldStateDatabase: ipldStateDB,
+ Config: c,
}, nil
}
@@ -208,7 +172,7 @@ func (b *Backend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.He
}
}()
- _, headerRLP, err := b.IPLDRetriever.RetrieveHeaderByHash(tx, hash)
+ _, headerRLP, err := b.Retriever.RetrieveHeaderByHash(tx, hash)
if err != nil {
return nil, err
}
@@ -374,21 +338,11 @@ func (b *Backend) BlockByHash(ctx context.Context, hash common.Hash) (*types.Blo
return nil, err
}
- // When num. of uncles = 2,
- // Check if calculated uncle hash matches the one in header
- // If not, re-order the two uncles
- // Assumption: Max num. of uncles in mainnet = 2
- if len(uncles) == 2 {
- uncleHash := types.CalcUncleHash(uncles)
- if uncleHash != header.UncleHash {
- uncles[0], uncles[1] = uncles[1], uncles[0]
-
- uncleHash = types.CalcUncleHash(uncles)
- // Check if uncle hash matches after re-ordering
- if uncleHash != header.UncleHash {
- log.Error("uncle hash mismatch for block hash: ", hash.Hex())
- }
- }
+ // We should not have any non-determinism in the ordering of the uncles returned to us now
+ uncleHash := types.CalcUncleHash(uncles)
+ // Check if uncle hash matches expected hash
+ if uncleHash != header.UncleHash {
+ log.Error("uncle hash mismatch for block hash: ", hash.Hex())
}
// Fetch transactions
@@ -411,7 +365,7 @@ func (b *Backend) BlockByHash(ctx context.Context, hash common.Hash) (*types.Blo
// GetHeaderByBlockHash retrieves header for a provided block hash
func (b *Backend) GetHeaderByBlockHash(tx *sqlx.Tx, hash common.Hash) (*types.Header, error) {
- _, headerRLP, err := b.IPLDRetriever.RetrieveHeaderByHash(tx, hash)
+ _, headerRLP, err := b.Retriever.RetrieveHeaderByHash(tx, hash)
if err != nil {
return nil, err
}
@@ -422,20 +376,14 @@ func (b *Backend) GetHeaderByBlockHash(tx *sqlx.Tx, hash common.Hash) (*types.He
// GetUnclesByBlockHash retrieves uncles for a provided block hash
func (b *Backend) GetUnclesByBlockHash(tx *sqlx.Tx, hash common.Hash) ([]*types.Header, error) {
- _, uncleBytes, err := b.IPLDRetriever.RetrieveUnclesByBlockHash(tx, hash)
+ _, uncleBytes, err := b.Retriever.RetrieveUnclesByBlockHash(tx, hash)
if err != nil {
return nil, err
}
- uncles := make([]*types.Header, len(uncleBytes))
- for i, bytes := range uncleBytes {
- var uncle types.Header
- err = rlp.DecodeBytes(bytes, &uncle)
- if err != nil {
- return nil, err
- }
-
- uncles[i] = &uncle
+ uncles := make([]*types.Header, 0)
+ if err := rlp.DecodeBytes(uncleBytes, uncles); err != nil {
+ return nil, err
}
return uncles, nil
@@ -443,20 +391,14 @@ func (b *Backend) GetUnclesByBlockHash(tx *sqlx.Tx, hash common.Hash) ([]*types.
// GetUnclesByBlockHashAndNumber retrieves uncles for a provided block hash and number
func (b *Backend) GetUnclesByBlockHashAndNumber(tx *sqlx.Tx, hash common.Hash, number uint64) ([]*types.Header, error) {
- _, uncleBytes, err := b.IPLDRetriever.RetrieveUncles(tx, hash, number)
+ _, uncleBytes, err := b.Retriever.RetrieveUncles(tx, hash, number)
if err != nil {
return nil, err
}
- uncles := make([]*types.Header, len(uncleBytes))
- for i, bytes := range uncleBytes {
- var uncle types.Header
- err = rlp.DecodeBytes(bytes, &uncle)
- if err != nil {
- return nil, err
- }
-
- uncles[i] = &uncle
+ uncles := make([]*types.Header, 0)
+ if err := rlp.DecodeBytes(uncleBytes, uncles); err != nil {
+ return nil, err
}
return uncles, nil
@@ -464,7 +406,7 @@ func (b *Backend) GetUnclesByBlockHashAndNumber(tx *sqlx.Tx, hash common.Hash, n
// GetTransactionsByBlockHash retrieves transactions for a provided block hash
func (b *Backend) GetTransactionsByBlockHash(tx *sqlx.Tx, hash common.Hash) (types.Transactions, error) {
- _, transactionBytes, err := b.IPLDRetriever.RetrieveTransactionsByBlockHash(tx, hash)
+ _, transactionBytes, err := b.Retriever.RetrieveTransactionsByBlockHash(tx, hash)
if err != nil {
return nil, err
}
@@ -484,7 +426,7 @@ func (b *Backend) GetTransactionsByBlockHash(tx *sqlx.Tx, hash common.Hash) (typ
// GetTransactionsByBlockHashAndNumber retrieves transactions for a provided block hash and number
func (b *Backend) GetTransactionsByBlockHashAndNumber(tx *sqlx.Tx, hash common.Hash, number uint64) (types.Transactions, error) {
- _, transactionBytes, err := b.IPLDRetriever.RetrieveTransactions(tx, hash, number)
+ _, transactionBytes, err := b.Retriever.RetrieveTransactions(tx, hash, number)
if err != nil {
return nil, err
}
@@ -504,7 +446,7 @@ func (b *Backend) GetTransactionsByBlockHashAndNumber(tx *sqlx.Tx, hash common.H
// GetReceiptsByBlockHash retrieves receipts for a provided block hash
func (b *Backend) GetReceiptsByBlockHash(tx *sqlx.Tx, hash common.Hash) (types.Receipts, error) {
- _, receiptBytes, txs, err := b.IPLDRetriever.RetrieveReceiptsByBlockHash(tx, hash)
+ _, receiptBytes, txs, err := b.Retriever.RetrieveReceiptsByBlockHash(tx, hash)
if err != nil {
return nil, err
}
@@ -522,7 +464,7 @@ func (b *Backend) GetReceiptsByBlockHash(tx *sqlx.Tx, hash common.Hash) (types.R
// GetReceiptsByBlockHashAndNumber retrieves receipts for a provided block hash and number
func (b *Backend) GetReceiptsByBlockHashAndNumber(tx *sqlx.Tx, hash common.Hash, number uint64) (types.Receipts, error) {
- _, receiptBytes, txs, err := b.IPLDRetriever.RetrieveReceipts(tx, hash, number)
+ _, receiptBytes, txs, err := b.Retriever.RetrieveReceipts(tx, hash, number)
if err != nil {
return nil, err
}
@@ -585,11 +527,10 @@ func (b *Backend) GetReceipts(ctx context.Context, hash common.Hash) (types.Rece
}
}()
- headerCID, err := b.Retriever.RetrieveHeaderCIDByHash(tx, hash)
+ blockNumber, err := b.Retriever.RetrieveBlockNumberByHash(tx, hash)
if err != nil {
return nil, err
}
- blockNumber, _ := strconv.ParseUint(string(headerCID.BlockNumber), 10, 64)
return b.GetReceiptsByBlockHashAndNumber(tx, hash, blockNumber)
}
@@ -612,7 +553,7 @@ func (b *Backend) GetLogs(ctx context.Context, hash common.Hash, number uint64)
}
}()
- _, receiptBytes, txs, err := b.IPLDRetriever.RetrieveReceipts(tx, hash, number)
+ _, receiptBytes, txs, err := b.Retriever.RetrieveReceipts(tx, hash, number)
if err != nil {
return nil, err
}
@@ -658,6 +599,32 @@ func (b *Backend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHas
return nil, nil, errors.New("invalid arguments; neither block nor hash specified")
}
+// IPLDStateDBAndHeaderByNumberOrHash returns the statedb and header for the provided block number or hash
+func (b *Backend) IPLDStateDBAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*ipld_eth_statedb.StateDB, *types.Header, error) {
+ if blockNr, ok := blockNrOrHash.Number(); ok {
+ return b.IPLDStateDBAndHeaderByNumber(ctx, blockNr)
+ }
+ if hash, ok := blockNrOrHash.Hash(); ok {
+ header, err := b.HeaderByHash(ctx, hash)
+ if err != nil {
+ return nil, nil, err
+ }
+ if header == nil {
+ return nil, nil, errors.New("header for hash not found")
+ }
+ canonicalHash, err := b.GetCanonicalHash(header.Number.Uint64())
+ if err != nil {
+ return nil, nil, err
+ }
+ if blockNrOrHash.RequireCanonical && canonicalHash != hash {
+ return nil, nil, errors.New("hash is not currently canonical")
+ }
+ stateDB, err := ipld_eth_statedb.New(header.Root, b.IpldStateDatabase)
+ return stateDB, header, err
+ }
+ return nil, nil, errors.New("invalid arguments; neither block nor hash specified")
+}
+
// StateAndHeaderByNumber returns the statedb and header for a provided block number
func (b *Backend) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error) {
// Pending state is only known by the miner
@@ -676,6 +643,24 @@ func (b *Backend) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNu
return stateDb, header, err
}
+// IPLDStateDBAndHeaderByNumber returns the statedb and header for a provided block number
+func (b *Backend) IPLDStateDBAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*ipld_eth_statedb.StateDB, *types.Header, error) {
+ // Pending state is only known by the miner
+ if number == rpc.PendingBlockNumber {
+ return nil, nil, errPendingBlockNumber
+ }
+ // Otherwise resolve the block number and return its state
+ header, err := b.HeaderByNumber(ctx, number)
+ if err != nil {
+ return nil, nil, err
+ }
+ if header == nil {
+ return nil, nil, errors.New("header not found")
+ }
+ stateDb, err := ipld_eth_statedb.New(header.Root, b.IpldStateDatabase)
+ return stateDb, header, err
+}
+
// GetCanonicalHash gets the canonical hash for the provided number, if there is one
func (b *Backend) GetCanonicalHash(number uint64) (common.Hash, error) {
var hashResult string
@@ -697,11 +682,11 @@ func (b *Backend) GetCanonicalHeader(number uint64) (string, []byte, error) {
}
// GetEVM constructs and returns a vm.EVM
-func (b *Backend) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header) (*vm.EVM, func() error, error) {
+func (b *Backend) GetEVM(ctx context.Context, msg core.Message, state vm.StateDB, header *types.Header) (*vm.EVM, func() error, error) {
vmError := func() error { return nil }
txContext := core.NewEVMTxContext(msg)
- context := core.NewEVMBlockContext(header, b, nil)
- return vm.NewEVM(context, txContext, state, b.Config.ChainConfig, b.Config.VMConfig), vmError, nil
+ blockContext := core.NewEVMBlockContext(header, b, nil)
+ return vm.NewEVM(blockContext, txContext, state, b.Config.ChainConfig, b.Config.VMConfig), vmError, nil
}
// GetAccountByNumberOrHash returns the account object for the provided address at the block corresponding to the provided number or hash
@@ -753,7 +738,7 @@ func (b *Backend) GetAccountByHash(ctx context.Context, address common.Address,
return nil, err
}
- _, accountRlp, err := b.IPLDRetriever.RetrieveAccountByAddressAndBlockHash(address, hash)
+ _, accountRlp, err := b.Retriever.RetrieveAccountByAddressAndBlockHash(address, hash)
if err != nil {
return nil, err
}
@@ -884,7 +869,7 @@ func (b *Backend) GetStorageByHash(ctx context.Context, address common.Address,
return nil, err
}
- _, _, storageRlp, err := b.IPLDRetriever.RetrieveStorageAtByAddressAndStorageSlotAndBlockHash(address, key, hash)
+ _, _, storageRlp, err := b.Retriever.RetrieveStorageAtByAddressAndStorageSlotAndBlockHash(address, key, hash)
return storageRlp, err
}
@@ -961,7 +946,7 @@ func (b *Backend) getSliceStem(headPath []byte, t state.Trie, response *GetSlice
if depthReached > metaData.maxDepth {
metaData.maxDepth = depthReached
}
- if node.NodeType == sdtypes.Leaf {
+ if node.NodeType == Leaf {
metaData.leafCount++
}
leavesFetchTime += leafFetchTime
@@ -1003,7 +988,7 @@ func (b *Backend) getSliceHead(headPath []byte, t state.Trie, response *GetSlice
if depthReached > metaData.maxDepth {
metaData.maxDepth = depthReached
}
- if node.NodeType == sdtypes.Leaf {
+ if node.NodeType == Leaf {
metaData.leafCount++
}
@@ -1045,7 +1030,7 @@ func (b *Backend) getSliceTrie(headPath []byte, t state.Trie, response *GetSlice
continue
}
- node, nodeElements, err := sdtrie.ResolveNode(it, b.StateDatabase.TrieDB())
+ node, nodeElements, err := ResolveNodeIt(it, b.StateDatabase.TrieDB())
if err != nil {
return err
}
@@ -1060,7 +1045,7 @@ func (b *Backend) getSliceTrie(headPath []byte, t state.Trie, response *GetSlice
if depthReached > metaData.maxDepth {
metaData.maxDepth = depthReached
}
- if node.NodeType == sdtypes.Leaf {
+ if node.NodeType == Leaf {
metaData.leafCount++
}
leavesFetchTime += leafFetchTime
diff --git a/pkg/eth/backend_utils.go b/pkg/eth/backend_utils.go
index 68655604..bc200cb3 100644
--- a/pkg/eth/backend_utils.go
+++ b/pkg/eth/backend_utils.go
@@ -35,8 +35,6 @@ import (
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc"
- sdtrie "github.com/ethereum/go-ethereum/statediff/trie_helpers"
- sdtypes "github.com/ethereum/go-ethereum/statediff/types"
"github.com/ethereum/go-ethereum/trie"
)
@@ -334,7 +332,7 @@ func fillSliceNodeData(
ethDB ethdb.KeyValueReader,
nodesMap map[string]string,
leavesMap map[string]GetSliceResponseAccount,
- node sdtypes.StateNode,
+ node StateNode,
nodeElements []interface{},
storage bool,
) (int64, error) {
@@ -344,7 +342,7 @@ func fillSliceNodeData(
// Extract account data if it's a Leaf node
leafStartTime := makeTimestamp()
- if node.NodeType == sdtypes.Leaf && !storage {
+ if node.NodeType == Leaf && !storage {
stateLeafKey, storageRoot, code, err := extractContractAccountInfo(ethDB, node, nodeElements)
if err != nil {
return 0, fmt.Errorf("GetSlice account lookup error: %s", err.Error())
@@ -362,7 +360,7 @@ func fillSliceNodeData(
return makeTimestamp() - leafStartTime, nil
}
-func extractContractAccountInfo(ethDB ethdb.KeyValueReader, node sdtypes.StateNode, nodeElements []interface{}) (string, string, []byte, error) {
+func extractContractAccountInfo(ethDB ethdb.KeyValueReader, node StateNode, nodeElements []interface{}) (string, string, []byte, error) {
var account types.StateAccount
if err := rlp.DecodeBytes(nodeElements[1].([]byte), &account); err != nil {
return "", "", nil, fmt.Errorf("error decoding account for leaf node at path %x nerror: %v", node.Path, err)
@@ -387,23 +385,3 @@ func extractContractAccountInfo(ethDB ethdb.KeyValueReader, node sdtypes.StateNo
return stateLeafKeyString, storageRootString, codeBytes, nil
}
-
-func ResolveNode(path []byte, node []byte, trieDB *trie.Database) (sdtypes.StateNode, []interface{}, error) {
- nodePath := make([]byte, len(path))
- copy(nodePath, path)
-
- var nodeElements []interface{}
- if err := rlp.DecodeBytes(node, &nodeElements); err != nil {
- return sdtypes.StateNode{}, nil, err
- }
-
- ty, err := sdtrie.CheckKeyType(nodeElements)
- if err != nil {
- return sdtypes.StateNode{}, nil, err
- }
- return sdtypes.StateNode{
- NodeType: ty,
- Path: nodePath,
- NodeValue: node,
- }, nodeElements, nil
-}
diff --git a/pkg/eth/cid_retriever.go b/pkg/eth/cid_retriever.go
deleted file mode 100644
index b9b943b4..00000000
--- a/pkg/eth/cid_retriever.go
+++ /dev/null
@@ -1,374 +0,0 @@
-// VulcanizeDB
-// Copyright © 2019 Vulcanize
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
-
-package eth
-
-import (
- "fmt"
- "math/big"
-
- "github.com/cerc-io/ipld-eth-server/v4/pkg/log"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/statediff/indexer/models"
- "github.com/jmoiron/sqlx"
- "github.com/lib/pq"
- "gorm.io/driver/postgres"
- "gorm.io/gorm"
-)
-
-// CIDRetriever satisfies the CIDRetriever interface for ethereum
-type CIDRetriever struct {
- db *sqlx.DB
- gormDB *gorm.DB
-}
-
-type IPLDModelRecord struct {
- models.IPLDModel
-}
-
-// TableName overrides the table name used by IPLD
-func (IPLDModelRecord) TableName() string {
- return "public.blocks"
-}
-
-type HeaderCIDRecord struct {
- CID string `gorm:"column:cid"`
- BlockHash string `gorm:"primaryKey"`
- BlockNumber string `gorm:"primaryKey"`
- ParentHash string
- Timestamp uint64
- StateRoot string
- TotalDifficulty string `gorm:"column:td"`
- TxRoot string
- RctRoot string `gorm:"column:receipt_root"`
- UncleRoot string
- Bloom []byte
- MhKey string
-
- // gorm doesn't check if foreign key exists in database.
- // It is required to eager load relations using preload.
- TransactionCIDs []TransactionCIDRecord `gorm:"foreignKey:HeaderID,BlockNumber;references:BlockHash,BlockNumber"`
- IPLD IPLDModelRecord `gorm:"foreignKey:MhKey,BlockNumber;references:Key,BlockNumber"`
-}
-
-// TableName overrides the table name used by HeaderCIDRecord
-func (HeaderCIDRecord) TableName() string {
- return "eth.header_cids"
-}
-
-type TransactionCIDRecord struct {
- CID string `gorm:"column:cid"`
- TxHash string `gorm:"primaryKey"`
- BlockNumber string `gorm:"primaryKey"`
- HeaderID string `gorm:"column:header_id"`
- Index int64
- Src string
- Dst string
- MhKey string
- IPLD IPLDModelRecord `gorm:"foreignKey:MhKey,BlockNumber;references:Key,BlockNumber"`
-}
-
-// TableName overrides the table name used by TransactionCIDRecord
-func (TransactionCIDRecord) TableName() string {
- return "eth.transaction_cids"
-}
-
-// NewCIDRetriever returns a pointer to a new CIDRetriever which supports the CIDRetriever interface
-func NewCIDRetriever(db *sqlx.DB) *CIDRetriever {
- gormDB, err := gorm.Open(postgres.New(postgres.Config{
- Conn: db,
- }), &gorm.Config{})
-
- if err != nil {
- log.Error(err)
- return nil
- }
-
- return &CIDRetriever{
- db: db,
- gormDB: gormDB,
- }
-}
-
-// RetrieveFirstBlockNumber is used to retrieve the first block number in the db
-func (ecr *CIDRetriever) RetrieveFirstBlockNumber() (int64, error) {
- var blockNumber int64
- err := ecr.db.Get(&blockNumber, "SELECT block_number FROM eth.header_cids ORDER BY block_number ASC LIMIT 1")
- return blockNumber, err
-}
-
-// RetrieveLastBlockNumber is used to retrieve the latest block number in the db
-func (ecr *CIDRetriever) RetrieveLastBlockNumber() (int64, error) {
- var blockNumber int64
- err := ecr.db.Get(&blockNumber, "SELECT block_number FROM eth.header_cids ORDER BY block_number DESC LIMIT 1")
- return blockNumber, err
-}
-
-func topicFilterCondition(id *int, topics [][]string, args []interface{}, pgStr string, first bool) (string, []interface{}) {
- for i, topicSet := range topics {
- if len(topicSet) == 0 {
- continue
- }
-
- if !first {
- pgStr += " AND"
- } else {
- first = false
- }
- pgStr += fmt.Sprintf(` eth.log_cids.topic%d = ANY ($%d)`, i, *id)
- args = append(args, pq.Array(topicSet))
- *id++
- }
- return pgStr, args
-}
-
-func logFilterCondition(id *int, pgStr string, args []interface{}, rctFilter ReceiptFilter) (string, []interface{}) {
- if len(rctFilter.LogAddresses) > 0 {
- pgStr += fmt.Sprintf(` AND eth.log_cids.address = ANY ($%d)`, *id)
- args = append(args, pq.Array(rctFilter.LogAddresses))
- *id++
- }
-
- // Filter on topics if there are any
- if hasTopics(rctFilter.Topics) {
- pgStr, args = topicFilterCondition(id, rctFilter.Topics, args, pgStr, false)
- }
-
- return pgStr, args
-}
-
-func receiptFilterConditions(id *int, pgStr string, args []interface{}, rctFilter ReceiptFilter, txHashes []string) (string, []interface{}) {
- rctCond := " AND (receipt_cids.tx_id = ANY ( "
- logQuery := "SELECT rct_id FROM eth.log_cids WHERE"
- if len(rctFilter.LogAddresses) > 0 {
- // Filter on log contract addresses if there are any
- pgStr += fmt.Sprintf(`%s %s eth.log_cids.address = ANY ($%d)`, rctCond, logQuery, *id)
- args = append(args, pq.Array(rctFilter.LogAddresses))
- *id++
-
- // Filter on topics if there are any
- if hasTopics(rctFilter.Topics) {
- pgStr, args = topicFilterCondition(id, rctFilter.Topics, args, pgStr, false)
- }
-
- pgStr += ")"
-
- // Filter on txHashes if there are any, and we are matching txs
- if rctFilter.MatchTxs && len(txHashes) > 0 {
- pgStr += fmt.Sprintf(` OR receipt_cids.tx_id = ANY($%d)`, *id)
- args = append(args, pq.Array(txHashes))
- }
- pgStr += ")"
- } else { // If there are no contract addresses to filter on
- // Filter on topics if there are any
- if hasTopics(rctFilter.Topics) {
- pgStr += rctCond + logQuery
- pgStr, args = topicFilterCondition(id, rctFilter.Topics, args, pgStr, true)
- pgStr += ")"
- // Filter on txHashes if there are any, and we are matching txs
- if rctFilter.MatchTxs && len(txHashes) > 0 {
- pgStr += fmt.Sprintf(` OR receipt_cids.tx_id = ANY($%d)`, *id)
- args = append(args, pq.Array(txHashes))
- }
- pgStr += ")"
- } else if rctFilter.MatchTxs && len(txHashes) > 0 {
- // If there are no contract addresses or topics to filter on,
- // Filter on txHashes if there are any, and we are matching txs
- pgStr += fmt.Sprintf(` AND receipt_cids.tx_id = ANY($%d)`, *id)
- args = append(args, pq.Array(txHashes))
- }
- }
-
- return pgStr, args
-}
-
-// RetrieveFilteredGQLLogs retrieves and returns all the log CIDs provided blockHash that conform to the provided
-// filter parameters.
-func (ecr *CIDRetriever) RetrieveFilteredGQLLogs(tx *sqlx.Tx, rctFilter ReceiptFilter, blockHash *common.Hash, blockNumber *big.Int) ([]LogResult, error) {
- log.Debug("retrieving log cids for receipt ids with block hash", blockHash.String())
- args := make([]interface{}, 0, 4)
- id := 1
- pgStr := `SELECT CAST(eth.log_cids.block_number as Text), eth.log_cids.header_id as block_hash,
- eth.log_cids.leaf_cid, eth.log_cids.index, eth.log_cids.rct_id, eth.log_cids.address,
- eth.log_cids.topic0, eth.log_cids.topic1, eth.log_cids.topic2, eth.log_cids.topic3, eth.log_cids.log_data,
- data, eth.receipt_cids.leaf_cid as cid, eth.receipt_cids.post_status, eth.receipt_cids.tx_id AS tx_hash
- FROM eth.log_cids, eth.receipt_cids, public.blocks
- WHERE eth.log_cids.rct_id = receipt_cids.tx_id
- AND eth.log_cids.header_id = receipt_cids.header_id
- AND eth.log_cids.block_number = receipt_cids.block_number
- AND log_cids.leaf_mh_key = blocks.key
- AND log_cids.block_number = blocks.block_number
- AND receipt_cids.header_id = $1`
-
- args = append(args, blockHash.String())
- id++
-
- if blockNumber != nil {
- pgStr += ` AND receipt_cids.block_number = $2`
- id++
- args = append(args, blockNumber.Int64())
- }
-
- pgStr, args = logFilterCondition(&id, pgStr, args, rctFilter)
- pgStr += ` ORDER BY log_cids.index`
-
- logCIDs := make([]LogResult, 0)
- err := tx.Select(&logCIDs, pgStr, args...)
- if err != nil {
- return nil, err
- }
-
- return logCIDs, nil
-}
-
-// RetrieveFilteredLog retrieves and returns all the log CIDs provided blockHeight or blockHash that conform to the provided
-// filter parameters.
-func (ecr *CIDRetriever) RetrieveFilteredLog(tx *sqlx.Tx, rctFilter ReceiptFilter, blockNumber int64, blockHash *common.Hash) ([]LogResult, error) {
- log.Debug("retrieving log cids for receipt ids")
- args := make([]interface{}, 0, 4)
- pgStr := `SELECT CAST(eth.log_cids.block_number as Text), eth.log_cids.leaf_cid, eth.log_cids.index, eth.log_cids.rct_id,
- eth.log_cids.address, eth.log_cids.topic0, eth.log_cids.topic1, eth.log_cids.topic2, eth.log_cids.topic3,
- eth.log_cids.log_data, eth.transaction_cids.tx_hash, eth.transaction_cids.index as txn_index,
- eth.receipt_cids.leaf_cid as cid, eth.receipt_cids.post_status, header_cids.block_hash
- FROM eth.log_cids, eth.receipt_cids, eth.transaction_cids, eth.header_cids
- WHERE eth.log_cids.rct_id = receipt_cids.tx_id
- AND eth.log_cids.header_id = eth.receipt_cids.header_id
- AND eth.log_cids.block_number = eth.receipt_cids.block_number
- AND receipt_cids.tx_id = transaction_cids.tx_hash
- AND receipt_cids.header_id = transaction_cids.header_id
- AND receipt_cids.block_number = transaction_cids.block_number
- AND transaction_cids.header_id = header_cids.block_hash
- AND transaction_cids.block_number = header_cids.block_number`
- id := 1
- if blockNumber > 0 {
- pgStr += fmt.Sprintf(` AND header_cids.block_number = $%d`, id)
- args = append(args, blockNumber)
- id++
- }
- if blockHash != nil {
- pgStr += fmt.Sprintf(` AND header_cids.block_hash = $%d`, id)
- args = append(args, blockHash.String())
- id++
- }
-
- pgStr, args = logFilterCondition(&id, pgStr, args, rctFilter)
- pgStr += ` ORDER BY log_cids.index`
-
- logCIDs := make([]LogResult, 0)
- err := tx.Select(&logCIDs, pgStr, args...)
- if err != nil {
- return nil, err
- }
-
- return logCIDs, nil
-}
-
-func hasTopics(topics [][]string) bool {
- for _, topicSet := range topics {
- if len(topicSet) > 0 {
- return true
- }
- }
- return false
-}
-
-// RetrieveHeaderCIDByHash returns the header for the given block hash
-func (ecr *CIDRetriever) RetrieveHeaderCIDByHash(tx *sqlx.Tx, blockHash common.Hash) (models.HeaderModel, error) {
- log.Debug("retrieving header cids for block hash ", blockHash.String())
- pgStr := `SELECT block_hash, CAST(block_number as Text), parent_hash, cid, mh_key, CAST(td as Text),
- state_root, uncle_root, tx_root, receipt_root, bloom, timestamp FROM eth.header_cids
- WHERE block_hash = $1`
- var headerCID models.HeaderModel
- return headerCID, tx.Get(&headerCID, pgStr, blockHash.String())
-}
-
-// RetrieveHeaderAndTxCIDsByBlockNumber retrieves header CIDs and their associated tx CIDs by block number
-func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockNumber(blockNumber int64) ([]HeaderCIDRecord, error) {
- log.Debug("retrieving header cids and tx cids for block number ", blockNumber)
-
- var headerCIDs []HeaderCIDRecord
-
- // https://github.com/go-gorm/gorm/issues/4083#issuecomment-778883283
- // Will use join for TransactionCIDs once preload for 1:N is supported.
- err := ecr.gormDB.Preload("TransactionCIDs", func(tx *gorm.DB) *gorm.DB {
- return tx.Select("cid", "tx_hash", "index", "src", "dst", "header_id", "block_number")
- }).Joins("IPLD").Find(&headerCIDs, "header_cids.block_number = ?", blockNumber).Error
-
- if err != nil {
- log.Error("header cid retrieval error")
- return nil, err
- }
-
- return headerCIDs, nil
-}
-
-// RetrieveHeaderAndTxCIDsByBlockHash retrieves header CID and their associated tx CIDs by block hash (and optionally block number)
-func (ecr *CIDRetriever) RetrieveHeaderAndTxCIDsByBlockHash(blockHash common.Hash, blockNumber *big.Int) (HeaderCIDRecord, error) {
- log.Debug("retrieving header cid and tx cids for block hash ", blockHash.String())
-
- var headerCIDs []HeaderCIDRecord
-
- conditions := map[string]interface{}{"block_hash": blockHash.String()}
- if blockNumber != nil {
- conditions["header_cids.block_number"] = blockNumber.Int64()
- }
-
- // https://github.com/go-gorm/gorm/issues/4083#issuecomment-778883283
- // Will use join for TransactionCIDs once preload for 1:N is supported.
- err := ecr.gormDB.Preload("TransactionCIDs", func(tx *gorm.DB) *gorm.DB {
- return tx.Select("cid", "tx_hash", "index", "src", "dst", "header_id", "block_number")
- }).Joins("IPLD").Find(&headerCIDs, conditions).Error
-
- if err != nil {
- log.Error("header cid retrieval error")
- return HeaderCIDRecord{}, err
- }
-
- if len(headerCIDs) == 0 {
- return HeaderCIDRecord{}, errHeaderHashNotFound
- } else if len(headerCIDs) > 1 {
- return HeaderCIDRecord{}, errMultipleHeadersForHash
- }
-
- return headerCIDs[0], nil
-}
-
-// RetrieveTxCIDByHash returns the tx for the given tx hash (and optionally block number)
-func (ecr *CIDRetriever) RetrieveTxCIDByHash(txHash string, blockNumber *big.Int) (TransactionCIDRecord, error) {
- log.Debug("retrieving tx cid for tx hash ", txHash)
-
- var txCIDs []TransactionCIDRecord
-
- var err error
- if blockNumber != nil {
- err = ecr.gormDB.Joins("IPLD").Find(&txCIDs, "tx_hash = ? AND transaction_cids.header_id = (SELECT canonical_header_hash(transaction_cids.block_number)) AND transaction_cids.block_number = ?", txHash, blockNumber.Int64()).Error
- } else {
- err = ecr.gormDB.Joins("IPLD").Find(&txCIDs, "tx_hash = ? AND transaction_cids.header_id = (SELECT canonical_header_hash(transaction_cids.block_number))", txHash).Error
- }
- if err != nil {
- log.Error("tx retrieval error")
- return TransactionCIDRecord{}, err
- }
-
- if len(txCIDs) == 0 {
- return TransactionCIDRecord{}, errTxHashNotFound
- } else if len(txCIDs) > 1 {
- // a transaction can be part of a only one canonical block
- return TransactionCIDRecord{}, errTxHashInMultipleBlocks
- }
-
- return txCIDs[0], nil
-}
diff --git a/pkg/eth/helpers.go b/pkg/eth/helpers.go
index cce23579..fcbf3cac 100644
--- a/pkg/eth/helpers.go
+++ b/pkg/eth/helpers.go
@@ -18,25 +18,8 @@ package eth
import (
"time"
-
- sdtypes "github.com/ethereum/go-ethereum/statediff/types"
)
-func ResolveToNodeType(nodeType int) sdtypes.NodeType {
- switch nodeType {
- case 0:
- return sdtypes.Branch
- case 1:
- return sdtypes.Extension
- case 2:
- return sdtypes.Leaf
- case 3:
- return sdtypes.Removed
- default:
- return sdtypes.Unknown
- }
-}
-
// Timestamp in milliseconds
func makeTimestamp() int64 {
return time.Now().UnixNano() / int64(time.Millisecond)
diff --git a/pkg/eth/interfaces.go b/pkg/eth/interfaces.go
deleted file mode 100644
index 9e2dcae3..00000000
--- a/pkg/eth/interfaces.go
+++ /dev/null
@@ -1,47 +0,0 @@
-// VulcanizeDB
-// Copyright © 2019 Vulcanize
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
-
-package eth
-
-import (
- "context"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/bloombits"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/rpc"
-)
-
-// FilterBackend is the geth interface we need to satisfy to use their filters
-type FilterBackend interface {
- ChainDb() ethdb.Database
- HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error)
- HeaderByHash(ctx context.Context, blockHash common.Hash) (*types.Header, error)
- GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error)
- GetLogs(ctx context.Context, blockHash common.Hash) ([][]*types.Log, error)
-
- SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription
- SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription
- SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription
- SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription
- SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription
-
- BloomStatus() (uint64, uint64)
- ServiceFilter(ctx context.Context, session *bloombits.MatcherSession)
-}
diff --git a/pkg/eth/ipld_retriever.go b/pkg/eth/ipld_retriever.go
deleted file mode 100644
index 51a12cb4..00000000
--- a/pkg/eth/ipld_retriever.go
+++ /dev/null
@@ -1,368 +0,0 @@
-// VulcanizeDB
-// Copyright © 2019 Vulcanize
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
-
-package eth
-
-import (
- "fmt"
- "strconv"
-
- "github.com/cerc-io/ipld-eth-server/v4/pkg/shared"
- "github.com/ethereum/go-ethereum/statediff/trie_helpers"
- sdtypes "github.com/ethereum/go-ethereum/statediff/types"
- "github.com/jmoiron/sqlx"
-
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/rlp"
-)
-
-const (
- RetrieveHeaderByHashPgStr = `SELECT cid, data
- FROM eth.header_cids
- INNER JOIN public.blocks ON (
- header_cids.mh_key = blocks.key
- AND header_cids.block_number = blocks.block_number
- )
- WHERE block_hash = $1`
- RetrieveUnclesPgStr = `SELECT uncle_cids.cid, data
- FROM eth.uncle_cids
- INNER JOIN eth.header_cids ON (
- uncle_cids.header_id = header_cids.block_hash
- AND uncle_cids.block_number = header_cids.block_number
- )
- INNER JOIN public.blocks ON (
- uncle_cids.mh_key = blocks.key
- AND uncle_cids.block_number = blocks.block_number
- )
- WHERE header_cids.block_hash = $1
- AND header_cids.block_number = $2
- ORDER BY uncle_cids.parent_hash`
- RetrieveUnclesByBlockHashPgStr = `SELECT uncle_cids.cid, data
- FROM eth.uncle_cids
- INNER JOIN eth.header_cids ON (
- uncle_cids.header_id = header_cids.block_hash
- AND uncle_cids.block_number = header_cids.block_number
- )
- INNER JOIN public.blocks ON (
- uncle_cids.mh_key = blocks.key
- AND uncle_cids.block_number = blocks.block_number
- )
- WHERE header_cids.block_hash = $1
- ORDER BY uncle_cids.parent_hash`
- RetrieveTransactionsPgStr = `SELECT transaction_cids.cid, data
- FROM eth.transaction_cids
- INNER JOIN eth.header_cids ON (
- transaction_cids.header_id = header_cids.block_hash
- AND transaction_cids.block_number = header_cids.block_number
- )
- INNER JOIN public.blocks ON (
- transaction_cids.mh_key = blocks.key
- AND transaction_cids.block_number = blocks.block_number
- )
- WHERE block_hash = $1
- AND header_cids.block_number = $2
- ORDER BY eth.transaction_cids.index ASC`
- RetrieveTransactionsByBlockHashPgStr = `SELECT transaction_cids.cid, data
- FROM eth.transaction_cids
- INNER JOIN eth.header_cids ON (
- transaction_cids.header_id = header_cids.block_hash
- AND transaction_cids.block_number = header_cids.block_number
- )
- INNER JOIN public.blocks ON (
- transaction_cids.mh_key = blocks.key
- AND transaction_cids.block_number = blocks.block_number
- )
- WHERE block_hash = $1
- ORDER BY eth.transaction_cids.index ASC`
- RetrieveReceiptsPgStr = `SELECT receipt_cids.leaf_cid, data, eth.transaction_cids.tx_hash
- FROM eth.receipt_cids
- INNER JOIN eth.transaction_cids ON (
- receipt_cids.tx_id = transaction_cids.tx_hash
- AND receipt_cids.header_id = transaction_cids.header_id
- AND receipt_cids.block_number = transaction_cids.block_number
- )
- INNER JOIN eth.header_cids ON (
- transaction_cids.header_id = header_cids.block_hash
- AND transaction_cids.block_number = header_cids.block_number
- )
- INNER JOIN public.blocks ON (
- receipt_cids.leaf_mh_key = blocks.key
- AND receipt_cids.block_number = blocks.block_number
- )
- WHERE block_hash = $1
- AND header_cids.block_number = $2
- ORDER BY eth.transaction_cids.index ASC`
- RetrieveReceiptsByBlockHashPgStr = `SELECT receipt_cids.leaf_cid, data, eth.transaction_cids.tx_hash
- FROM eth.receipt_cids
- INNER JOIN eth.transaction_cids ON (
- receipt_cids.tx_id = transaction_cids.tx_hash
- AND receipt_cids.header_id = transaction_cids.header_id
- AND receipt_cids.block_number = transaction_cids.block_number
- )
- INNER JOIN eth.header_cids ON (
- transaction_cids.header_id = header_cids.block_hash
- AND transaction_cids.block_number = header_cids.block_number
- )
- INNER JOIN public.blocks ON (
- receipt_cids.leaf_mh_key = blocks.key
- AND receipt_cids.block_number = blocks.block_number
- )
- WHERE block_hash = $1
- ORDER BY eth.transaction_cids.index ASC`
- RetrieveAccountByLeafKeyAndBlockHashPgStr = `SELECT state_cids.cid, state_cids.mh_key, state_cids.block_number, state_cids.node_type
- FROM eth.state_cids
- INNER JOIN eth.header_cids ON (
- state_cids.header_id = header_cids.block_hash
- AND state_cids.block_number = header_cids.block_number
- )
- WHERE state_leaf_key = $1
- AND header_cids.block_number <= (SELECT block_number
- FROM eth.header_cids
- WHERE block_hash = $2)
- AND header_cids.block_hash = (SELECT canonical_header_hash(header_cids.block_number))
- ORDER BY header_cids.block_number DESC
- LIMIT 1`
- RetrieveStorageLeafByAddressHashAndLeafKeyAndBlockHashPgStr = `SELECT cid, mh_key, block_number, node_type, state_leaf_removed FROM get_storage_at_by_hash($1, $2, $3)`
-)
-
-var EmptyNodeValue = make([]byte, common.HashLength)
-
-type rctIpldResult struct {
- LeafCID string `db:"leaf_cid"`
- Data []byte `db:"data"`
- TxHash string `db:"tx_hash"`
-}
-
-type ipldResult struct {
- CID string `db:"cid"`
- Data []byte `db:"data"`
- TxHash string `db:"tx_hash"`
-}
-
-type IPLDRetriever struct {
- db *sqlx.DB
-}
-
-func NewIPLDRetriever(db *sqlx.DB) *IPLDRetriever {
- return &IPLDRetriever{
- db: db,
- }
-}
-
-// RetrieveHeaderByHash returns the cid and rlp bytes for the header corresponding to the provided block hash
-func (r *IPLDRetriever) RetrieveHeaderByHash(tx *sqlx.Tx, hash common.Hash) (string, []byte, error) {
- headerResult := new(ipldResult)
- return headerResult.CID, headerResult.Data, tx.Get(headerResult, RetrieveHeaderByHashPgStr, hash.Hex())
-}
-
-// RetrieveUncles returns the cids and rlp bytes for the uncles corresponding to the provided block hash, number (of non-omner root block)
-func (r *IPLDRetriever) RetrieveUncles(tx *sqlx.Tx, hash common.Hash, number uint64) ([]string, [][]byte, error) {
- uncleResults := make([]ipldResult, 0)
- if err := tx.Select(&uncleResults, RetrieveUnclesPgStr, hash.Hex(), number); err != nil {
- return nil, nil, err
- }
- cids := make([]string, len(uncleResults))
- uncles := make([][]byte, len(uncleResults))
- for i, res := range uncleResults {
- cids[i] = res.CID
- uncles[i] = res.Data
- }
- return cids, uncles, nil
-}
-
-// RetrieveUnclesByBlockHash returns the cids and rlp bytes for the uncles corresponding to the provided block hash (of non-omner root block)
-func (r *IPLDRetriever) RetrieveUnclesByBlockHash(tx *sqlx.Tx, hash common.Hash) ([]string, [][]byte, error) {
- uncleResults := make([]ipldResult, 0)
- if err := tx.Select(&uncleResults, RetrieveUnclesByBlockHashPgStr, hash.Hex()); err != nil {
- return nil, nil, err
- }
- cids := make([]string, len(uncleResults))
- uncles := make([][]byte, len(uncleResults))
- for i, res := range uncleResults {
- cids[i] = res.CID
- uncles[i] = res.Data
- }
- return cids, uncles, nil
-}
-
-// RetrieveTransactions returns the cids and rlp bytes for the transactions corresponding to the provided block hash, number
-func (r *IPLDRetriever) RetrieveTransactions(tx *sqlx.Tx, hash common.Hash, number uint64) ([]string, [][]byte, error) {
- txResults := make([]ipldResult, 0)
- if err := tx.Select(&txResults, RetrieveTransactionsPgStr, hash.Hex(), number); err != nil {
- return nil, nil, err
- }
- cids := make([]string, len(txResults))
- txs := make([][]byte, len(txResults))
- for i, res := range txResults {
- cids[i] = res.CID
- txs[i] = res.Data
- }
- return cids, txs, nil
-}
-
-// RetrieveTransactionsByBlockHash returns the cids and rlp bytes for the transactions corresponding to the provided block hash
-func (r *IPLDRetriever) RetrieveTransactionsByBlockHash(tx *sqlx.Tx, hash common.Hash) ([]string, [][]byte, error) {
- txResults := make([]ipldResult, 0)
- if err := tx.Select(&txResults, RetrieveTransactionsByBlockHashPgStr, hash.Hex()); err != nil {
- return nil, nil, err
- }
- cids := make([]string, len(txResults))
- txs := make([][]byte, len(txResults))
- for i, res := range txResults {
- cids[i] = res.CID
- txs[i] = res.Data
- }
- return cids, txs, nil
-}
-
-// DecodeLeafNode decodes the leaf node data
-func DecodeLeafNode(node []byte) ([]byte, error) {
- var nodeElements []interface{}
- if err := rlp.DecodeBytes(node, &nodeElements); err != nil {
- return nil, err
- }
- ty, err := trie_helpers.CheckKeyType(nodeElements)
- if err != nil {
- return nil, err
- }
-
- if ty != sdtypes.Leaf {
- return nil, fmt.Errorf("expected leaf node but found %s", ty)
- }
- return nodeElements[1].([]byte), nil
-}
-
-// RetrieveReceipts returns the cids and rlp bytes for the receipts corresponding to the provided block hash, number.
-// cid returned corresponds to the leaf node data which contains the receipt.
-func (r *IPLDRetriever) RetrieveReceipts(tx *sqlx.Tx, hash common.Hash, number uint64) ([]string, [][]byte, []common.Hash, error) {
- rctResults := make([]rctIpldResult, 0)
- if err := tx.Select(&rctResults, RetrieveReceiptsPgStr, hash.Hex(), number); err != nil {
- return nil, nil, nil, err
- }
- cids := make([]string, len(rctResults))
- rcts := make([][]byte, len(rctResults))
- txs := make([]common.Hash, len(rctResults))
-
- for i, res := range rctResults {
- cids[i] = res.LeafCID
- nodeVal, err := DecodeLeafNode(res.Data)
- if err != nil {
- return nil, nil, nil, err
- }
- rcts[i] = nodeVal
- txs[i] = common.HexToHash(res.TxHash)
- }
-
- return cids, rcts, txs, nil
-}
-
-// RetrieveReceiptsByBlockHash returns the cids and rlp bytes for the receipts corresponding to the provided block hash.
-// cid returned corresponds to the leaf node data which contains the receipt.
-func (r *IPLDRetriever) RetrieveReceiptsByBlockHash(tx *sqlx.Tx, hash common.Hash) ([]string, [][]byte, []common.Hash, error) {
- rctResults := make([]rctIpldResult, 0)
- if err := tx.Select(&rctResults, RetrieveReceiptsByBlockHashPgStr, hash.Hex()); err != nil {
- return nil, nil, nil, err
- }
- cids := make([]string, len(rctResults))
- rcts := make([][]byte, len(rctResults))
- txs := make([]common.Hash, len(rctResults))
-
- for i, res := range rctResults {
- cids[i] = res.LeafCID
- nodeVal, err := DecodeLeafNode(res.Data)
- if err != nil {
- return nil, nil, nil, err
- }
- rcts[i] = nodeVal
- txs[i] = common.HexToHash(res.TxHash)
- }
-
- return cids, rcts, txs, nil
-}
-
-type nodeInfo struct {
- CID string `db:"cid"`
- MhKey string `db:"mh_key"`
- BlockNumber string `db:"block_number"`
- Data []byte `db:"data"`
- NodeType int `db:"node_type"`
- StateLeafRemoved bool `db:"state_leaf_removed"`
-}
-
-// RetrieveAccountByAddressAndBlockHash returns the cid and rlp bytes for the account corresponding to the provided address and block hash
-// TODO: ensure this handles deleted accounts appropriately
-func (r *IPLDRetriever) RetrieveAccountByAddressAndBlockHash(address common.Address, hash common.Hash) (string, []byte, error) {
- accountResult := new(nodeInfo)
- leafKey := crypto.Keccak256Hash(address.Bytes())
- if err := r.db.Get(accountResult, RetrieveAccountByLeafKeyAndBlockHashPgStr, leafKey.Hex(), hash.Hex()); err != nil {
- return "", nil, err
- }
-
- if accountResult.NodeType == sdtypes.Removed.Int() {
- return "", EmptyNodeValue, nil
- }
-
- blockNumber, err := strconv.ParseUint(accountResult.BlockNumber, 10, 64)
- if err != nil {
- return "", nil, err
- }
- accountResult.Data, err = shared.FetchIPLD(r.db, accountResult.MhKey, blockNumber)
- if err != nil {
- return "", nil, err
- }
-
- var i []interface{}
- if err := rlp.DecodeBytes(accountResult.Data, &i); err != nil {
- return "", nil, fmt.Errorf("error decoding state leaf node rlp: %s", err.Error())
- }
- if len(i) != 2 {
- return "", nil, fmt.Errorf("eth IPLDRetriever expected state leaf node rlp to decode into two elements")
- }
- return accountResult.CID, i[1].([]byte), nil
-}
-
-// RetrieveStorageAtByAddressAndStorageSlotAndBlockHash returns the cid and rlp bytes for the storage value corresponding to the provided address, storage slot, and block hash
-func (r *IPLDRetriever) RetrieveStorageAtByAddressAndStorageSlotAndBlockHash(address common.Address, key, hash common.Hash) (string, []byte, []byte, error) {
- storageResult := new(nodeInfo)
- stateLeafKey := crypto.Keccak256Hash(address.Bytes())
- storageHash := crypto.Keccak256Hash(key.Bytes())
- if err := r.db.Get(storageResult, RetrieveStorageLeafByAddressHashAndLeafKeyAndBlockHashPgStr, stateLeafKey.Hex(), storageHash.Hex(), hash.Hex()); err != nil {
- return "", nil, nil, err
- }
- if storageResult.StateLeafRemoved || storageResult.NodeType == sdtypes.Removed.Int() {
- return "", EmptyNodeValue, EmptyNodeValue, nil
- }
-
- blockNumber, err := strconv.ParseUint(storageResult.BlockNumber, 10, 64)
- if err != nil {
- return "", nil, nil, err
- }
- storageResult.Data, err = shared.FetchIPLD(r.db, storageResult.MhKey, blockNumber)
- if err != nil {
- return "", nil, nil, err
- }
-
- var i []interface{}
- if err := rlp.DecodeBytes(storageResult.Data, &i); err != nil {
- err = fmt.Errorf("error decoding storage leaf node rlp: %s", err.Error())
- return "", nil, nil, err
- }
- if len(i) != 2 {
- return "", nil, nil, fmt.Errorf("eth IPLDRetriever expected storage leaf node rlp to decode into two elements")
- }
- return storageResult.CID, storageResult.Data, i[1].([]byte), nil
-}
diff --git a/pkg/eth/node_types.go b/pkg/eth/node_types.go
new file mode 100644
index 00000000..f0f1ba15
--- /dev/null
+++ b/pkg/eth/node_types.go
@@ -0,0 +1,116 @@
+package eth
+
+import (
+ "fmt"
+
+ "github.com/ethereum/go-ethereum/rlp"
+ "github.com/ethereum/go-ethereum/trie"
+)
+
+// NodeType for explicitly setting type of node
+type NodeType string
+
+const (
+ Unknown NodeType = "Unknown"
+ Branch NodeType = "Branch"
+ Extension NodeType = "Extension"
+ Leaf NodeType = "Leaf"
+ Removed NodeType = "Removed" // used to represent paths which have been emptied
+)
+
+func (n NodeType) Int() int {
+ switch n {
+ case Branch:
+ return 0
+ case Extension:
+ return 1
+ case Leaf:
+ return 2
+ case Removed:
+ return 3
+ default:
+ return -1
+ }
+}
+
+// CheckKeyType checks what type of key we have
+func CheckKeyType(elements []interface{}) (NodeType, error) {
+ if len(elements) > 2 {
+ return Branch, nil
+ }
+ if len(elements) < 2 {
+ return Unknown, fmt.Errorf("node cannot be less than two elements in length")
+ }
+ switch elements[0].([]byte)[0] / 16 {
+ case '\x00':
+ return Extension, nil
+ case '\x01':
+ return Extension, nil
+ case '\x02':
+ return Leaf, nil
+ case '\x03':
+ return Leaf, nil
+ default:
+ return Unknown, fmt.Errorf("unknown hex prefix")
+ }
+}
+
+// StateNode holds the data for a single state diff node
+type StateNode struct {
+ NodeType NodeType `json:"nodeType" gencodec:"required"`
+ Path []byte `json:"path" gencodec:"required"`
+ NodeValue []byte `json:"value" gencodec:"required"`
+ StorageNodes []StorageNode `json:"storage"`
+ LeafKey []byte `json:"leafKey"`
+}
+
+// StorageNode holds the data for a single storage diff node
+type StorageNode struct {
+ NodeType NodeType `json:"nodeType" gencodec:"required"`
+ Path []byte `json:"path" gencodec:"required"`
+ NodeValue []byte `json:"value" gencodec:"required"`
+ LeafKey []byte `json:"leafKey"`
+}
+
+func ResolveNode(path []byte, node []byte, trieDB *trie.Database) (StateNode, []interface{}, error) {
+ nodePath := make([]byte, len(path))
+ copy(nodePath, path)
+
+ var nodeElements []interface{}
+ if err := rlp.DecodeBytes(node, &nodeElements); err != nil {
+ return StateNode{}, nil, err
+ }
+
+ ty, err := CheckKeyType(nodeElements)
+ if err != nil {
+ return StateNode{}, nil, err
+ }
+ return StateNode{
+ NodeType: ty,
+ Path: nodePath,
+ NodeValue: node,
+ }, nodeElements, nil
+}
+
+// ResolveNodeIt return the state diff node pointed by the iterator.
+func ResolveNodeIt(it trie.NodeIterator, trieDB *trie.Database) (StateNode, []interface{}, error) {
+ nodePath := make([]byte, len(it.Path()))
+ copy(nodePath, it.Path())
+ node, err := trieDB.Node(it.Hash())
+ if err != nil {
+ return StateNode{}, nil, err
+ }
+ var nodeElements []interface{}
+ if err = rlp.DecodeBytes(node, &nodeElements); err != nil {
+ return StateNode{}, nil, err
+ }
+ ty, err := CheckKeyType(nodeElements)
+ if err != nil {
+ return StateNode{}, nil, err
+ }
+ return StateNode{
+ NodeType: ty,
+ Path: nodePath,
+ NodeValue: node,
+ }, nodeElements, nil
+}
diff --git a/pkg/eth/retriever.go b/pkg/eth/retriever.go
new file mode 100644
index 00000000..09fe947e
--- /dev/null
+++ b/pkg/eth/retriever.go
@@ -0,0 +1,543 @@
+// VulcanizeDB
+// Copyright © 2019 Vulcanize
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package eth
+
+import (
+ "fmt"
+ "math/big"
+ "strconv"
+
+ "github.com/cerc-io/ipld-eth-server/v4/pkg/log"
+ "github.com/cerc-io/ipld-eth-server/v4/pkg/shared"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/rlp"
+ "github.com/ethereum/go-ethereum/statediff/indexer/models"
+ "github.com/ethereum/go-ethereum/statediff/trie_helpers"
+ sdtypes "github.com/ethereum/go-ethereum/statediff/types"
+ "github.com/jmoiron/sqlx"
+ "github.com/lib/pq"
+ "gorm.io/driver/postgres"
+ "gorm.io/gorm"
+)
+
+// Retriever is used for fetching
+type Retriever struct {
+ db *sqlx.DB
+ gormDB *gorm.DB
+}
+
+type IPLDModelRecord struct {
+ models.IPLDModel
+}
+
+// TableName overrides the table name used by IPLD
+func (IPLDModelRecord) TableName() string {
+ return "ipld.blocks"
+}
+
+type HeaderCIDRecord struct {
+ CID string `gorm:"column:cid"`
+ BlockHash string `gorm:"primaryKey"`
+ BlockNumber string `gorm:"primaryKey"`
+ ParentHash string
+ Timestamp uint64
+ StateRoot string
+ TotalDifficulty string `gorm:"column:td"`
+ TxRoot string
+ RctRoot string `gorm:"column:receipt_root"`
+ UncleRoot string
+ Bloom []byte
+ MhKey string
+
+ // gorm doesn't check if foreign key exists in database.
+ // It is required to eager load relations using preload.
+ TransactionCIDs []TransactionCIDRecord `gorm:"foreignKey:HeaderID,BlockNumber;references:BlockHash,BlockNumber"`
+ IPLD IPLDModelRecord `gorm:"foreignKey:MhKey,BlockNumber;references:Key,BlockNumber"`
+}
+
+// TableName overrides the table name used by HeaderCIDRecord
+func (HeaderCIDRecord) TableName() string {
+ return "eth.header_cids"
+}
+
+type TransactionCIDRecord struct {
+ CID string `gorm:"column:cid"`
+ TxHash string `gorm:"primaryKey"`
+ BlockNumber string `gorm:"primaryKey"`
+ HeaderID string `gorm:"column:header_id"`
+ Index int64
+ Src string
+ Dst string
+ MhKey string
+ IPLD IPLDModelRecord `gorm:"foreignKey:MhKey,BlockNumber;references:Key,BlockNumber"`
+}
+
+// TableName overrides the table name used by TransactionCIDRecord
+func (TransactionCIDRecord) TableName() string {
+ return "eth.transaction_cids"
+}
+
+// NewRetriever returns a pointer to a new Retriever which supports the Retriever interface
+func NewRetriever(db *sqlx.DB) *Retriever {
+ gormDB, err := gorm.Open(postgres.New(postgres.Config{
+ Conn: db,
+ }), &gorm.Config{})
+
+ if err != nil {
+ log.Error(err)
+ return nil
+ }
+
+ return &Retriever{
+ db: db,
+ gormDB: gormDB,
+ }
+}
+
+// RetrieveFirstBlockNumber is used to retrieve the first block number in the db
+func (r *Retriever) RetrieveFirstBlockNumber() (int64, error) {
+ var blockNumber int64
+ err := r.db.Get(&blockNumber, "SELECT block_number FROM ipld.blocks ORDER BY block_number ASC LIMIT 1")
+ return blockNumber, err
+}
+
+// RetrieveLastBlockNumber is used to retrieve the latest block number in the db
+func (r *Retriever) RetrieveLastBlockNumber() (int64, error) {
+ var blockNumber int64
+ err := r.db.Get(&blockNumber, "SELECT block_number FROM ipld.blocks ORDER BY block_number DESC LIMIT 1")
+ return blockNumber, err
+}
+
+func topicFilterCondition(id *int, topics [][]string, args []interface{}, pgStr string, first bool) (string, []interface{}) {
+ for i, topicSet := range topics {
+ if len(topicSet) == 0 {
+ continue
+ }
+
+ if !first {
+ pgStr += " AND"
+ } else {
+ first = false
+ }
+ pgStr += fmt.Sprintf(` eth.log_cids.topic%d = ANY ($%d)`, i, *id)
+ args = append(args, pq.Array(topicSet))
+ *id++
+ }
+ return pgStr, args
+}
+
+func logFilterCondition(id *int, pgStr string, args []interface{}, rctFilter ReceiptFilter) (string, []interface{}) {
+ if len(rctFilter.LogAddresses) > 0 {
+ pgStr += fmt.Sprintf(` AND eth.log_cids.address = ANY ($%d)`, *id)
+ args = append(args, pq.Array(rctFilter.LogAddresses))
+ *id++
+ }
+
+ // Filter on topics if there are any
+ if hasTopics(rctFilter.Topics) {
+ pgStr, args = topicFilterCondition(id, rctFilter.Topics, args, pgStr, false)
+ }
+
+ return pgStr, args
+}
+
+func receiptFilterConditions(id *int, pgStr string, args []interface{}, rctFilter ReceiptFilter, txHashes []string) (string, []interface{}) {
+ rctCond := " AND (receipt_cids.tx_id = ANY ( "
+ logQuery := "SELECT rct_id FROM eth.log_cids WHERE"
+ if len(rctFilter.LogAddresses) > 0 {
+ // Filter on log contract addresses if there are any
+ pgStr += fmt.Sprintf(`%s %s eth.log_cids.address = ANY ($%d)`, rctCond, logQuery, *id)
+ args = append(args, pq.Array(rctFilter.LogAddresses))
+ *id++
+
+ // Filter on topics if there are any
+ if hasTopics(rctFilter.Topics) {
+ pgStr, args = topicFilterCondition(id, rctFilter.Topics, args, pgStr, false)
+ }
+
+ pgStr += ")"
+
+ // Filter on txHashes if there are any, and we are matching txs
+ if rctFilter.MatchTxs && len(txHashes) > 0 {
+ pgStr += fmt.Sprintf(` OR receipt_cids.tx_id = ANY($%d)`, *id)
+ args = append(args, pq.Array(txHashes))
+ }
+ pgStr += ")"
+ } else { // If there are no contract addresses to filter on
+ // Filter on topics if there are any
+ if hasTopics(rctFilter.Topics) {
+ pgStr += rctCond + logQuery
+ pgStr, args = topicFilterCondition(id, rctFilter.Topics, args, pgStr, true)
+ pgStr += ")"
+ // Filter on txHashes if there are any, and we are matching txs
+ if rctFilter.MatchTxs && len(txHashes) > 0 {
+ pgStr += fmt.Sprintf(` OR receipt_cids.tx_id = ANY($%d)`, *id)
+ args = append(args, pq.Array(txHashes))
+ }
+ pgStr += ")"
+ } else if rctFilter.MatchTxs && len(txHashes) > 0 {
+ // If there are no contract addresses or topics to filter on,
+ // Filter on txHashes if there are any, and we are matching txs
+ pgStr += fmt.Sprintf(` AND receipt_cids.tx_id = ANY($%d)`, *id)
+ args = append(args, pq.Array(txHashes))
+ }
+ }
+
+ return pgStr, args
+}
+
+// RetrieveFilteredGQLLogs retrieves and returns all the log CIDs provided blockHash that conform to the provided
+// filter parameters.
+func (r *Retriever) RetrieveFilteredGQLLogs(tx *sqlx.Tx, rctFilter ReceiptFilter, blockHash *common.Hash, blockNumber *big.Int) ([]LogResult, error) {
+ log.Debug("retrieving log cids for receipt ids with block hash", blockHash.String())
+ args := make([]interface{}, 0, 4)
+ id := 1
+ pgStr := RetrieveFilteredGQLLogs
+ args = append(args, blockHash.String())
+ id++
+
+ if blockNumber != nil {
+ pgStr += ` AND receipt_cids.block_number = $2`
+ id++
+ args = append(args, blockNumber.Int64())
+ }
+
+ pgStr, args = logFilterCondition(&id, pgStr, args, rctFilter)
+ pgStr += ` ORDER BY log_cids.index`
+
+ logCIDs := make([]LogResult, 0)
+ err := tx.Select(&logCIDs, pgStr, args...)
+ if err != nil {
+ return nil, err
+ }
+
+ return logCIDs, nil
+}
+
+// RetrieveFilteredLogs retrieves and returns all the log CIDs provided blockHeight or blockHash that conform to the provided
+// filter parameters.
+func (r *Retriever) RetrieveFilteredLogs(tx *sqlx.Tx, rctFilter ReceiptFilter, blockNumber int64, blockHash *common.Hash) ([]LogResult, error) {
+ log.Debug("retrieving log cids for receipt ids")
+ args := make([]interface{}, 0, 4)
+ pgStr := RetrieveFilteredLogs
+ id := 1
+ if blockNumber > 0 {
+ pgStr += fmt.Sprintf(` AND header_cids.block_number = $%d`, id)
+ args = append(args, blockNumber)
+ id++
+ }
+ if blockHash != nil {
+ pgStr += fmt.Sprintf(` AND header_cids.block_hash = $%d`, id)
+ args = append(args, blockHash.String())
+ id++
+ }
+
+ pgStr, args = logFilterCondition(&id, pgStr, args, rctFilter)
+ pgStr += ` ORDER BY log_cids.index`
+
+ logCIDs := make([]LogResult, 0)
+ err := tx.Select(&logCIDs, pgStr, args...)
+ if err != nil {
+ return nil, err
+ }
+
+ return logCIDs, nil
+}
+
+func hasTopics(topics [][]string) bool {
+ for _, topicSet := range topics {
+ if len(topicSet) > 0 {
+ return true
+ }
+ }
+ return false
+}
+
+// RetrieveBlockNumberByHash returns the block number for the given block hash
+func (r *Retriever) RetrieveBlockNumberByHash(tx *sqlx.Tx, blockHash common.Hash) (uint64, error) {
+ log.Debug("retrieving block number for block hash ", blockHash.String())
+ pgStr := `SELECT CAST(block_number as TEXT) FROM eth.header_cids WHERE block_hash = $1`
+ var blockNumberStr string
+ if err := tx.Get(&blockNumberStr, pgStr, blockHash.String()); err != nil {
+ return 0, err
+ }
+ return strconv.ParseUint(blockNumberStr, 10, 64)
+}
+
+// RetrieveHeaderAndTxCIDsByBlockNumber retrieves header CIDs and their associated tx CIDs by block number
+func (r *Retriever) RetrieveHeaderAndTxCIDsByBlockNumber(blockNumber int64) ([]HeaderCIDRecord, error) {
+ log.Debug("retrieving header cids and tx cids for block number ", blockNumber)
+
+ var headerCIDs []HeaderCIDRecord
+
+ // https://github.com/go-gorm/gorm/issues/4083#issuecomment-778883283
+ // Will use join for TransactionCIDs once preload for 1:N is supported.
+ err := r.gormDB.Preload("TransactionCIDs", func(tx *gorm.DB) *gorm.DB {
+ return tx.Select("cid", "tx_hash", "index", "src", "dst", "header_id", "block_number")
+ }).Joins("IPLD").Find(&headerCIDs, "header_cids.block_number = ?", blockNumber).Error
+
+ if err != nil {
+ log.Error("header cid retrieval error")
+ return nil, err
+ }
+
+ return headerCIDs, nil
+}
+
+// RetrieveHeaderAndTxCIDsByBlockHash retrieves header CID and their associated tx CIDs by block hash (and optionally block number)
+func (r *Retriever) RetrieveHeaderAndTxCIDsByBlockHash(blockHash common.Hash, blockNumber *big.Int) (HeaderCIDRecord, error) {
+ log.Debug("retrieving header cid and tx cids for block hash ", blockHash.String())
+
+ var headerCIDs []HeaderCIDRecord
+
+ conditions := map[string]interface{}{"block_hash": blockHash.String()}
+ if blockNumber != nil {
+ conditions["header_cids.block_number"] = blockNumber.Int64()
+ }
+
+ // https://github.com/go-gorm/gorm/issues/4083#issuecomment-778883283
+ // Will use join for TransactionCIDs once preload for 1:N is supported.
+ err := r.gormDB.Preload("TransactionCIDs", func(tx *gorm.DB) *gorm.DB {
+ return tx.Select("cid", "tx_hash", "index", "src", "dst", "header_id", "block_number")
+ }).Joins("IPLD").Find(&headerCIDs, conditions).Error
+
+ if err != nil {
+ log.Error("header cid retrieval error")
+ return HeaderCIDRecord{}, err
+ }
+
+ if len(headerCIDs) == 0 {
+ return HeaderCIDRecord{}, errHeaderHashNotFound
+ } else if len(headerCIDs) > 1 {
+ return HeaderCIDRecord{}, errMultipleHeadersForHash
+ }
+
+ return headerCIDs[0], nil
+}
+
+// RetrieveTxCIDByHash returns the tx for the given tx hash (and optionally block number)
+func (r *Retriever) RetrieveTxCIDByHash(txHash string, blockNumber *big.Int) (TransactionCIDRecord, error) {
+ log.Debug("retrieving tx cid for tx hash ", txHash)
+
+ var txCIDs []TransactionCIDRecord
+
+ var err error
+ if blockNumber != nil {
+ err = r.gormDB.Joins("IPLD").Find(&txCIDs, "tx_hash = ? AND transaction_cids.header_id = (SELECT canonical_header_hash(transaction_cids.block_number)) AND transaction_cids.block_number = ?", txHash, blockNumber.Int64()).Error
+ } else {
+ err = r.gormDB.Joins("IPLD").Find(&txCIDs, "tx_hash = ? AND transaction_cids.header_id = (SELECT canonical_header_hash(transaction_cids.block_number))", txHash).Error
+ }
+ if err != nil {
+ log.Error("tx retrieval error")
+ return TransactionCIDRecord{}, err
+ }
+
+ if len(txCIDs) == 0 {
+ return TransactionCIDRecord{}, errTxHashNotFound
+ } else if len(txCIDs) > 1 {
+ // a transaction can be part of a only one canonical block
+ return TransactionCIDRecord{}, errTxHashInMultipleBlocks
+ }
+
+ return txCIDs[0], nil
+}
+
+var EmptyNodeValue = make([]byte, common.HashLength)
+
+// RetrieveHeaderByHash returns the cid and rlp bytes for the header corresponding to the provided block hash
+func (r *Retriever) RetrieveHeaderByHash(tx *sqlx.Tx, hash common.Hash) (string, []byte, error) {
+ headerResult := new(ipldResult)
+ return headerResult.CID, headerResult.Data, tx.Get(headerResult, RetrieveHeaderByHashPgStr, hash.Hex())
+}
+
+// RetrieveUncles returns the cid and rlp bytes for the uncle list corresponding to the provided block hash, number (of non-omner root block)
+func (r *Retriever) RetrieveUncles(tx *sqlx.Tx, hash common.Hash, number uint64) (string, []byte, error) {
+ uncleResult := new(ipldResult)
+ if err := tx.Select(uncleResult, RetrieveUnclesPgStr, hash.Hex(), number); err != nil {
+ return "", nil, err
+ }
+ return uncleResult.CID, uncleResult.Data, nil
+}
+
+// RetrieveUnclesByBlockHash returns the cid and rlp bytes for the uncle list corresponding to the provided block hash (of non-omner root block)
+func (r *Retriever) RetrieveUnclesByBlockHash(tx *sqlx.Tx, hash common.Hash) (string, []byte, error) {
+ uncleResult := new(ipldResult)
+ if err := tx.Select(uncleResult, RetrieveUnclesByBlockHashPgStr, hash.Hex()); err != nil {
+ return "", nil, err
+ }
+ return uncleResult.CID, uncleResult.Data, nil
+}
+
+// RetrieveTransactions returns the cids and rlp bytes for the transactions corresponding to the provided block hash, number
+func (r *Retriever) RetrieveTransactions(tx *sqlx.Tx, hash common.Hash, number uint64) ([]string, [][]byte, error) {
+ txResults := make([]ipldResult, 0)
+ if err := tx.Select(&txResults, RetrieveTransactionsPgStr, hash.Hex(), number); err != nil {
+ return nil, nil, err
+ }
+ cids := make([]string, len(txResults))
+ txs := make([][]byte, len(txResults))
+ for i, res := range txResults {
+ cids[i] = res.CID
+ txs[i] = res.Data
+ }
+ return cids, txs, nil
+}
+
+// RetrieveTransactionsByBlockHash returns the cids and rlp bytes for the transactions corresponding to the provided block hash
+func (r *Retriever) RetrieveTransactionsByBlockHash(tx *sqlx.Tx, hash common.Hash) ([]string, [][]byte, error) {
+ txResults := make([]ipldResult, 0)
+ if err := tx.Select(&txResults, RetrieveTransactionsByBlockHashPgStr, hash.Hex()); err != nil {
+ return nil, nil, err
+ }
+ cids := make([]string, len(txResults))
+ txs := make([][]byte, len(txResults))
+ for i, res := range txResults {
+ cids[i] = res.CID
+ txs[i] = res.Data
+ }
+ return cids, txs, nil
+}
+
+// DecodeLeafNode decodes the leaf node data
+func DecodeLeafNode(node []byte) ([]byte, error) {
+ var nodeElements []interface{}
+ if err := rlp.DecodeBytes(node, &nodeElements); err != nil {
+ return nil, err
+ }
+ ty, err := trie_helpers.CheckKeyType(nodeElements)
+ if err != nil {
+ return nil, err
+ }
+
+ if ty != sdtypes.Leaf {
+ return nil, fmt.Errorf("expected leaf node but found %s", ty)
+ }
+ return nodeElements[1].([]byte), nil
+}
+
+// RetrieveReceipts returns the cids and rlp bytes for the receipts corresponding to the provided block hash, number.
+// cid returned corresponds to the leaf node data which contains the receipt.
+func (r *Retriever) RetrieveReceipts(tx *sqlx.Tx, hash common.Hash, number uint64) ([]string, [][]byte, []common.Hash, error) {
+ rctResults := make([]ipldResult, 0)
+ if err := tx.Select(&rctResults, RetrieveReceiptsPgStr, hash.Hex(), number); err != nil {
+ return nil, nil, nil, err
+ }
+ cids := make([]string, len(rctResults))
+ rcts := make([][]byte, len(rctResults))
+ txs := make([]common.Hash, len(rctResults))
+
+ for i, res := range rctResults {
+ cids[i] = res.CID
+ nodeVal, err := DecodeLeafNode(res.Data)
+ if err != nil {
+ return nil, nil, nil, err
+ }
+ rcts[i] = nodeVal
+ txs[i] = common.HexToHash(res.TxHash)
+ }
+
+ return cids, rcts, txs, nil
+}
+
+// RetrieveReceiptsByBlockHash returns the cids and rlp bytes for the receipts corresponding to the provided block hash.
+// cid returned corresponds to the leaf node data which contains the receipt.
+func (r *Retriever) RetrieveReceiptsByBlockHash(tx *sqlx.Tx, hash common.Hash) ([]string, [][]byte, []common.Hash, error) {
+ rctResults := make([]ipldResult, 0)
+ if err := tx.Select(&rctResults, RetrieveReceiptsByBlockHashPgStr, hash.Hex()); err != nil {
+ return nil, nil, nil, err
+ }
+ cids := make([]string, len(rctResults))
+ rcts := make([][]byte, len(rctResults))
+ txs := make([]common.Hash, len(rctResults))
+
+ for i, res := range rctResults {
+ cids[i] = res.CID
+ nodeVal, err := DecodeLeafNode(res.Data)
+ if err != nil {
+ return nil, nil, nil, err
+ }
+ rcts[i] = nodeVal
+ txs[i] = common.HexToHash(res.TxHash)
+ }
+
+ return cids, rcts, txs, nil
+}
+
+// RetrieveAccountByAddressAndBlockHash returns the cid and rlp bytes for the account corresponding to the provided address and block hash
+// TODO: ensure this handles deleted accounts appropriately
+func (r *Retriever) RetrieveAccountByAddressAndBlockHash(address common.Address, hash common.Hash) (string, []byte, error) {
+ accountResult := new(nodeInfo)
+ leafKey := crypto.Keccak256Hash(address.Bytes())
+ if err := r.db.Get(accountResult, RetrieveAccountByLeafKeyAndBlockHashPgStr, leafKey.Hex(), hash.Hex()); err != nil {
+ return "", nil, err
+ }
+
+ if accountResult.Removed {
+ return "", EmptyNodeValue, nil
+ }
+
+ blockNumber, err := strconv.ParseUint(accountResult.BlockNumber, 10, 64)
+ if err != nil {
+ return "", nil, err
+ }
+ accountResult.Data, err = shared.FetchIPLD(r.db, accountResult.CID, blockNumber)
+ if err != nil {
+ return "", nil, err
+ }
+
+ var i []interface{}
+ if err := rlp.DecodeBytes(accountResult.Data, &i); err != nil {
+ return "", nil, fmt.Errorf("error decoding state leaf node rlp: %s", err.Error())
+ }
+ if len(i) != 2 {
+ return "", nil, fmt.Errorf("eth Retriever expected state leaf node rlp to decode into two elements")
+ }
+ return accountResult.CID, i[1].([]byte), nil
+}
+
+// RetrieveStorageAtByAddressAndStorageSlotAndBlockHash returns the cid and rlp bytes for the storage value corresponding to the provided address, storage slot, and block hash
+func (r *Retriever) RetrieveStorageAtByAddressAndStorageSlotAndBlockHash(address common.Address, key, hash common.Hash) (string, []byte, []byte, error) {
+ storageResult := new(nodeInfo)
+ stateLeafKey := crypto.Keccak256Hash(address.Bytes())
+ storageHash := crypto.Keccak256Hash(key.Bytes())
+ if err := r.db.Get(storageResult, RetrieveStorageLeafByAddressHashAndLeafKeyAndBlockHashPgStr, stateLeafKey.Hex(), storageHash.Hex(), hash.Hex()); err != nil {
+ return "", nil, nil, err
+ }
+ if storageResult.StateLeafRemoved || storageResult.Removed {
+ return "", EmptyNodeValue, EmptyNodeValue, nil
+ }
+
+ blockNumber, err := strconv.ParseUint(storageResult.BlockNumber, 10, 64)
+ if err != nil {
+ return "", nil, nil, err
+ }
+ storageResult.Data, err = shared.FetchIPLD(r.db, storageResult.CID, blockNumber)
+ if err != nil {
+ return "", nil, nil, err
+ }
+
+ var i []interface{}
+ if err := rlp.DecodeBytes(storageResult.Data, &i); err != nil {
+ err = fmt.Errorf("error decoding storage leaf node rlp: %s", err.Error())
+ return "", nil, nil, err
+ }
+ if len(i) != 2 {
+ return "", nil, nil, fmt.Errorf("eth Retriever expected storage leaf node rlp to decode into two elements")
+ }
+ return storageResult.CID, storageResult.Data, i[1].([]byte), nil
+}
diff --git a/pkg/eth/cid_retriever_test.go b/pkg/eth/retriever_test.go
similarity index 98%
rename from pkg/eth/cid_retriever_test.go
rename to pkg/eth/retriever_test.go
index 2941da0d..b2bb27dd 100644
--- a/pkg/eth/cid_retriever_test.go
+++ b/pkg/eth/retriever_test.go
@@ -33,13 +33,13 @@ var _ = Describe("Retriever", func() {
var (
db *sqlx.DB
diffIndexer interfaces.StateDiffIndexer
- retriever *eth.CIDRetriever
+ retriever *eth.Retriever
)
BeforeEach(func() {
db = shared.SetupDB()
diffIndexer = shared.SetupTestStateDiffIndexer(ctx, params.TestChainConfig, test_helpers.Genesis.Hash())
- retriever = eth.NewCIDRetriever(db)
+ retriever = eth.NewRetriever(db)
})
AfterEach(func() {
shared.TearDownDB(db)
diff --git a/pkg/eth/sql.go b/pkg/eth/sql.go
new file mode 100644
index 00000000..05aae02e
--- /dev/null
+++ b/pkg/eth/sql.go
@@ -0,0 +1,183 @@
+package eth
+
+const (
+ RetrieveHeaderByHashPgStr = `SELECT cid, data
+ FROM eth.header_cids
+ INNER JOIN ipld.blocks ON (
+ header_cids.cid = blocks.key
+ AND header_cids.block_number = blocks.block_number
+ )
+ WHERE block_hash = $1`
+ RetrieveUnclesPgStr = `SELECT uncle_cids.cid, data
+ FROM eth.uncle_cids
+ INNER JOIN eth.header_cids ON (
+ uncle_cids.header_id = header_cids.block_hash
+ AND uncle_cids.block_number = header_cids.block_number
+ )
+ INNER JOIN ipld.blocks ON (
+ uncle_cids.cid = blocks.key
+ AND uncle_cids.block_number = blocks.block_number
+ )
+ WHERE header_cids.block_hash = $1
+ AND header_cids.block_number = $2
+ ORDER BY uncle_cids.parent_hash
+ LIMIT 1`
+ RetrieveUnclesByBlockHashPgStr = `SELECT uncle_cids.cid, data
+ FROM eth.uncle_cids
+ INNER JOIN eth.header_cids ON (
+ uncle_cids.header_id = header_cids.block_hash
+ AND uncle_cids.block_number = header_cids.block_number
+ )
+ INNER JOIN ipld.blocks ON (
+ uncle_cids.cid = blocks.key
+ AND uncle_cids.block_number = blocks.block_number
+ )
+ WHERE header_cids.block_hash = $1
+ ORDER BY uncle_cids.parent_hash
+ LIMIT 1`
+ RetrieveTransactionsPgStr = `SELECT transaction_cids.cid, data
+ FROM eth.transaction_cids
+ INNER JOIN eth.header_cids ON (
+ transaction_cids.header_id = header_cids.block_hash
+ AND transaction_cids.block_number = header_cids.block_number
+ )
+ INNER JOIN ipld.blocks ON (
+ transaction_cids.cid = blocks.key
+ AND transaction_cids.block_number = blocks.block_number
+ )
+ WHERE block_hash = $1
+ AND header_cids.block_number = $2
+ ORDER BY eth.transaction_cids.index ASC`
+ RetrieveTransactionsByBlockHashPgStr = `SELECT transaction_cids.cid, data
+ FROM eth.transaction_cids
+ INNER JOIN eth.header_cids ON (
+ transaction_cids.header_id = header_cids.block_hash
+ AND transaction_cids.block_number = header_cids.block_number
+ )
+ INNER JOIN ipld.blocks ON (
+ transaction_cids.cid = blocks.key
+ AND transaction_cids.block_number = blocks.block_number
+ )
+ WHERE block_hash = $1
+ ORDER BY eth.transaction_cids.index ASC`
+ RetrieveReceiptsPgStr = `SELECT receipt_cids.cid, data, eth.transaction_cids.tx_hash
+ FROM eth.receipt_cids
+ INNER JOIN eth.transaction_cids ON (
+ receipt_cids.tx_id = transaction_cids.tx_hash
+ AND receipt_cids.header_id = transaction_cids.header_id
+ AND receipt_cids.block_number = transaction_cids.block_number
+ )
+ INNER JOIN eth.header_cids ON (
+ transaction_cids.header_id = header_cids.block_hash
+ AND transaction_cids.block_number = header_cids.block_number
+ )
+ INNER JOIN ipld.blocks ON (
+ receipt_cids.cid = blocks.key
+ AND receipt_cids.block_number = blocks.block_number
+ )
+ WHERE block_hash = $1
+ AND header_cids.block_number = $2
+ ORDER BY eth.transaction_cids.index ASC`
+ RetrieveReceiptsByBlockHashPgStr = `SELECT receipt_cids.cid, data, eth.transaction_cids.tx_hash
+ FROM eth.receipt_cids
+ INNER JOIN eth.transaction_cids ON (
+ receipt_cids.tx_id = transaction_cids.tx_hash
+ AND receipt_cids.header_id = transaction_cids.header_id
+ AND receipt_cids.block_number = transaction_cids.block_number
+ )
+ INNER JOIN eth.header_cids ON (
+ transaction_cids.header_id = header_cids.block_hash
+ AND transaction_cids.block_number = header_cids.block_number
+ )
+ INNER JOIN ipld.blocks ON (
+ receipt_cids.cid = blocks.key
+ AND receipt_cids.block_number = blocks.block_number
+ )
+ WHERE block_hash = $1
+ ORDER BY eth.transaction_cids.index ASC`
+ // TODO: join on ipld.blocks and return IPLD object in this query instead of round tripping back to ipld.blocks
+ RetrieveAccountByLeafKeyAndBlockHashPgStr = `SELECT state_cids.cid, state_cids.block_number, state_cids.removed
+ FROM eth.state_cids
+ INNER JOIN eth.header_cids ON (
+ state_cids.header_id = header_cids.block_hash
+ AND state_cids.block_number = header_cids.block_number
+ )
+ WHERE state_leaf_key = $1
+ AND header_cids.block_number <= (SELECT block_number
+ FROM eth.header_cids
+ WHERE block_hash = $2)
+ AND header_cids.block_hash = (SELECT canonical_header_hash(header_cids.block_number))
+ ORDER BY header_cids.block_number DESC
+ LIMIT 1`
+ RetrieveFilteredGQLLogs = `SELECT CAST(eth.log_cids.block_number as TEXT), eth.log_cids.header_id as block_hash,
+ eth.log_cids.cid, eth.log_cids.index, eth.log_cids.rct_id, eth.log_cids.address,
+ eth.log_cids.topic0, eth.log_cids.topic1, eth.log_cids.topic2, eth.log_cids.topic3, eth.log_cids.log_data,
+ data, eth.receipt_cids.cid, eth.receipt_cids.post_status, eth.receipt_cids.tx_id AS tx_hash
+ FROM eth.log_cids, eth.receipt_cids, ipld.blocks
+ WHERE eth.log_cids.rct_id = receipt_cids.tx_id
+ AND eth.log_cids.header_id = receipt_cids.header_id
+ AND eth.log_cids.block_number = receipt_cids.block_number
+ AND log_cids.cid = blocks.key
+ AND log_cids.block_number = blocks.block_number
+ AND receipt_cids.header_id = $1`
+ RetrieveFilteredLogs = `SELECT CAST(eth.log_cids.block_number as TEXT), eth.log_cids.cid, eth.log_cids.index, eth.log_cids.rct_id,
+ eth.log_cids.address, eth.log_cids.topic0, eth.log_cids.topic1, eth.log_cids.topic2, eth.log_cids.topic3,
+ eth.log_cids.log_data, eth.transaction_cids.tx_hash, eth.transaction_cids.index as txn_index,
+ eth.receipt_cids.cid as cid, eth.receipt_cids.post_status, header_cids.block_hash
+ FROM eth.log_cids, eth.receipt_cids, eth.transaction_cids, eth.header_cids
+ WHERE eth.log_cids.rct_id = receipt_cids.tx_id
+ AND eth.log_cids.header_id = eth.receipt_cids.header_id
+ AND eth.log_cids.block_number = eth.receipt_cids.block_number
+ AND receipt_cids.tx_id = transaction_cids.tx_hash
+ AND receipt_cids.header_id = transaction_cids.header_id
+ AND receipt_cids.block_number = transaction_cids.block_number
+ AND transaction_cids.header_id = header_cids.block_hash
+ AND transaction_cids.block_number = header_cids.block_number`
+ RetrieveStorageLeafByAddressHashAndLeafKeyAndBlockHashPgStr = `SELECT cid, val, block_number, removed, state_leaf_removed FROM get_storage_at_by_hash($1, $2, $3)`
+ RetrieveCanonicalBlockHashByNumber = `SELECT block_hash
+ FROM canonical_header_hash($1) AS block_hash
+ WHERE block_hash IS NOT NULL`
+ RetrieveCanonicalHeaderByNumber = `SELECT cid, data FROM eth.header_cids
+ INNER JOIN ipld.blocks ON (
+ header_cids.cid = blocks.key
+ AND header_cids.block_number = blocks.block_number
+ )
+ WHERE block_hash = (SELECT canonical_header_hash($1))`
+ RetrieveTD = `SELECT CAST(td as TEXT) FROM eth.header_cids
+ WHERE header_cids.block_hash = $1`
+ RetrieveRPCTransaction = `SELECT blocks.data, header_id, transaction_cids.block_number, index
+ FROM ipld.blocks, eth.transaction_cids
+ WHERE blocks.key = transaction_cids.cid
+ AND blocks.block_number = transaction_cids.block_number
+ AND transaction_cids.tx_hash = $1
+ AND transaction_cids.header_id = (SELECT canonical_header_hash(transaction_cids.block_number))`
+ RetrieveCodeHashByLeafKeyAndBlockHash = `SELECT code_hash FROM eth.state_accounts, eth.state_cids, eth.header_cids
+ WHERE state_accounts.header_id = state_cids.header_id
+ AND state_accounts.state_path = state_cids.state_path
+ AND state_accounts.block_number = state_cids.block_number
+ AND state_cids.header_id = header_cids.block_hash
+ AND state_cids.block_number = header_cids.block_number
+ AND state_leaf_key = $1
+ AND header_cids.block_number <= (SELECT block_number
+ FROM eth.header_cids
+ WHERE block_hash = $2)
+ AND header_cids.block_hash = (SELECT canonical_header_hash(header_cids.block_number))
+ ORDER BY header_cids.block_number DESC
+ LIMIT 1`
+ RetrieveCodeByMhKey = `SELECT data FROM ipld.blocks WHERE key = $1`
+)
+
+type ipldResult struct {
+ CID string `db:"cid"`
+ Data []byte `db:"data"`
+ TxHash string `db:"tx_hash"`
+}
+
+type nodeInfo struct {
+ CID string `db:"cid"`
+ Value []byte `db:"val"`
+ BlockNumber string `db:"block_number"`
+ Data []byte `db:"data"`
+ Removed bool `db:"removed"`
+ StateLeafRemoved bool `db:"state_leaf_removed"`
+}
diff --git a/pkg/eth/test_helpers/test_data.go b/pkg/eth/test_helpers/test_data.go
index 2e5d40b9..37553009 100644
--- a/pkg/eth/test_helpers/test_data.go
+++ b/pkg/eth/test_helpers/test_data.go
@@ -17,28 +17,22 @@
package test_helpers
import (
- "bytes"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"math/big"
+ "github.com/cerc-io/ipld-eth-server/v4/pkg/eth"
"github.com/cerc-io/ipld-eth-server/v4/pkg/log"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/statediff/indexer/ipld"
"github.com/ethereum/go-ethereum/statediff/indexer/models"
- "github.com/ethereum/go-ethereum/statediff/indexer/shared"
testhelpers "github.com/ethereum/go-ethereum/statediff/test_helpers"
sdtypes "github.com/ethereum/go-ethereum/statediff/types"
"github.com/ethereum/go-ethereum/trie"
- blocks "github.com/ipfs/go-block-format"
- "github.com/multiformats/go-multihash"
-
- "github.com/cerc-io/ipld-eth-server/v4/pkg/eth"
)
// Test variables
@@ -75,10 +69,8 @@ var (
Extra: []byte{},
},
}
- ReceiptsRlp, _ = rlp.EncodeToBytes(MockReceipts)
- MockBlock = createNewBlock(&MockHeader, MockTransactions, MockUncles, MockReceipts, new(trie.Trie))
- MockHeaderRlp, _ = rlp.EncodeToBytes(MockBlock.Header())
- MockChildHeader = types.Header{
+ MockBlock = createNewBlock(&MockHeader, MockTransactions, MockUncles, MockReceipts, new(trie.Trie))
+ MockChildHeader = types.Header{
Time: 0,
Number: new(big.Int).Add(BlockNumber, common.Big1),
Root: common.HexToHash("0x0"),
@@ -89,7 +81,6 @@ var (
ParentHash: MockBlock.Header().Hash(),
}
MockChild = types.NewBlock(&MockChildHeader, MockTransactions, MockUncles, MockReceipts, new(trie.Trie))
- MockChildRlp, _ = rlp.EncodeToBytes(MockChild.Header())
Address = common.HexToAddress("0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476592")
AnotherAddress = common.HexToAddress("0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476593")
AnotherAddress1 = common.HexToAddress("0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476594")
@@ -157,41 +148,10 @@ var (
Index: 5,
}
- Tx1 = GetTxnRlp(0, MockTransactions)
- Tx2 = GetTxnRlp(1, MockTransactions)
- Tx3 = GetTxnRlp(2, MockTransactions)
- Tx4 = GetTxnRlp(3, MockTransactions)
-
- rctCIDs, rctIPLDData, _ = GetRctLeafNodeData(MockReceipts)
- HeaderCID, _ = ipld.RawdataToCid(ipld.MEthHeader, MockHeaderRlp, multihash.KECCAK_256)
- HeaderMhKey = shared.MultihashKeyFromCID(HeaderCID)
- Trx1CID, _ = ipld.RawdataToCid(ipld.MEthTx, Tx1, multihash.KECCAK_256)
- Trx1MhKey = shared.MultihashKeyFromCID(Trx1CID)
- Trx2CID, _ = ipld.RawdataToCid(ipld.MEthTx, Tx2, multihash.KECCAK_256)
- Trx2MhKey = shared.MultihashKeyFromCID(Trx2CID)
- Trx3CID, _ = ipld.RawdataToCid(ipld.MEthTx, Tx3, multihash.KECCAK_256)
- Trx3MhKey = shared.MultihashKeyFromCID(Trx3CID)
- Trx4CID, _ = ipld.RawdataToCid(ipld.MEthTx, Tx4, multihash.KECCAK_256)
- Trx4MhKey = shared.MultihashKeyFromCID(Trx4CID)
- Rct1CID = rctCIDs[0]
- Rct1MhKey = shared.MultihashKeyFromCID(Rct1CID)
- Rct2CID = rctCIDs[1]
- Rct2MhKey = shared.MultihashKeyFromCID(Rct2CID)
- Rct3CID = rctCIDs[2]
- Rct3MhKey = shared.MultihashKeyFromCID(Rct3CID)
- Rct4CID = rctCIDs[3]
- Rct4MhKey = shared.MultihashKeyFromCID(Rct4CID)
- State1CID, _ = ipld.RawdataToCid(ipld.MEthStateTrie, ContractLeafNode, multihash.KECCAK_256)
- State1MhKey = shared.MultihashKeyFromCID(State1CID)
- State2CID, _ = ipld.RawdataToCid(ipld.MEthStateTrie, AccountLeafNode, multihash.KECCAK_256)
- State2MhKey = shared.MultihashKeyFromCID(State2CID)
- StorageCID, _ = ipld.RawdataToCid(ipld.MEthStorageTrie, StorageLeafNode, multihash.KECCAK_256)
- StorageMhKey = shared.MultihashKeyFromCID(StorageCID)
- Rct1IPLD = rctIPLDData[0]
- Rct2IPLD = rctIPLDData[1]
- Rct3IPLD = rctIPLDData[2]
- Rct4IPLD = rctIPLDData[3]
- MockTrxMeta = []models.TxModel{
+ rctCIDs, _, _ = GetRctLeafNodeData(MockReceipts)
+ Rct1CID = rctCIDs[0]
+ Rct4CID = rctCIDs[3]
+ MockTrxMeta = []models.TxModel{
{
CID: "", // This is empty until we go to publish to ipfs
MhKey: "",
@@ -229,48 +189,6 @@ var (
Data: []byte{},
},
}
- MockTrxMetaPostPublsh = []models.TxModel{
- {
- BlockNumber: "1",
- CID: Trx1CID.String(), // This is empty until we go to publish to ipfs
- MhKey: Trx1MhKey,
- Src: SenderAddr.Hex(),
- Dst: Address.String(),
- Index: 0,
- TxHash: MockTransactions[0].Hash().String(),
- Data: []byte{},
- },
- {
- BlockNumber: "1",
- CID: Trx2CID.String(),
- MhKey: Trx2MhKey,
- Src: SenderAddr.Hex(),
- Dst: AnotherAddress.String(),
- Index: 1,
- TxHash: MockTransactions[1].Hash().String(),
- Data: []byte{},
- },
- {
- BlockNumber: "1",
- CID: Trx3CID.String(),
- MhKey: Trx3MhKey,
- Src: SenderAddr.Hex(),
- Dst: "",
- Index: 2,
- TxHash: MockTransactions[2].Hash().String(),
- Data: MockContractByteCode,
- },
- {
- BlockNumber: "1",
- CID: Trx4CID.String(),
- MhKey: Trx4MhKey,
- Src: SenderAddr.Hex(),
- Dst: AnotherAddress1.String(),
- Index: 3,
- TxHash: MockTransactions[3].Hash().String(),
- Data: []byte{},
- },
- }
MockRctMeta = []models.ReceiptModel{
{
LeafCID: "",
@@ -298,41 +216,6 @@ var (
},
}
- MockRctMetaPostPublish = []models.ReceiptModel{
- {
- BlockNumber: "1",
- HeaderID: MockBlock.Hash().String(),
- LeafCID: Rct1CID.String(),
- LeafMhKey: Rct1MhKey,
- Contract: "",
- ContractHash: "",
- },
- {
- BlockNumber: "1",
- HeaderID: MockBlock.Hash().String(),
- LeafCID: Rct2CID.String(),
- LeafMhKey: Rct2MhKey,
- Contract: "",
- ContractHash: "",
- },
- {
- BlockNumber: "1",
- HeaderID: MockBlock.Hash().String(),
- LeafCID: Rct3CID.String(),
- LeafMhKey: Rct3MhKey,
- Contract: ContractAddress.String(),
- ContractHash: ContractHash,
- },
- {
- BlockNumber: "1",
- HeaderID: MockBlock.Hash().String(),
- LeafCID: Rct4CID.String(),
- LeafMhKey: Rct4MhKey,
- Contract: "",
- ContractHash: "",
- },
- }
-
// statediff data
storageLocation = common.HexToHash("0")
StorageLeafKey = crypto.Keccak256Hash(storageLocation[:]).Bytes()
@@ -401,24 +284,6 @@ var (
StorageNodes: []sdtypes.StorageNode{},
},
}
- MockStateMetaPostPublish = []models.StateNodeModel{
- {
- BlockNumber: "1",
- CID: State1CID.String(),
- MhKey: State1MhKey,
- Path: []byte{'\x06'},
- NodeType: 2,
- StateKey: common.BytesToHash(ContractLeafKey).Hex(),
- },
- {
- BlockNumber: "1",
- CID: State2CID.String(),
- MhKey: State2MhKey,
- Path: []byte{'\x0c'},
- NodeType: 2,
- StateKey: common.BytesToHash(AccountLeafKey).Hex(),
- },
- }
MockStorageNodes = map[string][]sdtypes.StorageNode{
contractPath: {
{
@@ -439,149 +304,6 @@ var (
StorageNodes: MockStorageNodes,
StateNodes: MockStateNodes,
}
- MockConvertedPayloadForChild = eth.ConvertedPayload{
- TotalDifficulty: MockChild.Difficulty(),
- Block: MockChild,
- Receipts: MockReceipts,
- TxMetaData: MockTrxMeta,
- ReceiptMetaData: MockRctMeta,
- StorageNodes: MockStorageNodes,
- StateNodes: MockStateNodes,
- }
-
- Reward = shared.CalcEthBlockReward(MockBlock.Header(), MockBlock.Uncles(), MockBlock.Transactions(), MockReceipts)
- MockCIDWrapper = ð.CIDWrapper{
- BlockNumber: new(big.Int).Set(BlockNumber),
- Header: models.HeaderModel{
- BlockNumber: "1",
- BlockHash: MockBlock.Hash().String(),
- ParentHash: "0x0000000000000000000000000000000000000000000000000000000000000000",
- CID: HeaderCID.String(),
- MhKey: HeaderMhKey,
- TotalDifficulty: MockBlock.Difficulty().String(),
- Reward: Reward.String(),
- StateRoot: MockBlock.Root().String(),
- RctRoot: MockBlock.ReceiptHash().String(),
- TxRoot: MockBlock.TxHash().String(),
- UncleRoot: MockBlock.UncleHash().String(),
- Bloom: MockBlock.Bloom().Bytes(),
- Timestamp: MockBlock.Time(),
- TimesValidated: 1,
- Coinbase: "0x0000000000000000000000000000000000000000",
- },
- Transactions: MockTrxMetaPostPublsh,
- Receipts: MockRctMetaPostPublish,
- Uncles: []models.UncleModel{},
- StateNodes: MockStateMetaPostPublish,
- StorageNodes: []models.StorageNodeWithStateKeyModel{
- {
- BlockNumber: "1",
- Path: []byte{},
- CID: StorageCID.String(),
- MhKey: StorageMhKey,
- NodeType: 2,
- StateKey: common.BytesToHash(ContractLeafKey).Hex(),
- StorageKey: common.BytesToHash(StorageLeafKey).Hex(),
- },
- },
- }
-
- HeaderIPLD, _ = blocks.NewBlockWithCid(MockHeaderRlp, HeaderCID)
- Trx1IPLD, _ = blocks.NewBlockWithCid(Tx1, Trx1CID)
- Trx2IPLD, _ = blocks.NewBlockWithCid(Tx2, Trx2CID)
- Trx3IPLD, _ = blocks.NewBlockWithCid(Tx3, Trx3CID)
- Trx4IPLD, _ = blocks.NewBlockWithCid(Tx4, Trx4CID)
- State1IPLD, _ = blocks.NewBlockWithCid(ContractLeafNode, State1CID)
- State2IPLD, _ = blocks.NewBlockWithCid(AccountLeafNode, State2CID)
- StorageIPLD, _ = blocks.NewBlockWithCid(StorageLeafNode, StorageCID)
-
- MockIPLDs = eth.IPLDs{
- BlockNumber: new(big.Int).Set(BlockNumber),
- Header: models.IPLDModel{
- BlockNumber: BlockNumber.String(),
- Data: HeaderIPLD.RawData(),
- Key: HeaderIPLD.Cid().String(),
- },
- Transactions: []models.IPLDModel{
- {
- BlockNumber: BlockNumber.String(),
- Data: Trx1IPLD.RawData(),
- Key: Trx1IPLD.Cid().String(),
- },
- {
- BlockNumber: BlockNumber.String(),
- Data: Trx2IPLD.RawData(),
- Key: Trx2IPLD.Cid().String(),
- },
- {
- BlockNumber: BlockNumber.String(),
- Data: Trx3IPLD.RawData(),
- Key: Trx3IPLD.Cid().String(),
- },
- {
- BlockNumber: BlockNumber.String(),
- Data: Trx4IPLD.RawData(),
- Key: Trx4IPLD.Cid().String(),
- },
- },
- Receipts: []models.IPLDModel{
- {
- BlockNumber: BlockNumber.String(),
- Data: Rct1IPLD,
- Key: Rct1CID.String(),
- },
- {
- BlockNumber: BlockNumber.String(),
- Data: Rct2IPLD,
- Key: Rct2CID.String(),
- },
- {
- BlockNumber: BlockNumber.String(),
- Data: Rct3IPLD,
- Key: Rct3CID.String(),
- },
- {
- BlockNumber: BlockNumber.String(),
- Data: Rct4IPLD,
- Key: Rct4CID.String(),
- },
- },
- StateNodes: []eth.StateNode{
- {
- StateLeafKey: common.BytesToHash(ContractLeafKey),
- Type: sdtypes.Leaf,
- IPLD: models.IPLDModel{
- BlockNumber: BlockNumber.String(),
- Data: State1IPLD.RawData(),
- Key: State1IPLD.Cid().String(),
- },
- Path: []byte{'\x06'},
- },
- {
- StateLeafKey: common.BytesToHash(AccountLeafKey),
- Type: sdtypes.Leaf,
- IPLD: models.IPLDModel{
- BlockNumber: BlockNumber.String(),
- Data: State2IPLD.RawData(),
- Key: State2IPLD.Cid().String(),
- },
- Path: []byte{'\x0c'},
- },
- },
- StorageNodes: []eth.StorageNode{
- {
- StateLeafKey: common.BytesToHash(ContractLeafKey),
- StorageLeafKey: common.BytesToHash(StorageLeafKey),
- Type: sdtypes.Leaf,
- IPLD: models.IPLDModel{
- BlockNumber: BlockNumber.String(),
- Data: StorageIPLD.RawData(),
- Key: StorageIPLD.Cid().String(),
- },
- Path: []byte{},
- },
- },
- }
LondonBlockNum = new(big.Int).Add(BlockNumber, big.NewInt(2))
MockLondonHeader = types.Header{
@@ -741,21 +463,3 @@ func createLegacyTransactionsAndReceipts() (types.Transactions, types.Receipts,
return types.Transactions{signedTrx1, signedTrx2, signedTrx3, signedTrx4}, types.Receipts{mockReceipt1, mockReceipt2, mockReceipt3, mockReceipt4}, SenderAddr
}
-
-func GetTxnRlp(num int, txs types.Transactions) []byte {
- buf := new(bytes.Buffer)
- txs.EncodeIndex(num, buf)
- tx := make([]byte, buf.Len())
- copy(tx, buf.Bytes())
- buf.Reset()
- return tx
-}
-
-func GetRctRlp(num int, rcts types.Receipts) []byte {
- buf := new(bytes.Buffer)
- rcts.EncodeIndex(num, buf)
- rct := make([]byte, buf.Len())
- copy(rct, buf.Bytes())
- buf.Reset()
- return rct
-}
diff --git a/pkg/eth/types.go b/pkg/eth/types.go
index 1efa9084..c74c959c 100644
--- a/pkg/eth/types.go
+++ b/pkg/eth/types.go
@@ -193,47 +193,6 @@ func (arg *CallArgs) ToMessage(globalGasCap uint64, baseFee *big.Int) (types.Mes
return msg, nil
}
-// IPLDs is used to package raw IPLD block data fetched from IPFS and returned by the server
-// Returned by IPLDFetcher and ResponseFilterer
-type IPLDs struct {
- BlockNumber *big.Int
- TotalDifficulty *big.Int
- Header models.IPLDModel
- Uncles []models.IPLDModel
- Transactions []models.IPLDModel
- Receipts []models.IPLDModel
- StateNodes []StateNode
- StorageNodes []StorageNode
-}
-
-type StateNode struct {
- Type sdtypes.NodeType
- StateLeafKey common.Hash
- Path []byte
- IPLD models.IPLDModel
-}
-
-type StorageNode struct {
- Type sdtypes.NodeType
- StateLeafKey common.Hash
- StorageLeafKey common.Hash
- Path []byte
- IPLD models.IPLDModel
-}
-
-// CIDWrapper is used to direct fetching of IPLDs from IPFS
-// Returned by CIDRetriever
-// Passed to IPLDFetcher
-type CIDWrapper struct {
- BlockNumber *big.Int
- Header models.HeaderModel
- Uncles []models.UncleModel
- Transactions []models.TxModel
- Receipts []models.ReceiptModel
- StateNodes []models.StateNodeModel
- StorageNodes []models.StorageNodeWithStateKeyModel
-}
-
// ConvertedPayload is a custom type which packages raw ETH data for publishing to IPFS and filtering to subscribers
// Returned by PayloadConverter
// Passed to IPLDPublisher and ResponseFilterer
@@ -249,7 +208,7 @@ type ConvertedPayload struct {
// LogResult represent a log.
type LogResult struct {
- LeafCID string `db:"leaf_cid"`
+ LeafCID string `db:"cid"`
ReceiptID string `db:"rct_id"`
Address string `db:"address"`
Index int64 `db:"index"`
diff --git a/pkg/graphql/graphql.go b/pkg/graphql/graphql.go
index afcbd0f3..da6dd827 100644
--- a/pkg/graphql/graphql.go
+++ b/pkg/graphql/graphql.go
@@ -29,7 +29,6 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/rawdb"
- "github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/eth/filters"
"github.com/ethereum/go-ethereum/rlp"
@@ -37,6 +36,7 @@ import (
"github.com/cerc-io/ipld-eth-server/v4/pkg/eth"
"github.com/cerc-io/ipld-eth-server/v4/pkg/shared"
+ ipld_eth_statedb "github.com/cerc-io/ipld-eth-statedb"
)
var (
@@ -51,8 +51,8 @@ type Account struct {
}
// getState fetches the StateDB object for an account.
-func (a *Account) getState(ctx context.Context) (*state.StateDB, error) {
- state, _, err := a.backend.StateAndHeaderByNumberOrHash(ctx, a.blockNrOrHash)
+func (a *Account) getState(ctx context.Context) (*ipld_eth_statedb.StateDB, error) {
+ state, _, err := a.backend.IPLDStateDBAndHeaderByNumberOrHash(ctx, a.blockNrOrHash)
return state, err
}
@@ -1009,7 +1009,7 @@ func (r *Resolver) GetStorageAt(ctx context.Context, args struct {
Contract common.Address
Slot common.Hash
}) (*StorageResult, error) {
- cid, ipldBlock, rlpValue, err := r.backend.IPLDRetriever.RetrieveStorageAtByAddressAndStorageSlotAndBlockHash(args.Contract, args.Slot, args.BlockHash)
+ cid, ipldBlock, rlpValue, err := r.backend.Retriever.RetrieveStorageAtByAddressAndStorageSlotAndBlockHash(args.Contract, args.Slot, args.BlockHash)
if err != nil {
if err == sql.ErrNoRows {
diff --git a/pkg/graphql/service.go b/pkg/graphql/service.go
index 95211d7a..f3df0d48 100644
--- a/pkg/graphql/service.go
+++ b/pkg/graphql/service.go
@@ -81,7 +81,7 @@ func (s *Service) Start(server *p2p.Server) error {
return nil
}
-// newHandler returns a new `http.Handler` that will answer GraphQL queries.
+// NewHandler returns a new `http.Handler` that will answer GraphQL queries.
// It additionally exports an interactive query browser on the / endpoint.
func NewHandler(backend *eth.Backend) (http.Handler, error) {
q := Resolver{backend}
diff --git a/pkg/serve/service.go b/pkg/serve/service.go
index 5d92a9f8..d36d96e8 100644
--- a/pkg/serve/service.go
+++ b/pkg/serve/service.go
@@ -58,7 +58,7 @@ type Service struct {
sync.Mutex
// Used to signal shutdown of the service
QuitChan chan bool
- // Underlying db
+ // Underlying db connection pool
db *sqlx.DB
// rpc client for forwarding cache misses
client *rpc.Client
diff --git a/pkg/shared/functions.go b/pkg/shared/functions.go
index f5eac06c..d54ddaf1 100644
--- a/pkg/shared/functions.go
+++ b/pkg/shared/functions.go
@@ -50,14 +50,14 @@ func Rollback(tx *sqlx.Tx) {
// FetchIPLDByMhKeyAndBlockNumber is used to retrieve an ipld from Postgres blockstore with the provided tx, mhkey string and blockNumber
func FetchIPLDByMhKeyAndBlockNumber(tx *sqlx.Tx, mhKey string, blockNumber uint64) ([]byte, error) {
- pgStr := `SELECT data FROM public.blocks WHERE key = $1 AND block_number = $2`
+ pgStr := `SELECT data FROM ipld.blocks WHERE key = $1 AND block_number = $2`
var block []byte
return block, tx.Get(&block, pgStr, mhKey, blockNumber)
}
// FetchIPLD is used to retrieve an IPLD from Postgres mhkey and blockNumber
func FetchIPLD(db *sqlx.DB, mhKey string, blockNumber uint64) ([]byte, error) {
- pgStr := `SELECT data FROM public.blocks WHERE key = $1 AND block_number = $2`
+ pgStr := `SELECT data FROM ipld.blocks WHERE key = $1 AND block_number = $2`
var block []byte
return block, db.Get(&block, pgStr, mhKey, blockNumber)
}
diff --git a/test_config/test_config.go b/test_config/test_config.go
index 982f9b44..de67b704 100644
--- a/test_config/test_config.go
+++ b/test_config/test_config.go
@@ -18,6 +18,7 @@ package test_config
import (
"errors"
+
"github.com/cerc-io/ipld-eth-server/v4/pkg/log"
"github.com/ethereum/go-ethereum/statediff/indexer/database/sql/postgres"
"github.com/spf13/viper"