wormhole/node/pkg/devnet/guardianset_vaa.go

90 lines
2.3 KiB
Go

package devnet
import (
"context"
"fmt"
"time"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
"go.uber.org/zap"
"github.com/certusone/wormhole/node/pkg/ethereum/abi"
"github.com/certusone/wormhole/node/pkg/supervisor"
"github.com/certusone/wormhole/node/pkg/vaa"
)
// DevnetGuardianSetVSS returns a VAA signed by guardian-0 that adds all n validators.
func DevnetGuardianSetVSS(n uint) *vaa.VAA {
pubkeys := make([]common.Address, n)
for n := range pubkeys {
key := DeterministicEcdsaKeyByIndex(crypto.S256(), uint64(n))
pubkeys[n] = crypto.PubkeyToAddress(key.PublicKey)
}
v := &vaa.VAA{
Version: 1,
GuardianSetIndex: 0,
Timestamp: time.Unix(5000, 0),
EmitterChain: 3,
EmitterAddress: vaa.Address{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,
},
Payload: vaa.BodyGuardianSetUpdate{
Keys: pubkeys,
NewIndex: 1,
}.Serialize(),
}
// The devnet is initialized with a single guardian (ethereum/migrations/1_initial_migration.js).
key0 := DeterministicEcdsaKeyByIndex(crypto.S256(), 0)
v.AddSignature(key0, 0)
return v
}
// SubmitVAA submits a VAA to the devnet chain using well-known accounts and contract addresses.
func SubmitVAA(ctx context.Context, rpcURL string, vaa *vaa.VAA) (*types.Transaction, error) {
c, err := ethclient.DialContext(ctx, rpcURL)
if err != nil {
return nil, fmt.Errorf("dialing eth client failed: %w", err)
}
kt := GetKeyedTransactor(ctx)
bridge, err := abi.NewAbi(GanacheBridgeContractAddress, c)
if err != nil {
panic(err)
}
b, err := vaa.Marshal()
if err != nil {
panic(err)
}
supervisor.Logger(ctx).Info("submitted VAA to Ethereum devnet", zap.Binary("binary", b))
tx, err := bridge.SubmitNewGuardianSet(kt, b)
if err != nil {
return nil, err
}
return tx, nil
}
// GetKeyedTransactor returns a transaction signer with the deterministic devnet key.
func GetKeyedTransactor(ctx context.Context) *bind.TransactOpts {
key, err := Wallet().PrivateKey(DeriveAccount(0))
if err != nil {
panic(err)
}
kt := bind.NewKeyedTransactor(key)
kt.Context = ctx
return kt
}