diff --git a/Makefile b/Makefile index 5e4eb06c86b..5978eba771d 100644 --- a/Makefile +++ b/Makefile @@ -36,6 +36,9 @@ AUTHOR ?= $(shell git config user.email || echo $$USER) ENABLE_METRICS ?= true BUILD_TAGS ?= + +-include $(PROXY_WRAPPER_PATH)/Makefile.vars + BUILD_FLAGS ?= $(shell echo "-ldflags='\ -X github.com/status-im/status-go/params.Version=$(RELEASE_TAG:v%=%) \ -X github.com/status-im/status-go/params.GitCommit=$(GIT_COMMIT) \ @@ -165,6 +168,7 @@ statusgo-shared-library: ##@cross-compile Build status-go as shared library for mkdir -p build/bin/statusgo-lib go run cmd/library/*.go > build/bin/statusgo-lib/main.go @echo "Building shared library..." + @echo "Tags: $(BUILD_TAGS)" $(GOBIN_SHARED_LIB_CFLAGS) $(GOBIN_SHARED_LIB_CGO_LDFLAGS) go build \ -tags '$(BUILD_TAGS)' \ $(BUILD_FLAGS) \ @@ -389,3 +393,16 @@ migration: migration-protocol: DEFAULT_PROTOCOL_PATH := protocol/migrations/sqlite migration-protocol: touch $(DEFAULT_PROTOCOL_PATH)/$(shell date +%s)_$(D).up.sql + +PROXY_WRAPPER_PATH = $(CURDIR)/vendor/github.com/siphiuel/lc-proxy-wrapper +-include $(PROXY_WRAPPER_PATH)/Makefile.vars + +#export VERIF_PROXY_OUT_PATH = $(CURDIR)/vendor/github.com/siphiuel/lc-proxy-wrapper +build-verif-proxy: + $(MAKE) -C $(NIMBUS_ETH1_PATH) libverifproxy + +build-verif-proxy-wrapper: + $(MAKE) -C $(VERIF_PROXY_OUT_PATH) build-verif-proxy-wrapper + +test-verif-proxy-wrapper: + CGO_CFLAGS="$(CGO_CFLAGS)" go test -v github.com/status-im/status-go/rpc -tags gowaku_skip_migrations,nimbus_light_client -run ^TestProxySuite$$ -testify.m TestRun -ldflags $(LDFLAGS) diff --git a/go.mod b/go.mod index 7f1ab1fc9d2..b2a1c6f4dbd 100644 --- a/go.mod +++ b/go.mod @@ -79,6 +79,7 @@ require ( github.com/ladydascalie/currency v1.6.0 github.com/meirf/gopart v0.0.0-20180520194036-37e9492a85a8 github.com/schollz/peerdiscovery v1.7.0 + github.com/siphiuel/lc-proxy-wrapper v0.0.0-20230516150924-246507cee8c7 github.com/waku-org/go-waku v0.5.3-0.20230404182041-41691a44e579 github.com/yeqown/go-qrcode/v2 v2.2.1 github.com/yeqown/go-qrcode/writer/standard v1.2.1 @@ -86,6 +87,7 @@ require ( ) require ( + github.com/BurntSushi/toml v1.2.1 // indirect github.com/PuerkitoBio/goquery v1.6.1 // indirect github.com/RoaringBitmap/roaring v0.9.4 // indirect github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 // indirect diff --git a/go.sum b/go.sum index de8f2ed4e8a..8b0edbb13a3 100644 --- a/go.sum +++ b/go.sum @@ -105,6 +105,7 @@ github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbt github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= +github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ClickHouse/clickhouse-go v1.4.3/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= @@ -1943,6 +1944,8 @@ github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go. github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= +github.com/siphiuel/lc-proxy-wrapper v0.0.0-20230516150924-246507cee8c7 h1:l7v5b3ghketKidVR6QjJlsgrrgzRnRRCc0lywjjONjQ= +github.com/siphiuel/lc-proxy-wrapper v0.0.0-20230516150924-246507cee8c7/go.mod h1:Cpir2acMsYVjrwbmRKN+2w1mYbBZdWwmoIyqc7x470U= github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= diff --git a/params/defaults.go b/params/defaults.go index ac76f0d2e18..48f299ea9a4 100644 --- a/params/defaults.go +++ b/params/defaults.go @@ -9,6 +9,8 @@ const ( // SendTransactionMethodName defines the name for a giving transaction. SendTransactionMethodName = "eth_sendTransaction" + BalanceMethodName = "eth_getBalance" + // AccountsMethodName defines the name for listing the currently signed accounts. AccountsMethodName = "eth_accounts" diff --git a/rpc/client.go b/rpc/client.go index 477e307f924..ee6bfb5ac1e 100644 --- a/rpc/client.go +++ b/rpc/client.go @@ -35,6 +35,7 @@ type Handler func(context.Context, uint64, ...interface{}) (interface{}, error) // Client represents RPC client with custom routing // scheme. It automatically decides where RPC call // goes - Upstream or Local node. + type Client struct { sync.RWMutex @@ -56,6 +57,9 @@ type Client struct { walletNotifier func(chainID uint64, message string) } +// Is initialized in a build-tag-dependent module +var verifProxyInitFn func(c *Client) + // NewClient initializes Client and tries to connect to both, // upstream and local node. // @@ -92,6 +96,10 @@ func NewClient(client *gethrpc.Client, upstreamChainID uint64, upstream params.U c.router = newRouter(c.upstreamEnabled) + if verifProxyInitFn != nil { + verifProxyInitFn(&c) + } + return &c, nil } @@ -247,6 +255,14 @@ func (c *Client) RegisterHandler(method string, handler Handler) { c.handlers[method] = handler } +// UnregisterHandler removes a previously registered handler. +func (c *Client) UnregisterHandler(method string) { + c.handlersMx.Lock() + defer c.handlersMx.Unlock() + + delete(c.handlers, method) +} + // callMethod calls registered RPC handler with given args and pointer to result. // It handles proper params and result converting // diff --git a/rpc/verif_proxy.go b/rpc/verif_proxy.go new file mode 100644 index 00000000000..6c28f730aef --- /dev/null +++ b/rpc/verif_proxy.go @@ -0,0 +1,70 @@ +// +build nimbus_light_client + +package rpc + +import ( + "context" + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + gethrpc "github.com/ethereum/go-ethereum/rpc" + proxy "github.com/siphiuel/lc-proxy-wrapper" + "github.com/status-im/status-go/params" +) + +type VerifProxy struct { + config *proxy.Config + client *gethrpc.Client +} + +func init() { + verifProxyInitFn = func(c *Client) { + ctx := context.Background() + var testConfig = proxy.Config{ + Eth2Network: "mainnet", + //TrustedBlockRoot: "0x6fd2f9fdc616a0755f3f88ac58e4a7871788c3128261a18bf9645eee7042eb53", + TrustedBlockRoot: "0xc5182cdb750fe088138b0d475683cda26a96befc24de16fb17bcf49d9cadf2f7", + //Web3Url: Web3UrlType{"HttpUrl", "https://mainnet.infura.io/v3/800c641949d64d768a5070a1b0511938"}, + Web3Url: c.upstreamURL, + RpcAddress: "127.0.0.1", + RpcPort: 8545, + LogLevel: "INFO", + //Eth2Network: "prater", + //TrustedBlockRoot: "0x017e4563ebf7fed67cff819c63d8da397b4ed0452a3bbd7cae13476abc5020e4", + } + proxy.StartLightClient(ctx, &testConfig) + verifProxy := NewVerifProxy(&testConfig) + c.RegisterHandler( + params.BalanceMethodName, + func(ctx context.Context, v uint64, params ...interface{}) (interface{}, error) { + fmt.Println("### inside registered handler") + addr := params[0].(common.Address) + return verifProxy.GetBalance(ctx, addr) + }, + ) + } +} + +func NewVerifProxy(cfg *proxy.Config) *VerifProxy { + endpoint := "http://" + cfg.RpcAddress + ":" + fmt.Sprint(cfg.RpcPort) + fmt.Println("### NewVerifProxy: ", endpoint) + client, err := gethrpc.DialHTTP(endpoint) + if err != nil { + fmt.Println("Error when creating VerifProxy client", err) + } + proxy := &VerifProxy{cfg, client} + proxy.client = client + return proxy +} + +func (p *VerifProxy) GetBalance(ctx context.Context, address common.Address) (interface{}, error) { + fmt.Println("### IN GetBalance, address ", address) + var result hexutil.Big + err := p.client.CallContext(ctx, &result, "eth_getBalance", address, "latest") + if err != nil { + fmt.Println("### IN GetBalance, error ", err) + } + return result, nil + +} diff --git a/rpc/verif_proxy_test.go b/rpc/verif_proxy_test.go new file mode 100644 index 00000000000..2dc16ed4a11 --- /dev/null +++ b/rpc/verif_proxy_test.go @@ -0,0 +1,109 @@ +// +build nimbus_light_client + +package rpc + +import ( + "context" + "fmt" + "os" + "os/signal" + "syscall" + "testing" + "time" + + "net/http" + "net/http/httptest" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + gethrpc "github.com/ethereum/go-ethereum/rpc" + "github.com/status-im/status-go/params" + + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type ProxySuite struct { + suite.Suite +} + +func TestProxySuite(t *testing.T) { + suite.Run(t, new(ProxySuite)) +} + +// func startNode() { +// // Start node +// utils.Init() + +// backend := api.NewGethStatusBackend() +// config, err := utils.MakeTestNodeConfig(params.StatusChainNetworkID) +// require.NoError(s.T(), err) +// require.NoError(s.T(), backend.AccountManager().InitKeystore(config.KeyStoreDir)) +// err = backend.StartNode(config) +// require.NoError(s.T(), err) + +// defer func() { +// require.NoError(s.T(), backend.StopNode()) +// }() +// } + +func (s *ProxySuite) startRpcClient(infuraURL string) *Client { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintln(w, `{ + "id": 1, + "jsonrpc": "2.0", + "result": "0x234234e22b9ffc2387e18636e0534534a3d0c56b0243567432453264c16e78a2adc" + }`) + })) + defer ts.Close() + + gethRPCClient, err := gethrpc.Dial(ts.URL) + require.NoError(s.T(), err) + + db, close := setupTestNetworkDB(s.T()) + defer close() + c, err := NewClient(gethRPCClient, 1, params.UpstreamRPCConfig{Enabled: true, URL: infuraURL}, []params.Network{}, db) + require.NoError(s.T(), err) + + return c +} + +func (s *ProxySuite) TestRun() { + infuraURL := "https://mainnet.infura.io/v3/800c641949d64d768a5070a1b0511938" + client := s.startRpcClient(infuraURL) + + // Run light client proxy + ctx, cancel := context.WithCancel(context.Background()) + + signals := make(chan os.Signal, 1) + signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM) + fmt.Println("Before range signals") + // time.Sleep(8 * time.Second) + // cancel() + + // Invoke eth_getBalance + // '{"jsonrpc":"2.0","method":"eth_getBalance","params":["0x407d73d8a49eeb85d32cf465507dd71d507100c1", "latest"],"id":1}' + fmt.Println("### upstream URL: ", client.upstreamURL) + fmt.Println("### upstream chainID: ", client.UpstreamChainID) + var result hexutil.Big + var addr common.Address + addr = common.HexToAddress("0x95222290DD7278Aa3Ddd389Cc1E1d165CC4BAfe5") + chainID := uint64(1) + + time.Sleep(200 * time.Second) + err := client.CallContext(ctx, &result, chainID, "eth_getBalance", addr, "latest") + require.NoError(s.T(), err) + fmt.Println("### result: ", result.String()) + + client.UnregisterHandler("eth_getBalance") + var resultRaw hexutil.Big + err = client.CallContext(ctx, &resultRaw, chainID, "eth_getBalance", addr, "latest") + fmt.Println("### resultRaw: ", resultRaw.String()) + s.Require().Equal(result, resultRaw) + for range signals { + fmt.Println("Signal caught, exiting") + cancel() + } + fmt.Println("Exiting") + +} diff --git a/vendor/modules.txt b/vendor/modules.txt index d547f260a84..c7ce6a1462c 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,3 +1,7 @@ +# github.com/BurntSushi/toml v1.2.1 +## explicit; go 1.16 +github.com/BurntSushi/toml +github.com/BurntSushi/toml/internal # github.com/PuerkitoBio/goquery v1.6.1 ## explicit; go 1.13 github.com/PuerkitoBio/goquery @@ -876,6 +880,9 @@ github.com/shirou/gopsutil/internal/common # github.com/shopspring/decimal v1.2.0 ## explicit; go 1.13 github.com/shopspring/decimal +# github.com/siphiuel/lc-proxy-wrapper v0.0.0-20230516150924-246507cee8c7 +## explicit; go 1.18 +github.com/siphiuel/lc-proxy-wrapper # github.com/spaolacci/murmur3 v1.1.0 ## explicit github.com/spaolacci/murmur3