Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ShouldSendMessage decider #344

Merged
merged 32 commits into from
Jul 26, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
1b161e6
`ShouldSendMessage` decider service support
feuGeneA Jun 21, 2024
5c6422e
rm superfluous/duplicate comment
feuGeneA Jul 19, 2024
584556e
msg handler: extract `deciderRejectedMsg()` helper
feuGeneA Jul 19, 2024
562cf7c
extract helper `initializeDeciderClient()`
feuGeneA Jul 19, 2024
b01b14b
main: deciderClient as main() local, not global
feuGeneA Jul 19, 2024
0d6b07b
Merge remote-tracking branch 'origin/main' into decider
feuGeneA Jul 19, 2024
249de65
Apply suggestions from code review
feuGeneA Jul 19, 2024
81b30bc
proto .sh: pull protoc-gen-go version from go.mod
feuGeneA Jul 22, 2024
ed3f4e7
rm unused github_token from .github workflow
feuGeneA Jul 22, 2024
f897c89
Merge branch 'main' into decider
feuGeneA Jul 22, 2024
f89bd35
add timeout to decider delegation
feuGeneA Jul 22, 2024
3631b7b
follow ava-go: exclude ver from proto svc name
feuGeneA Jul 22, 2024
be38f17
add descriptions of new config options
feuGeneA Jul 22, 2024
aab66d5
validate uri
feuGeneA Jul 22, 2024
df26aa2
improve readbility of decider invocation
feuGeneA Jul 24, 2024
a9c374c
validate decider host/port in config, not main
feuGeneA Jul 24, 2024
6a9c276
explain `createDeciderClient()`
feuGeneA Jul 24, 2024
c37fd41
add to README
feuGeneA Jul 24, 2024
7eb5112
config: just DeciderURL, not Host/Port
feuGeneA Jul 24, 2024
598f9bb
Merge branch 'main' into decider
feuGeneA Jul 25, 2024
7e02e1a
stop returning bool pointer
feuGeneA Jul 25, 2024
0a22497
rename and document helper method
feuGeneA Jul 25, 2024
742a6ee
e2e test: panic if decider exits abnormally
feuGeneA Jul 25, 2024
1837d4b
Update messages/teleporter/message_handler.go
feuGeneA Jul 25, 2024
8ed8112
streamline getShouldSendMessageFromDecider flow
feuGeneA Jul 25, 2024
6488c81
Update config/config.go
feuGeneA Jul 25, 2024
9a7944d
stop decoding warpMsgID
feuGeneA Jul 25, 2024
19e8689
rename parameter
feuGeneA Jul 25, 2024
682fead
remove redundant assignment of nil to interface
feuGeneA Jul 25, 2024
79c82b2
`deciderConnection`, not just `deciderClient`
feuGeneA Jul 26, 2024
c4b2262
add comment to separate two "halves" of function
feuGeneA Jul 26, 2024
f8662fd
when conn==nil, init client to "empty" impl
feuGeneA Jul 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,10 @@ jobs:
with:
submodules: recursive

- name: Install buf
uses: bufbuild/[email protected]
with:
github_token: ${{ github.token }}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the github token necessary? Does the repo even have access to a gh token?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently not. I removed this in ed3f4e7 and everything still ran fine. I had just copied this from avalanchego. Thanks for noticing it.


- name: Run E2E Tests
run: AVALANCHEGO_BUILD_PATH=/tmp/e2e-test/avalanchego DATA_DIR=/tmp/e2e-test/data ./scripts/e2e_test.sh
12 changes: 12 additions & 0 deletions .github/workflows/linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,17 @@ jobs:
with:
go-version-file: 'go.mod'

- name: Install buf
uses: bufbuild/[email protected]
with:
github_token: ${{ github.token }}

- name: Run Lint
run: ./scripts/lint.sh --go-lint

