Skip to content

Commit

Permalink
NTT / Acct / Node: Guardian support (#3815)
Browse files Browse the repository at this point in the history
* NTT/Acct/Node: Guardian changes

* Add per-emitter enforcement

* complete ntt accountant integration tests and run in parallel

* Minor tweaks

* Increase delay in tests

* fix accountant ci check

* Add CI AR address

* update prefixes

* increase timeout

* update ntt transfer wire format

* Code review rework from PR #3800

* Up tilt timeout

* Allow NTT accountant without base accountant

* Define known automatic relayer emitters

* Code review rework

---------

Co-authored-by: Evan Gray <[email protected]>
  • Loading branch information
bruce-riley and evan-gray authored Mar 8, 2024
1 parent b31bec7 commit 3a9dfd9
Show file tree
Hide file tree
Showing 42 changed files with 4,120 additions and 743 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
kubectl config use-context ci
# temporarily set --guardiand_loglevel=info to debug https://github.com/wormhole-foundation/wormhole/issues/3052
- run: tilt ci -- --ci --namespace=$DEPLOY_NS --num=2 --guardiand_loglevel=info
- run: tilt ci --timeout 45m0s -- --ci --namespace=$DEPLOY_NS --num=2 --guardiand_loglevel=info
timeout-minutes: 60

# Clean up k8s resources
Expand Down
18 changes: 16 additions & 2 deletions Tiltfile
Original file line number Diff line number Diff line change
Expand Up @@ -274,17 +274,25 @@ def build_node_yaml():
"--wormchainURL",
"wormchain:9090",

"--accountantWS",
"http://wormchain:26657",

"--accountantContract",
"wormhole14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9srrg465",
"--accountantKeyPath",
"/tmp/mounted-keys/wormchain/accountantKey",
"--accountantKeyPassPhrase",
"test0000",
"--accountantWS",
"http://wormchain:26657",
"--accountantCheckEnabled",
"true",

"--accountantNttContract",
"wormhole17p9rzwnnfxcjp32un9ug7yhhzgtkhvl9jfksztgw5uh69wac2pgshdnj3k",
"--accountantNttKeyPath",
"/tmp/mounted-keys/wormchain/accountantNttKey",
"--accountantNttKeyPassPhrase",
"test0000",

"--ibcContract",
"wormhole1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrq0kdhcj",
"--ibcWS",
Expand Down Expand Up @@ -597,6 +605,12 @@ if ci_tests:
trigger_mode = trigger_mode,
resource_deps = [], # uses devnet-consts.json, but wormchain/contracts/tools/test_accountant.sh handles waiting for guardian, not having deps gets the build earlier
)
k8s_resource(
"ntt-accountant-ci-tests",
labels = ["ci"],
trigger_mode = trigger_mode,
resource_deps = [], # uses devnet-consts.json, but wormchain/contracts/tools/test_ntt_accountant.sh handles waiting for guardian, not having deps gets the build earlier
)
k8s_resource(
"query-ci-tests",
labels = ["ci"],
Expand Down
2 changes: 1 addition & 1 deletion devnet/eth-devnet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ spec:
- --wallet.deterministic
- --chain.time="1970-01-01T00:00:00+00:00"
- --host=0.0.0.0
- --wallet.totalAccounts=11
- --wallet.totalAccounts=13
- --chain.chainId=1
- --chain.asyncRequestProcessing=false
ports:
Expand Down
2 changes: 1 addition & 1 deletion devnet/eth-devnet2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ spec:
- --wallet.deterministic
- --chain.time="1970-01-01T00:00:00+00:00"
- --host=0.0.0.0
- --wallet.totalAccounts=11
- --wallet.totalAccounts=13
- --chain.chainId=1397
- --chain.asyncRequestProcessing=false
ports:
Expand Down
6 changes: 6 additions & 0 deletions devnet/node.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ spec:
path: gwrelayerKey0
- key: gwrelayerKey1
path: gwrelayerKey1
- key: accountantNttKey0
path: accountantNttKey0
- key: accountantNttKey1
path: accountantNttKey1
- name: node-config
configMap:
name: node-config
Expand Down Expand Up @@ -224,6 +228,8 @@ data:
accountantKey1: LS0tLS1CRUdJTiBURU5ERVJNSU5UIFBSSVZBVEUgS0VZLS0tLS0Ka2RmOiBiY3J5cHQKc2FsdDogNzc1M0NCQTBBMUQ0NTJCMkE2QzlERDM4ODc3MTg0NEEKdHlwZTogc2VjcDI1NmsxCgpSYnhRVWRnK2ZHcjMzZTAyVWFFQW1YTDFlNFkrTGJUMFdqbnl4RVR3OXBoL2JXOGI0MzdhWmErOWlCc3NBa0UyCnRScUwvb0J1NWFnQXJocHNnWUgxNlhOWjJHMXRwY0R3V0dQZ1VWVT0KPUd6YUwKLS0tLS1FTkQgVEVOREVSTUlOVCBQUklWQVRFIEtFWS0tLS0t
gwrelayerKey0: LS0tLS1CRUdJTiBURU5ERVJNSU5UIFBSSVZBVEUgS0VZLS0tLS0KdHlwZTogc2VjcDI1NmsxCmtkZjogYmNyeXB0CnNhbHQ6IDc4OUYzRTBCMkVGNDcyNjAyQzNFMUE0OUI2OENFQzlBCgpGWHAvSllPS3E4WmZtOWxHZ3ZFNEM3NXFyUXFNZFp2RHNWRjhObTdMQU1oR2dHbXBnZnpoZjUrZ3IwZ1hjYjVWCmtSTXA2c0p0NkxCVzRPYWF2ckk3ay84Vml2NWhMVU1la1dPMHg5bz0KPUxrb1MKLS0tLS1FTkQgVEVOREVSTUlOVCBQUklWQVRFIEtFWS0tLS0t
gwrelayerKey1: LS0tLS1CRUdJTiBURU5ERVJNSU5UIFBSSVZBVEUgS0VZLS0tLS0Ka2RmOiBiY3J5cHQKc2FsdDogNDc5RDk3RDE2OTE0QkQ4QjlFNUUwQzkzMDA0RDA4RUEKdHlwZTogc2VjcDI1NmsxCgpvTEJ0aUkwT2pudXo5bHlzeVlZOFhQeEVkTnpwYUJOVWFkL0UySlJld2pFWFZNVVNTWll2QVZKbERiN3hEQjlSCmEvdm45SFNPM2hKOFc1QTBKOVFqUVZXRzVoZXBNZVpQUEI4M1FCUT0KPVJuTGEKLS0tLS1FTkQgVEVOREVSTUlOVCBQUklWQVRFIEtFWS0tLS0t
accountantNttKey0: LS0tLS1CRUdJTiBURU5ERVJNSU5UIFBSSVZBVEUgS0VZLS0tLS0Ka2RmOiBiY3J5cHQKc2FsdDogNzI4NTBEREJFNDQ4NzZBN0Q1Q0YxNDlBQjBGQjNBQzEKdHlwZTogc2VjcDI1NmsxCgpYN1BGMUJaZFBZMmlvRHdVRm9KcXdVdVg4YlFmcFNGckk4UklPS2g1ZUg5cCtDUzZYMm5lM2hVWGFPTDB3YXhUCnM3QVduTzErU241L1g1V0NicklqNHdDVUcwUWdNb0IyN2VFQnB2ND0KPWJiSEkKLS0tLS1FTkQgVEVOREVSTUlOVCBQUklWQVRFIEtFWS0tLS0t
accountantNttKey1: LS0tLS1CRUdJTiBURU5ERVJNSU5UIFBSSVZBVEUgS0VZLS0tLS0Ka2RmOiBiY3J5cHQKc2FsdDogNEI2NDI1NDY0MDY0RTIzQjJENUUyNkQyNUI1QUIzQTcKdHlwZTogc2VjcDI1NmsxCgp2NDFNNGdqelc2MHVwcUhyb2l3aURYakVJMEE5WjN1R2lZcmdyNVpjUit2c3V5RFdDZWNXZUFqV2NXb2tINmRhCldKQ1cvdjNua1pqa0xhajByeEpxYTNrSThodDBtdjZ4eDB0WHhSUT0KPUpSZS8KLS0tLS1FTkQgVEVOREVSTUlOVCBQUklWQVRFIEtFWS0tLS0t
---
apiVersion: v1
kind: ConfigMap
Expand Down
27 changes: 26 additions & 1 deletion devnet/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,32 @@ spec:
command:
- test
- -e
- "/app/accountant/success"
- "/app/tools/success"
initialDelaySeconds: 5
periodSeconds: 5
---
kind: Job
apiVersion: batch/v1
metadata:
name: ntt-accountant-ci-tests
spec:
backoffLimit: 0
template:
spec:
restartPolicy: Never
containers:
- name: ntt-accountant-ci-tests
image: wormchain-deploy
command:
- /bin/sh
- -c
- "bash /app/tools/test_ntt_accountant.sh && touch /app/tools/success"
readinessProbe:
exec:
command:
- test
- -e
- "/app/tools/success"
initialDelaySeconds: 5
periodSeconds: 5
---
Expand Down
89 changes: 54 additions & 35 deletions node/cmd/guardiand/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,7 @@ var (
nearRPC *string
nearContract *string

wormchainURL *string
wormchainKeyPath *string
wormchainKeyPassPhrase *string
wormchainURL *string

ibcWS *string
ibcLCD *string
Expand All @@ -145,6 +143,10 @@ var (
accountantKeyPath *string
accountantKeyPassPhrase *string

accountantNttContract *string
accountantNttKeyPath *string
accountantNttKeyPassPhrase *string

aptosRPC *string
aptosAccount *string
aptosHandle *string
Expand Down Expand Up @@ -309,9 +311,6 @@ func init() {
nearContract = NodeCmd.Flags().String("nearContract", "", "Near contract")

wormchainURL = node.RegisterFlagWithValidationOrFail(NodeCmd, "wormchainURL", "Wormhole-chain gRPC URL", "wormchain:9090", []string{""})
// TODO: These are deprecated. Get rid of them once the guardians have had a chance to migrate off of them.
wormchainKeyPath = NodeCmd.Flags().String("wormchainKeyPath", "", "path to wormhole-chain private key for signing transactions")
wormchainKeyPassPhrase = NodeCmd.Flags().String("wormchainKeyPassPhrase", "", "pass phrase used to unarmor the wormchain key file")

ibcWS = node.RegisterFlagWithValidationOrFail(NodeCmd, "ibcWS", "Websocket used to listen to the IBC receiver smart contract on wormchain", "ws://wormchain:26657/websocket", []string{"ws", "wss"})
ibcLCD = node.RegisterFlagWithValidationOrFail(NodeCmd, "ibcLCD", "Path to LCD service root for http calls", "http://wormchain:1317", []string{"http", "https"})
Expand All @@ -324,6 +323,10 @@ func init() {
accountantKeyPassPhrase = NodeCmd.Flags().String("accountantKeyPassPhrase", "", "pass phrase used to unarmor the accountant key file")
accountantCheckEnabled = NodeCmd.Flags().Bool("accountantCheckEnabled", false, "Should accountant be enforced on transfers")

accountantNttContract = NodeCmd.Flags().String("accountantNttContract", "", "Address of the NTT accountant smart contract on wormchain")
accountantNttKeyPath = NodeCmd.Flags().String("accountantNttKeyPath", "", "path to NTT accountant private key for signing transactions")
accountantNttKeyPassPhrase = NodeCmd.Flags().String("accountantNttKeyPassPhrase", "", "pass phrase used to unarmor the NTT accountant key file")

aptosRPC = node.RegisterFlagWithValidationOrFail(NodeCmd, "aptosRPC", "Aptos RPC URL", "http://aptos:8080", []string{"http", "https"})
aptosAccount = NodeCmd.Flags().String("aptosAccount", "", "aptos account")
aptosHandle = NodeCmd.Flags().String("aptosHandle", "", "aptos handle")
Expand Down Expand Up @@ -1027,51 +1030,67 @@ func runNode(cmd *cobra.Command, args []string) {
wormchainId = "wormchain-testnet-0"
}

var accountantWormchainConn *wormconn.ClientConn
var accountantWormchainConn, accountantNttWormchainConn *wormconn.ClientConn
if *accountantContract != "" {
// TODO: wormchainKeyPath and wormchainKeyPassPhrase are being replaced by accountantKeyPath and accountantKeyPassPhrase.
// Give the guardians time to migrate off of the old parameters, but then remove them.
keyPath := *accountantKeyPath
if keyPath == "" {
if *wormchainKeyPath == "" {
logger.Fatal("if accountantContract is specified, accountantKeyPath is required", zap.String("component", "gacct"))
}
logger.Error("the wormchainKeyPath parameter is deprecated, please change to accountantKeyPath", zap.String("component", "gacct"))
keyPath = *wormchainKeyPath
} else if *wormchainKeyPath != "" {
logger.Fatal("the wormchainKeyPath parameter is obsolete, please remove it", zap.String("component", "gacct"))
if *accountantKeyPath == "" {
logger.Fatal("if accountantContract is specified, accountantKeyPath is required", zap.String("component", "gacct"))
}

keyPassPhrase := *accountantKeyPassPhrase
if keyPassPhrase == "" {
if *wormchainKeyPassPhrase == "" {
logger.Fatal("if accountantContract is specified, accountantKeyPassPhrase is required", zap.String("component", "gacct"))
}
logger.Error("the wormchainKeyPassPhrase parameter is deprecated, please change to accountantKeyPassPhrase", zap.String("component", "gacct"))
keyPassPhrase = *wormchainKeyPassPhrase
} else if *wormchainKeyPassPhrase != "" {
logger.Fatal("the wormchainKeyPassPhrase parameter is obsolete, please remove it", zap.String("component", "gacct"))
if *accountantKeyPassPhrase == "" {
logger.Fatal("if accountantContract is specified, accountantKeyPassPhrase is required", zap.String("component", "gacct"))
}

keyPathName := keyPath
keyPathName := *accountantKeyPath
if *unsafeDevMode {
idx, err := devnet.GetDevnetIndex()
if err != nil {
logger.Fatal("failed to get devnet index", zap.Error(err), zap.String("component", "gacct"))
}
keyPathName = fmt.Sprint(keyPath, idx)
keyPathName = fmt.Sprint(*accountantKeyPath, idx)
}

wormchainKey, err := wormconn.LoadWormchainPrivKey(keyPathName, keyPassPhrase)
wormchainKey, err := wormconn.LoadWormchainPrivKey(keyPathName, *accountantKeyPassPhrase)
if err != nil {
logger.Fatal("failed to load wormchain private key", zap.Error(err), zap.String("component", "gacct"))
logger.Fatal("failed to load accountant private key", zap.Error(err), zap.String("component", "gacct"))
}

// Connect to wormchain.
logger.Info("Connecting to wormchain", zap.String("wormchainURL", *wormchainURL), zap.String("keyPath", keyPathName), zap.String("component", "gacct"))
// Connect to wormchain for the accountant.
logger.Info("Connecting to wormchain for accountant", zap.String("wormchainURL", *wormchainURL), zap.String("keyPath", keyPathName), zap.String("component", "gacct"))
accountantWormchainConn, err = wormconn.NewConn(rootCtx, *wormchainURL, wormchainKey, wormchainId)
if err != nil {
logger.Fatal("failed to connect to wormchain", zap.Error(err), zap.String("component", "gacct"))
logger.Fatal("failed to connect to wormchain for accountant", zap.Error(err), zap.String("component", "gacct"))
}
}

// If the NTT accountant is enabled, create a wormchain connection for it.
if *accountantNttContract != "" {
if *accountantNttKeyPath == "" {
logger.Fatal("if accountantNttContract is specified, accountantNttKeyPath is required", zap.String("component", "gacct"))
}

if *accountantNttKeyPassPhrase == "" {
logger.Fatal("if accountantNttContract is specified, accountantNttKeyPassPhrase is required", zap.String("component", "gacct"))
}

keyPathName := *accountantNttKeyPath
if *unsafeDevMode {
idx, err := devnet.GetDevnetIndex()
if err != nil {
logger.Fatal("failed to get devnet index", zap.Error(err), zap.String("component", "gacct"))
}
keyPathName = fmt.Sprint(*accountantNttKeyPath, idx)
}

wormchainKey, err := wormconn.LoadWormchainPrivKey(keyPathName, *accountantNttKeyPassPhrase)
if err != nil {
logger.Fatal("failed to load NTT accountant private key", zap.Error(err), zap.String("component", "gacct"))
}

// Connect to wormchain for the NTT accountant.
logger.Info("Connecting to wormchain for NTT accountant", zap.String("wormchainURL", *wormchainURL), zap.String("keyPath", keyPathName), zap.String("component", "gacct"))
accountantNttWormchainConn, err = wormconn.NewConn(rootCtx, *wormchainURL, wormchainKey, wormchainId)
if err != nil {
logger.Fatal("failed to connect to wormchain for NTT accountant", zap.Error(err), zap.String("component", "gacct"))
}
}

Expand Down Expand Up @@ -1553,7 +1572,7 @@ func runNode(cmd *cobra.Command, args []string) {
guardianOptions := []*node.GuardianOption{
node.GuardianOptionDatabase(db),
node.GuardianOptionWatchers(watcherConfigs, ibcWatcherConfig),
node.GuardianOptionAccountant(*accountantContract, *accountantWS, *accountantCheckEnabled, accountantWormchainConn),
node.GuardianOptionAccountant(*accountantWS, *accountantContract, *accountantCheckEnabled, accountantWormchainConn, *accountantNttContract, accountantNttWormchainConn),
node.GuardianOptionGovernor(*chainGovernorEnabled),
node.GuardianOptionGatewayRelayer(*gatewayRelayerContract, gatewayRelayerWormchainConn),
node.GuardianOptionQueryHandler(*ccqEnabled, *ccqAllowedRequesters),
Expand Down
2 changes: 1 addition & 1 deletion node/hack/accountant/send_obs.go
Original file line number Diff line number Diff line change
Expand Up @@ -437,5 +437,5 @@ func submit(
gsIndex := uint32(0)
guardianIndex := uint32(0)

return accountant.SubmitObservationsToContract(ctx, logger, gk, gsIndex, guardianIndex, wormchainConn, contract, msgs)
return accountant.SubmitObservationsToContract(ctx, logger, gk, gsIndex, guardianIndex, wormchainConn, contract, accountant.SubmitObservationPrefix, msgs)
}
Loading

0 comments on commit 3a9dfd9

Please sign in to comment.