From 85f3c937ce76974eb5027fabe77605f8d82dab98 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 24 Oct 2024 14:55:30 -0400 Subject: [PATCH 1/5] Use updated rescue-proxy package and new testing library --- go.mod | 22 +++++++++++++--------- go.sum | 42 ++++++++++++++++++++++-------------------- 2 files changed, 35 insertions(+), 29 deletions(-) diff --git a/go.mod b/go.mod index ccb0828..b210983 100644 --- a/go.mod +++ b/go.mod @@ -4,14 +4,15 @@ go 1.21 require ( github.com/Rocket-Rescue-Node/credentials v0.0.0-20240224174210-626742fc699e - github.com/Rocket-Rescue-Node/rescue-proxy v1.0.2 + github.com/Rocket-Rescue-Node/rescue-proxy v1.2.3 github.com/ethereum/go-ethereum v1.13.5 github.com/gorilla/mux v1.8.1 github.com/jonboulle/clockwork v0.4.0 github.com/mattn/go-sqlite3 v1.14.18 github.com/rs/cors v1.10.1 + github.com/stretchr/testify v1.8.4 go.uber.org/zap v1.26.0 - google.golang.org/grpc v1.59.0 + google.golang.org/grpc v1.64.0 ) require ( @@ -25,16 +26,18 @@ require ( github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect github.com/getsentry/sentry-go v0.18.0 // indirect github.com/go-stack/stack v1.8.1 // indirect - github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/protobuf v1.5.4 // indirect github.com/holiman/uint256 v1.2.4 // indirect github.com/klauspost/compress v1.16.4 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.16.0 // indirect github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.44.0 // indirect @@ -45,12 +48,13 @@ require ( github.com/supranational/blst v0.3.11 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.17.0 // indirect - golang.org/x/net v0.19.0 // indirect - golang.org/x/sync v0.5.0 // indirect - golang.org/x/sys v0.15.0 // indirect + golang.org/x/crypto v0.21.0 // indirect + golang.org/x/net v0.23.0 // indirect + golang.org/x/sync v0.6.0 // indirect + golang.org/x/sys v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20231127180814-3a041ad873d4 // indirect - google.golang.org/protobuf v1.31.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect + google.golang.org/protobuf v1.33.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect rsc.io/tmplfunc v0.0.3 // indirect ) diff --git a/go.sum b/go.sum index efd5f58..c270d4d 100644 --- a/go.sum +++ b/go.sum @@ -8,8 +8,8 @@ github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwS github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= github.com/Rocket-Rescue-Node/credentials v0.0.0-20240224174210-626742fc699e h1:fGJ5R5lOqdyGfTL8HcTiCFrNT6hyvjDR5ROIaqIHGlk= github.com/Rocket-Rescue-Node/credentials v0.0.0-20240224174210-626742fc699e/go.mod h1:rInGId8V6ezrcyrNTeuWkfcSKD9fF97Mguso/x7ahJs= -github.com/Rocket-Rescue-Node/rescue-proxy v1.0.2 h1:upKCiEs3JrOkdG7H1KQhksvCMvte/sD5rPuludYX3r0= -github.com/Rocket-Rescue-Node/rescue-proxy v1.0.2/go.mod h1:hJObiXyvaqR9oen3yluDTz+3lXt1smj/yrCRvvRhLqU= +github.com/Rocket-Rescue-Node/rescue-proxy v1.2.3 h1:LK974tPFaLys6WgSEG37JjA+AoqoJwrb+zUTnM/98Wk= +github.com/Rocket-Rescue-Node/rescue-proxy v1.2.3/go.mod h1:0DTx8FB72+GK2BXy++GILTww+8ac//ssj4fchMtee6s= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= @@ -121,8 +121,8 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -133,8 +133,8 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= @@ -333,8 +333,8 @@ golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= -golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= @@ -367,8 +367,8 @@ golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -378,8 +378,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/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-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -410,8 +410,8 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -449,16 +449,16 @@ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoA google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231127180814-3a041ad873d4 h1:DC7wcm+i+P1rN3Ff07vL+OndGg5OhNddHyTA+ocPqYE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231127180814-3a041ad873d4/go.mod h1:eJVxU6o+4G1PSczBr85xmyvSNYAKvAYgkub40YGomFM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 h1:NnYq6UN9ReLM9/Y01KWNOWyI5xQ9kbIms5GGJVwS/Yc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= -google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= +google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= +google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -470,11 +470,13 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= From c784498cba66db20808eadb5eae0db5f69dadaab Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 24 Oct 2024 15:01:29 -0400 Subject: [PATCH 2/5] Implement EIP1271 support --- api/messages.go | 38 +++++++++++++++++++++++++++++---- api/router.go | 33 +++++++++++----------------- external/rescue_proxy.go | 25 ++++++++++++++++++++++ main.go | 3 +++ services/credentials.go | 2 +- services/operator_info.go | 2 +- services/service.go | 45 ++++++++++++++++++++++++++++----------- 7 files changed, 109 insertions(+), 39 deletions(-) diff --git a/api/messages.go b/api/messages.go index 2976730..50e435e 100644 --- a/api/messages.go +++ b/api/messages.go @@ -11,6 +11,7 @@ import ( "github.com/Rocket-Rescue-Node/credentials" "github.com/Rocket-Rescue-Node/credentials/pb" "github.com/Rocket-Rescue-Node/rescue-api/services" + "github.com/ethereum/go-ethereum/common" ) type response struct { @@ -28,14 +29,43 @@ func (br *decodingError) Error() string { } type CreateCredentialRequest struct { - Address string `json:"address"` - Msg string `json:"msg"` - Sig string `json:"sig"` - Version string `json:"version"` + Address common.Address `json:"address"` + Msg []byte `json:"msg"` + Sig []byte `json:"sig"` + Version string `json:"version"` operatorType credentials.OperatorType `json:"-"` } +func (c *CreateCredentialRequest) UnmarshalJSON(data []byte) error { + type Alias CreateCredentialRequest + aux := &struct { + Address string `json:"address"` + Msg string `json:"msg"` + Sig string `json:"sig"` + + // Populates the `Version` field + *Alias + }{ + Alias: (*Alias)(c), + } + + if err := json.Unmarshal(data, &aux); err != nil { + return err + } + + // Convert Address + c.Address = common.HexToAddress(aux.Address) + + // Convert Msg + c.Msg = []byte(aux.Msg) + + // Convert Sig + c.Sig = []byte(aux.Sig) + + return nil +} + type CreateCredentialResponse struct { Username string `json:"username"` Password string `json:"password"` diff --git a/api/router.go b/api/router.go index 16997b7..4497311 100644 --- a/api/router.go +++ b/api/router.go @@ -3,11 +3,9 @@ package api import ( "encoding/hex" "net/http" - "strings" "time" "github.com/Rocket-Rescue-Node/rescue-api/services" - "github.com/ethereum/go-ethereum/common" "github.com/gorilla/mux" "github.com/rs/cors" "go.uber.org/zap" @@ -18,42 +16,35 @@ type apiRouter struct { logger *zap.Logger } -func readJSONRequest(r *http.Request, logger *zap.Logger) (*[]byte, *CreateCredentialRequest, error) { +func (ar *apiRouter) readJSONRequest(r *http.Request) (*CreateCredentialRequest, error) { out := new(CreateCredentialRequest) // Validate the request body if err := validateJSONRequest(r, out); err != nil { - return nil, nil, err + return nil, err } - logger.Info("Got valid request", + ar.logger.Info("Got valid request", zap.String("endpoint", r.URL.Path), - zap.String("address", out.Address), - zap.String("msg", out.Msg), - zap.String("sig", out.Sig), + zap.String("address", out.Address.Hex()), + zap.String("msg", string(out.Msg)), + zap.String("sig", hex.EncodeToString(out.Sig)), zap.String("version", out.Version), zap.Int("operator_type", int(out.operatorType)), ) - // Validate the message signature - sig, err := hex.DecodeString(strings.TrimPrefix(out.Sig, "0x")) - if err != nil { - msg := "invalid signature" - return nil, nil, &decodingError{status: http.StatusBadRequest, msg: msg} - } - - return &sig, out, nil + return out, nil } func (ar *apiRouter) CreateCredential(w http.ResponseWriter, r *http.Request) error { // Try to read the request - sig, req, err := readJSONRequest(r, ar.logger) + req, err := ar.readJSONRequest(r) if err != nil { return writeJSONError(w, err) } // Create the credential - cred, err := ar.svc.CreateCredentialWithRetry([]byte(req.Msg), *sig, common.HexToAddress(req.Address), req.operatorType) + cred, err := ar.svc.CreateCredentialWithRetry(req.Msg, req.Sig, req.Address, req.operatorType) if err != nil { return writeJSONError(w, err) } @@ -82,7 +73,7 @@ func (ar *apiRouter) CreateCredential(w http.ResponseWriter, r *http.Request) er func (ar *apiRouter) GetOperatorInfo(w http.ResponseWriter, r *http.Request) error { // Try to read the request - sig, credReq, err := readJSONRequest(r, ar.logger) + credReq, err := ar.readJSONRequest(r) if err != nil { return writeJSONError(w, err) } @@ -90,14 +81,14 @@ func (ar *apiRouter) GetOperatorInfo(w http.ResponseWriter, r *http.Request) err req := (*OperatorInfoRequest)(credReq) // Get operator info - operatorInfo, err := ar.svc.GetOperatorInfo([]byte(req.Msg), *sig, common.HexToAddress(req.Address), req.operatorType) + operatorInfo, err := ar.svc.GetOperatorInfo(req.Msg, req.Sig, req.Address, req.operatorType) if err != nil { return writeJSONError(w, err) } // Cred events retrieved ar.logger.Info("Retrieved operator info", - zap.String("nodeID", req.Address), + zap.String("nodeID", req.Address.Hex()), zap.Int("operator_type", int(req.operatorType)), ) diff --git a/external/rescue_proxy.go b/external/rescue_proxy.go index 72f8f2c..f139d03 100644 --- a/external/rescue_proxy.go +++ b/external/rescue_proxy.go @@ -3,9 +3,11 @@ package external import ( "context" "crypto/tls" + "errors" "time" proxy "github.com/Rocket-Rescue-Node/rescue-proxy/pb" + "github.com/ethereum/go-ethereum/common" "go.uber.org/zap" "google.golang.org/grpc" "google.golang.org/grpc/credentials" @@ -114,6 +116,29 @@ func (c *RescueProxyAPIClient) GetWithdrawalAddresses() ([][]byte, error) { return r.GetWithdrawalAddresses(), nil } +func (c *RescueProxyAPIClient) ValidateEIP1271(dataHash *common.Hash, signature *[]byte, address *common.Address) (bool, error) { + // Connect if not yet connected. + if err := c.ensureConnection(); err != nil { + return false, err + } + c.logger.Debug("requesting eip1271 validation") + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + r, err := c.client.ValidateEIP1271(ctx, &proxy.ValidateEIP1271Request{ + DataHash: dataHash.Bytes(), + Signature: *signature, + Address: address.Bytes(), + }) + if err != nil { + return false, err + } + rErr := r.GetError() + if rErr != "" { + return false, errors.New(rErr) + } + return r.GetValid(), nil +} + func (c *RescueProxyAPIClient) Close() error { if c.conn == nil { return nil diff --git a/main.go b/main.go index ac12eb8..d41f942 100644 --- a/main.go +++ b/main.go @@ -122,6 +122,9 @@ func main() { Logger: logger, Clock: clock, EnableSoloValidators: cfg.EnableSoloValidators, + + RescueProxyAddr: cfg.RescueProxyAPIAddr, + RescueProxySecureGRPC: cfg.SecureGRPC, } svc := services.NewService(svcCfg) if err := svc.Init(); err != nil { diff --git a/services/credentials.go b/services/credentials.go index 2af4af7..be5dee6 100644 --- a/services/credentials.go +++ b/services/credentials.go @@ -153,7 +153,7 @@ func (s *Service) CreateCredential(msg []byte, sig []byte, expectedNodeId common var err error // Validate request - nodeID, err := s.validateSignedRequest(&msg, &sig, expectedNodeId, ot) + nodeID, err := s.validateSignedRequest(msg, sig, expectedNodeId, ot) if err != nil { return nil, err } diff --git a/services/operator_info.go b/services/operator_info.go index f92ee5d..d49c8c5 100644 --- a/services/operator_info.go +++ b/services/operator_info.go @@ -17,7 +17,7 @@ func (s *Service) GetOperatorInfo(msg []byte, sig []byte, expectedNodeId common. var err error // Validate request - nodeID, err := s.validateSignedRequest(&msg, &sig, expectedNodeId, ot) + nodeID, err := s.validateSignedRequest(msg, sig, expectedNodeId, ot) if err != nil { return nil, err } diff --git a/services/service.go b/services/service.go index 39c8be2..42b425c 100644 --- a/services/service.go +++ b/services/service.go @@ -9,10 +9,12 @@ import ( creds "github.com/Rocket-Rescue-Node/credentials" "github.com/Rocket-Rescue-Node/credentials/pb" + "github.com/Rocket-Rescue-Node/rescue-api/external" "github.com/Rocket-Rescue-Node/rescue-api/models" authz "github.com/Rocket-Rescue-Node/rescue-api/models/authorization" "github.com/Rocket-Rescue-Node/rescue-api/util" "github.com/Rocket-Rescue-Node/rescue-proxy/metrics" + "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" "github.com/jonboulle/clockwork" "go.uber.org/zap" @@ -71,6 +73,9 @@ type ServiceConfig struct { Logger *zap.Logger Clock clockwork.Clock EnableSoloValidators bool + + RescueProxyAddr string + RescueProxySecureGRPC bool } // Services contain business logic, are responsible for interacting with the database, @@ -100,6 +105,8 @@ type Service struct { clock clockwork.Clock enableSoloValidators bool + + rescueProxyClient *external.RescueProxyAPIClient } func NewService(config *ServiceConfig) *Service { @@ -113,6 +120,11 @@ func NewService(config *ServiceConfig) *Service { logger: config.Logger, clock: config.Clock, enableSoloValidators: config.EnableSoloValidators, + rescueProxyClient: external.NewRescueProxyAPIClient( + config.Logger, + config.RescueProxyAddr, + config.RescueProxySecureGRPC, + ), } } @@ -319,29 +331,38 @@ func (s *Service) checkNodeAuthorization(nodeID *models.NodeID, ot creds.Operato return nil } -func (s *Service) validateSignedRequest(msg *[]byte, sig *[]byte, expectedNodeId common.Address, ot pb.OperatorType) (*common.Address, error) { +func (s *Service) validateSignedRequest(msg []byte, sig []byte, expectedNodeId common.Address, ot pb.OperatorType) (common.Address, error) { // Check request age - if err := s.checkRequestAge(msg); err != nil { - return nil, err + if err := s.checkRequestAge(&msg); err != nil { + return common.Address{}, err } - // Recover nodeID - nodeID, err := s.getNodeID(msg, sig) + // First, assume EOA signature + recoveredNodeId, err := s.getNodeID(&msg, &sig) if err != nil { - return nil, err + return common.Address{}, err } // Check if the nodeID matches the expected nodeID - if *nodeID != expectedNodeId { - return nil, &AuthenticationError{fmt.Sprintf("provided node id (%s) did not match address (%s) which signed the message", expectedNodeId.Hex(), nodeID.Hex())} + if *recoveredNodeId != expectedNodeId { + // if not, we probably have an EIP-1271 signature + dataHash := common.BytesToHash(accounts.TextHash(msg)) + valid, err := s.rescueProxyClient.ValidateEIP1271(&dataHash, &sig, &expectedNodeId) + if err != nil { + return common.Address{}, &AuthenticationError{fmt.Sprintf("failed to validate EIP-1271 signature: %v", err)} + } + if !valid { + return common.Address{}, &AuthenticationError{"invalid signature: both EOA and EIP-1271 validation failed"} + } } - // Check node authz - if err := s.checkNodeAuthorization(nodeID, ot); err != nil { - return nil, err + // If getNodeID succeeds, check authorization + if err := s.checkNodeAuthorization(&expectedNodeId, ot); err != nil { + // If authorization check passes, we're done + return common.Address{}, err } - return nodeID, nil + return expectedNodeId, nil } func (s *Service) Deinit() { From 6d75c5a7fb0cae2967473d1f91d81125e6116bba Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 24 Oct 2024 15:01:38 -0400 Subject: [PATCH 3/5] Add tests --- util/ethereum_test.go | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 util/ethereum_test.go diff --git a/util/ethereum_test.go b/util/ethereum_test.go new file mode 100644 index 0000000..7259d08 --- /dev/null +++ b/util/ethereum_test.go @@ -0,0 +1,40 @@ +package util + +import ( + "encoding/hex" + "testing" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" +) + +func TestAccountsTextHash(t *testing.T) { + tests := []struct { + name string + input []byte + expected string + }{ + { + name: "Example message", + input: []byte("foo bar"), + expected: "475d68f61c0282c2e194d37d855756f36f73a3f61d1ebbe1eaa42df9e2fe6934", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + resultBytes := accounts.TextHash(tt.input) + resultHash := common.BytesToHash(resultBytes) + + assert.Equal(t, common.HexToHash(tt.expected), resultHash, "Hash mismatch") + + // Additional check: verify the length of the hash + assert.Equal(t, 32, len(resultHash), "Hash length should be 32 bytes") + + // Print the hash in hexadecimal format for visual inspection + t.Logf("Input: %s", string(tt.input)) + t.Logf("Resulting hash: 0x%s", hex.EncodeToString(resultHash.Bytes())) + }) + } +} From 266e06483f4b224f405b34ee9206834c75224b2f Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 24 Oct 2024 22:47:31 -0400 Subject: [PATCH 4/5] Use hexutil for encoding and decoding hex bytes --- api/messages.go | 8 +++++++- api/router.go | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/api/messages.go b/api/messages.go index 50e435e..80423fe 100644 --- a/api/messages.go +++ b/api/messages.go @@ -3,6 +3,7 @@ package api import ( "encoding/json" "errors" + "fmt" "io" "mime" "net/http" @@ -12,6 +13,7 @@ import ( "github.com/Rocket-Rescue-Node/credentials/pb" "github.com/Rocket-Rescue-Node/rescue-api/services" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" ) type response struct { @@ -61,7 +63,11 @@ func (c *CreateCredentialRequest) UnmarshalJSON(data []byte) error { c.Msg = []byte(aux.Msg) // Convert Sig - c.Sig = []byte(aux.Sig) + var err error + c.Sig, err = hexutil.Decode(aux.Sig) + if err != nil { + return fmt.Errorf("invalid signature hex: %v", err) + } return nil } diff --git a/api/router.go b/api/router.go index 4497311..0ee7a63 100644 --- a/api/router.go +++ b/api/router.go @@ -6,6 +6,7 @@ import ( "time" "github.com/Rocket-Rescue-Node/rescue-api/services" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/gorilla/mux" "github.com/rs/cors" "go.uber.org/zap" @@ -28,7 +29,7 @@ func (ar *apiRouter) readJSONRequest(r *http.Request) (*CreateCredentialRequest, zap.String("endpoint", r.URL.Path), zap.String("address", out.Address.Hex()), zap.String("msg", string(out.Msg)), - zap.String("sig", hex.EncodeToString(out.Sig)), + zap.String("sig", hexutil.Encode(out.Sig)), zap.String("version", out.Version), zap.Int("operator_type", int(out.operatorType)), ) From d1c304d9125f1ae479d85dd2d95c76ea36b987b8 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Thu, 24 Oct 2024 23:13:31 -0400 Subject: [PATCH 5/5] Replace deprecated grpc connection code with non deprecated code --- external/rescue_proxy.go | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/external/rescue_proxy.go b/external/rescue_proxy.go index f139d03..8ba4aef 100644 --- a/external/rescue_proxy.go +++ b/external/rescue_proxy.go @@ -34,17 +34,13 @@ func NewRescueProxyAPIClient(logger *zap.Logger, address string, secure bool) *R func (c *RescueProxyAPIClient) connect() error { var err error - ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) - defer cancel() - // Try to connect to the Rescue Proxy API using TLS. // An empty TLS config will use the system's root CAs. tc := credentials.NewTLS(&tls.Config{}) - if c.conn, err = grpc.DialContext(ctx, + if c.conn, err = grpc.NewClient( c.address, grpc.WithTransportCredentials(tc), - grpc.WithBlock()); err == nil { - + ); err == nil { c.client = proxy.NewApiClient(c.conn) c.logger.Debug("connected to rescue-proxy with TLS", zap.String("address", c.address)) return nil @@ -58,14 +54,10 @@ func (c *RescueProxyAPIClient) connect() error { c.logger.Debug("attempting to connect to rescue-proxy without TLS, since insecure grpc is allowed", zap.String("address", c.address)) - ctx, cancel2 := context.WithTimeout(context.Background(), 1*time.Second) - defer cancel2() - - if c.conn, err = grpc.DialContext(ctx, + if c.conn, err = grpc.NewClient( c.address, grpc.WithTransportCredentials(insecure.NewCredentials()), - grpc.WithBlock()); err != nil { - + ); err != nil { return err }