Commit a156d08
committed
canton: bind NTT Receive's recipient to the VAA's recipientAddress via a hash
Receive previously took `recipient : Party` as a plain, relayer-supplied choice
argument with no binding to the VAA's `recipientAddress` at all -- the operator
(the choice's controller) could steer an inbound mint to any Canton party.
recipientAddress is a Bytes32, sized for chains whose native address IS a
fixed-size identifier (EVM, Solana). A Canton Party id has no such fixed-size
form, so there's nothing to compare it against directly.
recipientAddressFor recipient = keccak256("wormhole:ntt-recipient:v1" ‖
lp(partyToText recipient)), mirroring nttManagerAddressFor's style. Receive
keeps `recipient` as a choice argument, but asserts recipientAddressFor
recipient == ntt.recipientAddress before minting: recipientAddress is fixed by
the sender and covered by the guardian signature, so the operator still cannot
steer an inbound mint anywhere the sender didn't address, without needing a
registry template pair or an extra on-ledger lookup on every receive.
Tradeoff, accepted deliberately: a Canton Party id never changes once
allocated (it's the hash of a namespace root, or of a
DecentralizedNamespaceDefinition's founding owners), so this permanently binds
a signed VAA to the recipient party as it existed when the sender computed the
hash. If that party ever needs to change (a lost key, a planned custodial
migration -- not a rename of the same party, which has no meaning in Canton), a
VAA already signed against the old hash cannot be redirected; the sender must
re-send against the new party's hash. A self-service handle registry (resolving
a stable, sender-chosen handle to a party that can be repointed later) avoids
that, at the cost of an extra template pair and a fetchByKey on every receive;
this is the simpler mechanism, accepting a manual re-send as the cost of a
Party ever having to change.
Tests: testRecipientAddressForVector pins the encoding against fixed text (a
live Party's fingerprint is nondeterministic and can't be baked into a
constant -- same reasoning as nttManagerAddressFor's own vector), cross-checked
in node/pkg/cantonclient/vectorgen_test.go:TestGenerateAddressVectors (extended
with the matching preimage shape). testNttReceiveRecipientMismatchFails proves
the check actually gates Receive against the real signed fixture.
Known test gap (documented in README.md and Manager.daml): no automated test
exercises the MATCHING-recipient path through a real Receive call end-to-end.
The fixture is a single, statically pre-signed VAA with a fixed
recipientAddress, and a live Party's fingerprint is freshly and unpredictably
allocated every run, so no allocated Party can ever be made to match it ahead
of time. Closing this needs a live two-step sign-then-relay harness (allocate
the recipient, compute its hash, sign a fresh VAA against that hash via the
guardian test key, then relay it) -- not built here, since it would add back
most of the complexity this change was meant to avoid.
Verified: dpm build --all clean (5 packages); dpm test 20/20; gofmt/go vet/go
test clean on node/pkg/cantonclient and pkg/watchers/canton.1 parent 584340a commit a156d08
4 files changed
Lines changed: 154 additions & 45 deletions
File tree
- canton
- ntt/daml/Wormhole/Ntt
- test/daml/Test
- node/pkg/cantonclient
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
673 | 673 | | |
674 | 674 | | |
675 | 675 | | |
676 | | - | |
| 676 | + | |
677 | 677 | | |
678 | 678 | | |
679 | 679 | | |
| |||
852 | 852 | | |
853 | 853 | | |
854 | 854 | | |
855 | | - | |
856 | | - | |
857 | | - | |
| 855 | + | |
| 856 | + | |
| 857 | + | |
| 858 | + | |
| 859 | + | |
| 860 | + | |
| 861 | + | |
| 862 | + | |
| 863 | + | |
| 864 | + | |
| 865 | + | |
| 866 | + | |
| 867 | + | |
| 868 | + | |
| 869 | + | |
| 870 | + | |
| 871 | + | |
| 872 | + | |
| 873 | + | |
| 874 | + | |
| 875 | + | |
| 876 | + | |
| 877 | + | |
| 878 | + | |
| 879 | + | |
| 880 | + | |
| 881 | + | |
| 882 | + | |
| 883 | + | |
| 884 | + | |
| 885 | + | |
| 886 | + | |
| 887 | + | |
| 888 | + | |
| 889 | + | |
| 890 | + | |
| 891 | + | |
| 892 | + | |
| 893 | + | |
| 894 | + | |
| 895 | + | |
| 896 | + | |
| 897 | + | |
| 898 | + | |
| 899 | + | |
| 900 | + | |
| 901 | + | |
| 902 | + | |
| 903 | + | |
| 904 | + | |
| 905 | + | |
| 906 | + | |
| 907 | + | |
| 908 | + | |
| 909 | + | |
858 | 910 | | |
859 | 911 | | |
860 | 912 | | |
| |||
882 | 934 | | |
883 | 935 | | |
884 | 936 | | |
885 | | - | |
886 | | - | |
| 937 | + | |
| 938 | + | |
| 939 | + | |
| 940 | + | |
| 941 | + | |
| 942 | + | |
| 943 | + | |
887 | 944 | | |
888 | 945 | | |
889 | 946 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
26 | | - | |
| 26 | + | |
| 27 | + | |
27 | 28 | | |
28 | 29 | | |
| 30 | + | |
29 | 31 | | |
30 | 32 | | |
31 | 33 | | |
| |||
65 | 67 | | |
66 | 68 | | |
67 | 69 | | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
68 | 94 | | |
69 | 95 | | |
70 | 96 | | |
| |||
209 | 235 | | |
210 | 236 | | |
211 | 237 | | |
212 | | - | |
213 | | - | |
214 | | - | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
215 | 261 | | |
216 | | - | |
217 | | - | |
218 | | - | |
219 | | - | |
220 | | - | |
| 262 | + | |
| 263 | + | |
221 | 264 | | |
222 | 265 | | |
223 | 266 | | |
| |||
245 | 288 | | |
246 | 289 | | |
247 | 290 | | |
| 291 | + | |
| 292 | + | |
248 | 293 | | |
249 | 294 | | |
250 | 295 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
| 5 | + | |
5 | 6 | | |
6 | 7 | | |
7 | 8 | | |
| |||
218 | 219 | | |
219 | 220 | | |
220 | 221 | | |
221 | | - | |
222 | | - | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
223 | 247 | | |
224 | 248 | | |
225 | | - | |
| 249 | + | |
226 | 250 | | |
227 | 251 | | |
228 | 252 | | |
| |||
231 | 255 | | |
232 | 256 | | |
233 | 257 | | |
234 | | - | |
| 258 | + | |
235 | 259 | | |
236 | 260 | | |
237 | 261 | | |
| |||
250 | 274 | | |
251 | 275 | | |
252 | 276 | | |
253 | | - | |
254 | | - | |
255 | | - | |
256 | | - | |
257 | | - | |
258 | | - | |
259 | | - | |
260 | | - | |
261 | | - | |
262 | | - | |
263 | | - | |
264 | | - | |
265 | | - | |
266 | | - | |
267 | | - | |
268 | | - | |
269 | | - | |
270 | | - | |
271 | | - | |
272 | | - | |
273 | | - | |
274 | | - | |
275 | | - | |
276 | 277 | | |
277 | | - | |
| 278 | + | |
278 | 279 | | |
279 | 280 | | |
280 | 281 | | |
281 | | - | |
| 282 | + | |
282 | 283 | | |
283 | 284 | | |
284 | 285 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
182 | 182 | | |
183 | 183 | | |
184 | 184 | | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
185 | 191 | | |
0 commit comments