- name: Ensure protobuf changes are checked in
run: |
scripts/protobuf_codegen.sh
git update-index --really-refresh >> /dev/null
git diff-index HEAD # to show the differences
git diff-index --quiet HEAD || (echo 'protobuf generated code changes have not all been checked in' && exit 1)
Comment on lines +39 to +41
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the difference between this method of checking that generated files are checked in versus the one we use in teleporter? https://github.com/ava-labs/teleporter/blob/main/.github/workflows/abi_bindings_checker.yml#L41

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
build/
__debug_bin
tests/cmd/decider/decider

.vscode*

Expand Down
2 changes: 1 addition & 1 deletion README.md
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add descriptions of the new config options.

Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ awm-relayer --help Display awm-relayer usag

### Building

Before building, be sure to install Go, which is required even if you're just building the Docker image.
Before building, be sure to install Go, which is required even if you're just building the Docker image. You'll also need to install [buf](github.com/bufbuild/buf/).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is buf required even if the Decider is unused (i.e. the relevant config options are omitted)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order to build, yes, because the relayer binary is built to be aware of the protobuf interfaces so that that same binary can be used later if you decide you do want to include those config options.


Build the relayer by running the script:

Expand Down
2 changes: 2 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ type Config struct {
SourceBlockchains []*SourceBlockchain `mapstructure:"source-blockchains" json:"source-blockchains"`
DestinationBlockchains []*DestinationBlockchain `mapstructure:"destination-blockchains" json:"destination-blockchains"`
ProcessMissedBlocks bool `mapstructure:"process-missed-blocks" json:"process-missed-blocks"`
DeciderHost string `mapstructure:"decider-host" json:"decider-host"`
DeciderPort *uint16 `mapstructure:"decider-port" json:"decider-port"`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add some validation on these new fields? If they're provided, they should be able to construct a valid URI.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed in a9c374c

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thoughts on combining these into a unified URI?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way I have it coded right now, you can skip specifying a host, and it will assume localhost, which felt nice for the case when the decider is running locally. It's nice, but not a huge deal. I'm definitely open to other opinions.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just calling this out because I wasn't aware how it worked exactly myself:

AvalancheGo communicates with VM plugins via gprc, but instead of assuming the VMs are running and providing their host/port in the configuration, it starts the configured VMs itself on the first port available on 127.0.0.1 here.

That type of pattern may be less error prone for relayers to set up. i.e: the relayer config would specify the decider plugin(s) (if any) to run for a given source chain, and the application would handle initializing/configuring them itself.

Not suggesting we do this now, but could be worth considering going forward.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that what Michael described is the generally preferred pattern for colocated services, and I agree that less config is better and less error prone.

A counter example for why we would want to keep it, is that this allows for using remote deciders.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cam and I also discussed this. For this iteration I was going for the simplest thing possible, and sub-process management proved non-trivial, so I went with this host/port approach instead, since we said that ultimately we want to be able to support both local and remote deciders.

Going forward, I'm open to doing the sub-process/plugin approach; we may be able to leverage the sub-process modules available in avalanchego, but if not then the complexity added to the code base for this would be a lot, at least as compared to the host/port approach.

Also, at the moment I'm leaning towards just the host/port approach so that there's one single config interface, rather than one for a local decider (the plugin path) and a separate/different one for a remote decider (the host/port).


// convenience field to fetch a blockchain's subnet ID
blockchainIDToSubnetID map[ids.ID]ids.ID
Expand Down
13 changes: 6 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ require (
github.com/aws/aws-sdk-go-v2/config v1.27.9
github.com/aws/aws-sdk-go-v2/service/kms v1.32.1
github.com/ethereum/go-ethereum v1.12.0
github.com/golang/protobuf v1.5.4
github.com/onsi/ginkgo/v2 v2.19.0
github.com/onsi/gomega v1.33.1
github.com/pkg/errors v0.9.1
Expand All @@ -22,6 +23,7 @@ require (
github.com/stretchr/testify v1.9.0
go.uber.org/mock v0.4.0
go.uber.org/zap v1.27.0
google.golang.org/grpc v1.64.0
)

require (
Expand Down Expand Up @@ -85,9 +87,8 @@ require (
golang.org/x/exp v0.0.0-20231127185646-65229373498e // indirect
golang.org/x/mod v0.17.0 // indirect
golang.org/x/tools v0.21.0 // indirect
google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
)

Expand All @@ -108,10 +109,9 @@ require (
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-stack/stack v1.8.1 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/gorilla/rpc v1.2.0 // indirect
github.com/gorilla/websocket v1.4.2 // indirect
Expand Down Expand Up @@ -154,8 +154,7 @@ require (
golang.org/x/text v0.15.0 // indirect
golang.org/x/time v0.3.0 // indirect
gonum.org/v1/gonum v0.11.0 // indirect
google.golang.org/grpc v1.58.3 // indirect
google.golang.org/protobuf v1.33.0 // indirect
google.golang.org/protobuf v1.33.0
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
26 changes: 12 additions & 14 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -273,8 +273,8 @@ github.com/golang-jwt/jwt/v4 v4.3.0 h1:kHL1vqdqWNfATmA0FNMdmZNMyZI1U6O31X4rlIPoB
github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=
github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE=
github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ=
github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68=
github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
Expand All @@ -301,8 +301,8 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
github.com/golang/protobuf v1.4.3/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=
Expand Down Expand Up @@ -347,8 +347,8 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4
github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg=
github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
Expand Down Expand Up @@ -1011,12 +1011,10 @@ google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 h1:L6iMMGrtzgHsWofoFcihmDEMYeDR9KN/ThbPWGrh++g=
google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5/go.mod h1:oH/ZOT02u4kWEp7oYBGYFFkCdKS/uYR9Z7+0/xuuFp8=
google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d h1:DoPTO70H+bcDXcd39vOqb2viZxgqeBeSGtZ55yZU4/Q=
google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M=
google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 h1:RFiFrvy37/mpSpdySBDrUdipW/dHwsRwh3J3+A9VgT4=
google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237/go.mod h1:Z5Iiy3jtmioajWHDGFk7CeugTyHtPvMHA4UTmUkyalE=
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.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
Expand All @@ -1039,8 +1037,8 @@ google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ=
google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
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=
Expand Down
39 changes: 38 additions & 1 deletion main/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"log"
"net/http"
"os"
"runtime"
"strconv"
"strings"

"github.com/ava-labs/avalanchego/api/metrics"
Expand All @@ -33,9 +35,16 @@ import (
"go.uber.org/atomic"
"go.uber.org/zap"
"golang.org/x/sync/errgroup"
"google.golang.org/grpc"
"google.golang.org/grpc/connectivity"
"google.golang.org/grpc/credentials/insecure"
)

var version = "v0.0.0-dev"
var (
version = "v0.0.0-dev"

grpcClient *grpc.ClientConn // for connecting to the decider service
geoff-vball marked this conversation as resolved.
Show resolved Hide resolved
)

func main() {
fs := config.BuildFlagSet()
Expand Down Expand Up @@ -216,6 +225,33 @@ func main() {

// Create listeners for each of the subnets configured as a source
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this comment is duplicated on line 254. Was that intended?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved it, but I think the original crept back in as a merge conflict. Thanks for pointing it out. Addressed in 5c6422e

errGroup, ctx := errgroup.WithContext(context.Background())

if cfg.DeciderPort != nil {
geoff-vball marked this conversation as resolved.
Show resolved Hide resolved
port := strconv.FormatUint(uint64(*cfg.DeciderPort), 10)

host := cfg.DeciderHost
if len(host) == 0 {
host = "localhost"
}

grpcClient, err = grpc.NewClient(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use a more descriptive variable name, such as deciderClient?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed in b01b14b

strings.Join([]string{host, port}, ":"),
grpc.WithTransportCredentials(
insecure.NewCredentials(),
),
)
if err != nil {
logger.Fatal(
"Failed to instantiate decider client",
zap.Error(err),
)
panic(err)
}
runtime.SetFinalizer(grpcClient, func(c *grpc.ClientConn) { c.Close() })
grpcClient.WaitForStateChange(ctx, connectivity.Ready)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe WaitForStateChange is currently marked as experimental:

https://pkg.go.dev/google.golang.org/grpc#ClientConn.WaitForStateChange

Not sure if this is an issue, just wanted to point it out.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}

// Create listeners for each of the subnets configured as a source
for _, s := range cfg.SourceBlockchains {
sourceBlockchain := s

Expand Down Expand Up @@ -259,6 +295,7 @@ func createMessageHandlerFactories(
logger,
address,
cfg,
grpcClient,
)
case config.OFF_CHAIN_REGISTRY:
m, err = offchainregistry.NewMessageHandlerFactory(
Expand Down
58 changes: 57 additions & 1 deletion messages/teleporter/message_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ package teleporter

import (
"context"
"encoding/hex"
"encoding/json"
"fmt"
"reflect"
"time"

"github.com/ava-labs/avalanchego/ids"
Expand All @@ -15,6 +17,7 @@ import (
warpPayload "github.com/ava-labs/avalanchego/vms/platformvm/warp/payload"
"github.com/ava-labs/awm-relayer/config"
"github.com/ava-labs/awm-relayer/messages"
pbDecider "github.com/ava-labs/awm-relayer/proto/pb/decider/v1"
"github.com/ava-labs/awm-relayer/utils"
"github.com/ava-labs/awm-relayer/vms"
"github.com/ava-labs/subnet-evm/accounts/abi/bind"
Expand All @@ -25,25 +28,29 @@ import (
teleporterUtils "github.com/ava-labs/teleporter/utils/teleporter-utils"
"github.com/ethereum/go-ethereum/common"
"go.uber.org/zap"
"google.golang.org/grpc"
)

type factory struct {
messageConfig Config
protocolAddress common.Address
logger logging.Logger
deciderClient pbDecider.DeciderServiceClient
}

type messageHandler struct {
logger logging.Logger
teleporterMessage *teleportermessenger.TeleporterMessage
unsignedMessage *warp.UnsignedMessage
factory *factory
deciderClient pbDecider.DeciderServiceClient
}

func NewMessageHandlerFactory(
logger logging.Logger,
messageProtocolAddress common.Address,
messageProtocolConfig config.MessageProtocolConfig,
grpcClient *grpc.ClientConn,
) (messages.MessageHandlerFactory, error) {
// Marshal the map and unmarshal into the Teleporter config
data, err := json.Marshal(messageProtocolConfig.Settings)
Expand All @@ -65,10 +72,18 @@ func NewMessageHandlerFactory(
return nil, err
}

var deciderClient pbDecider.DeciderServiceClient
if grpcClient == nil {
deciderClient = nil
geoff-vball marked this conversation as resolved.
Show resolved Hide resolved
} else {
deciderClient = pbDecider.NewDeciderServiceClient(grpcClient)
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move this to main so that grpcClient can be limited in scope to main? When we get to #365 we'll have to handle dialing different grpcClients per message type, so some refactoring will be necessary anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed in b01b14b


return &factory{
messageConfig: messageConfig,
protocolAddress: messageProtocolAddress,
logger: logger,
deciderClient: deciderClient,
}, nil
}

Expand All @@ -86,6 +101,7 @@ func (f *factory) NewMessageHandler(unsignedMessage *warp.UnsignedMessage) (mess
teleporterMessage: teleporterMessage,
unsignedMessage: unsignedMessage,
factory: f,
deciderClient: f.deciderClient,
}, nil
}

Expand Down Expand Up @@ -167,7 +183,47 @@ func (m *messageHandler) ShouldSendMessage(destinationClient vms.DestinationClie
return false, nil
}

feuGeneA marked this conversation as resolved.
Show resolved Hide resolved
return true, nil
var decision bool = true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be initialized to false? It looks like the error cases are just returning decision without modifying it, and I assume we should return false in those cases.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intended control flow here is to separate the existing ShouldSendMessage decision logic from the Decider logic that is dispatched to the service. If the Decider fails, then we should return the prior decision from the existing logic.

I think this could be made clearer by adding a new helper, and calling it like so:

ShouldSendMessage() {
  // Existing decision logic
  decision, err :=  m.dispatchToDecider()
  if err != nil
    // log the error, but do not return it
    log.Warn("Decider returned error")
    return true, nil  
  }
  return decision
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I extracted the logic into a new helper, and adapted my changes to ShouldSendMessage to fit the existing flow logic (if __ return false; if ___ return false; ...; return true), in 584556e

deciderClientValue := reflect.ValueOf(m.deciderClient)
if deciderClientValue.IsValid() && !deciderClientValue.IsNil() {
geoff-vball marked this conversation as resolved.
Show resolved Hide resolved
warpMsgIDStr := m.unsignedMessage.ID().Hex()

warpMsgID, err := hex.DecodeString(warpMsgIDStr)
if err != nil {
m.logger.Error(
"Error decoding message ID",
zap.String("warpMsgIDStr", warpMsgIDStr),
zap.Error(err),
)
return decision, err
}

// TODO: add a timeout to the context
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's include timeouts in this PR

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed in f89bd35

response, err := m.deciderClient.ShouldSendMessage(
context.Background(),
&pbDecider.ShouldSendMessageRequest{
NetworkId: m.unsignedMessage.NetworkID,
SourceChainId: m.unsignedMessage.SourceChainID[:],
Payload: m.unsignedMessage.Payload,
BytesRepresentation: m.unsignedMessage.Bytes(),
Id: warpMsgID,
},
)
if err != nil {
m.logger.Error(
"Error response from decider.",
zap.String("destinationBlockchainID", destinationBlockchainID.String()),
zap.String("teleporterMessageID", teleporterMessageID.String()),
zap.Any("warpMessageID", warpMsgIDStr),
zap.Error(err),
)
return decision, err
}
geoff-vball marked this conversation as resolved.
Show resolved Hide resolved

decision = response.ShouldSendMessage
}

return decision, nil
}

// SendMessage extracts the gasLimit and packs the call data to call the receiveCrossChainMessage
Expand Down
1 change: 1 addition & 0 deletions messages/teleporter/message_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ func TestShouldSendMessage(t *testing.T) {
logger,
messageProtocolAddress,
messageProtocolConfig,
nil,
)
require.NoError(t, err)
messageHandler, err := factory.NewMessageHandler(test.warpUnsignedMessage)
Expand Down
11 changes: 11 additions & 0 deletions proto/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Protobuf linting and generation for this project is managed by
[buf](https://github.com/bufbuild/buf).

Please find installation instructions on
feuGeneA marked this conversation as resolved.
Show resolved Hide resolved
[https://docs.buf.build/installation/](https://docs.buf.build/installation/).

Any changes made to proto definition can be updated by running
feuGeneA marked this conversation as resolved.
Show resolved Hide resolved
`protobuf_codegen.sh` located in the `scripts/` directory of this repo.

Introduction to `buf`
[https://docs.buf.build/tour/introduction](https://docs.buf.build/tour/introduction)
8 changes: 8 additions & 0 deletions proto/buf.gen.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
version: v1
plugins:
- name: go
out: pb
opt: paths=source_relative
- name: go-grpc
out: pb
opt: paths=source_relative
8 changes: 8 additions & 0 deletions proto/buf.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Generated by buf. DO NOT EDIT.
version: v1
deps:
- remote: buf.build
owner: prometheus
repository: client-model
commit: e171c0b235c546d5a9a597c2961bd357
digest: shake256:7db3f73ac0f1dce71e70f304f318e9741e857fd78b7b42f0df7a3da353fbb2f387899da7b0a77ac9ee9565194510e39a913cdb9a8ab3c2ff4b8713428c795213
Loading