node/cmd/guardiand: batched submission of governance messages

Change-Id: I1f8541a89fb1ef3b5bafaede43a8481634cd3451
This commit is contained in:
Leo 2021-10-29 17:50:46 +02:00 committed by Leopold Schabel
parent d5f6540656
commit 2396adc2c5
5 changed files with 110 additions and 76 deletions

View File

@ -109,7 +109,9 @@ func runInjectGovernanceVAA(cmd *cobra.Command, args []string) {
log.Fatalf("failed to submit governance VAA: %v", err)
}
log.Printf("VAA successfully injected with digest %s", hexutils.BytesToHex(resp.Digest))
for _, digest := range resp.Digests {
log.Printf("VAA successfully injected with digest %s", hexutils.BytesToHex(digest))
}
}
func runFindMissingMessages(cmd *cobra.Command, args []string) {

View File

@ -163,36 +163,43 @@ func (s *nodePrivilegedService) InjectGovernanceVAA(ctx context.Context, req *no
v *vaa.VAA
err error
)
switch payload := req.Payload.(type) {
case *nodev1.InjectGovernanceVAARequest_GuardianSet:
v, err = adminGuardianSetUpdateToVAA(payload.GuardianSet, req.CurrentSetIndex, req.Nonce, req.Sequence)
case *nodev1.InjectGovernanceVAARequest_ContractUpgrade:
v, err = adminContractUpgradeToVAA(payload.ContractUpgrade, req.CurrentSetIndex, req.Nonce, req.Sequence)
case *nodev1.InjectGovernanceVAARequest_BridgeRegisterChain:
v, err = tokenBridgeRegisterChain(payload.BridgeRegisterChain, req.CurrentSetIndex, req.Nonce, req.Sequence)
case *nodev1.InjectGovernanceVAARequest_BridgeContractUpgrade:
v, err = tokenBridgeUpgradeContract(payload.BridgeContractUpgrade, req.CurrentSetIndex, req.Nonce, req.Sequence)
default:
panic(fmt.Sprintf("unsupported VAA type: %T", payload))
}
if err != nil {
return nil, status.Error(codes.InvalidArgument, err.Error())
digests := make([][]byte, len(req.Messages))
for i, message := range req.Messages {
switch payload := message.Payload.(type) {
case *nodev1.GovernanceMessage_GuardianSet:
v, err = adminGuardianSetUpdateToVAA(payload.GuardianSet, req.CurrentSetIndex, message.Nonce, message.Sequence)
case *nodev1.GovernanceMessage_ContractUpgrade:
v, err = adminContractUpgradeToVAA(payload.ContractUpgrade, req.CurrentSetIndex, message.Nonce, message.Sequence)
case *nodev1.GovernanceMessage_BridgeRegisterChain:
v, err = tokenBridgeRegisterChain(payload.BridgeRegisterChain, req.CurrentSetIndex, message.Nonce, message.Sequence)
case *nodev1.GovernanceMessage_BridgeContractUpgrade:
v, err = tokenBridgeUpgradeContract(payload.BridgeContractUpgrade, req.CurrentSetIndex, message.Nonce, message.Sequence)
default:
panic(fmt.Sprintf("unsupported VAA type: %T", payload))
}
if err != nil {
return nil, status.Error(codes.InvalidArgument, err.Error())
}
// Generate digest of the unsigned VAA.
digest, err := v.SigningMsg()
if err != nil {
panic(err)
}
s.logger.Info("governance VAA constructed",
zap.Any("vaa", v),
zap.String("digest", digest.String()),
)
s.injectC <- v
digests[i] = digest.Bytes()
}
// Generate digest of the unsigned VAA.
digest, err := v.SigningMsg()
if err != nil {
panic(err)
}
s.logger.Info("governance VAA constructed",
zap.Any("vaa", v),
zap.String("digest", digest.String()),
)
s.injectC <- v
return &nodev1.InjectGovernanceVAAResponse{Digest: digest.Bytes()}, nil
return &nodev1.InjectGovernanceVAAResponse{Digests: digests}, nil
}
func (s *nodePrivilegedService) FindMissingMessages(ctx context.Context, req *nodev1.FindMissingMessagesRequest) (*nodev1.FindMissingMessagesResponse, error) {

View File

@ -93,10 +93,14 @@ func runGuardianSetTemplate(cmd *cobra.Command, args []string) {
m := &nodev1.InjectGovernanceVAARequest{
CurrentSetIndex: uint32(*templateGuardianIndex),
Sequence: rand.Uint64(),
Nonce: rand.Uint32(),
Payload: &nodev1.InjectGovernanceVAARequest_GuardianSet{
GuardianSet: &nodev1.GuardianSetUpdate{Guardians: guardians},
Messages: []*nodev1.GovernanceMessage{
{
Sequence: rand.Uint64(),
Nonce: rand.Uint32(),
Payload: &nodev1.GovernanceMessage_GuardianSet{
GuardianSet: &nodev1.GuardianSetUpdate{Guardians: guardians},
},
},
},
}
@ -119,12 +123,16 @@ func runContractUpgradeTemplate(cmd *cobra.Command, args []string) {
m := &nodev1.InjectGovernanceVAARequest{
CurrentSetIndex: uint32(*templateGuardianIndex),
Sequence: rand.Uint64(),
Nonce: rand.Uint32(),
Payload: &nodev1.InjectGovernanceVAARequest_ContractUpgrade{
ContractUpgrade: &nodev1.ContractUpgrade{
ChainId: uint32(chainID),
NewContract: address,
Messages: []*nodev1.GovernanceMessage{
{
Sequence: rand.Uint64(),
Nonce: rand.Uint32(),
Payload: &nodev1.GovernanceMessage_ContractUpgrade{
ContractUpgrade: &nodev1.ContractUpgrade{
ChainId: uint32(chainID),
NewContract: address,
},
},
},
},
}
@ -147,13 +155,17 @@ func runTokenBridgeRegisterChainTemplate(cmd *cobra.Command, args []string) {
m := &nodev1.InjectGovernanceVAARequest{
CurrentSetIndex: uint32(*templateGuardianIndex),
Sequence: rand.Uint64(),
Nonce: rand.Uint32(),
Payload: &nodev1.InjectGovernanceVAARequest_BridgeRegisterChain{
BridgeRegisterChain: &nodev1.BridgeRegisterChain{
Module: *module,
ChainId: uint32(chainID),
EmitterAddress: address,
Messages: []*nodev1.GovernanceMessage{
{
Sequence: rand.Uint64(),
Nonce: rand.Uint32(),
Payload: &nodev1.GovernanceMessage_BridgeRegisterChain{
BridgeRegisterChain: &nodev1.BridgeRegisterChain{
Module: *module,
ChainId: uint32(chainID),
EmitterAddress: address,
},
},
},
},
}
@ -177,13 +189,17 @@ func runTokenBridgeUpgradeContractTemplate(cmd *cobra.Command, args []string) {
m := &nodev1.InjectGovernanceVAARequest{
CurrentSetIndex: uint32(*templateGuardianIndex),
Sequence: rand.Uint64(),
Nonce: rand.Uint32(),
Payload: &nodev1.InjectGovernanceVAARequest_BridgeContractUpgrade{
BridgeContractUpgrade: &nodev1.BridgeUpgradeContract{
Module: *module,
TargetChainId: uint32(chainID),
NewContract: address,
Messages: []*nodev1.GovernanceMessage{
{
Sequence: rand.Uint64(),
Nonce: rand.Uint32(),
Payload: &nodev1.GovernanceMessage_BridgeContractUpgrade{
BridgeContractUpgrade: &nodev1.BridgeUpgradeContract{
Module: *module,
TargetChainId: uint32(chainID),
NewContract: address,
},
},
},
},
}

View File

@ -34,27 +34,31 @@ func runGovernanceVAAVerify(cmd *cobra.Command, args []string) {
log.Fatalf("failed to deserialize: %v", err)
}
var (
v *vaa.VAA
)
switch payload := msg.Payload.(type) {
case *nodev1.InjectGovernanceVAARequest_GuardianSet:
v, err = adminGuardianSetUpdateToVAA(payload.GuardianSet, msg.CurrentSetIndex, msg.Nonce, msg.Sequence)
case *nodev1.InjectGovernanceVAARequest_ContractUpgrade:
v, err = adminContractUpgradeToVAA(payload.ContractUpgrade, msg.CurrentSetIndex, msg.Nonce, msg.Sequence)
case *nodev1.InjectGovernanceVAARequest_BridgeRegisterChain:
v, err = tokenBridgeRegisterChain(payload.BridgeRegisterChain, msg.CurrentSetIndex, msg.Nonce, msg.Sequence)
default:
panic(fmt.Sprintf("unsupported VAA type: %T", payload))
}
if err != nil {
log.Fatalf("invalid update: %v", err)
}
for _, message := range msg.Messages {
var (
v *vaa.VAA
)
switch payload := message.Payload.(type) {
case *nodev1.GovernanceMessage_GuardianSet:
v, err = adminGuardianSetUpdateToVAA(payload.GuardianSet, msg.CurrentSetIndex, message.Nonce, message.Sequence)
case *nodev1.GovernanceMessage_ContractUpgrade:
v, err = adminContractUpgradeToVAA(payload.ContractUpgrade, msg.CurrentSetIndex, message.Nonce, message.Sequence)
case *nodev1.GovernanceMessage_BridgeRegisterChain:
v, err = tokenBridgeRegisterChain(payload.BridgeRegisterChain, msg.CurrentSetIndex, message.Nonce, message.Sequence)
case *nodev1.GovernanceMessage_BridgeContractUpgrade:
v, err = tokenBridgeUpgradeContract(payload.BridgeContractUpgrade, msg.CurrentSetIndex, message.Nonce, message.Sequence)
default:
panic(fmt.Sprintf("unsupported VAA type: %T", payload))
}
if err != nil {
log.Fatalf("invalid update: %v", err)
}
digest, err := v.SigningMsg()
if err != nil {
panic(err)
}
digest, err := v.SigningMsg()
if err != nil {
panic(err)
}
log.Printf("VAA with digest %s: %+v", digest.Hex(), spew.Sdump(v))
log.Printf("VAA with digest %s: %+v", digest.Hex(), spew.Sdump(v))
}
}

View File

@ -27,6 +27,11 @@ message InjectGovernanceVAARequest {
// Index of the current guardian set.
uint32 current_set_index = 1;
// List of governance VAA messages to inject.
repeated GovernanceMessage messages = 2;
}
message GovernanceMessage {
// Sequence number. This is critical for replay protection - make sure the sequence number
// is unique for every new manually injected governance VAA. Sequences are tracked
// by emitter, and manually injected VAAs all use a single hardcoded emitter.
@ -51,8 +56,8 @@ message InjectGovernanceVAARequest {
}
message InjectGovernanceVAAResponse {
// Canonical digest of the submitted VAA.
bytes digest = 1;
// Canonical digests of the submitted VAAs.
repeated bytes digests = 1;
}
// GuardianSet represents a new guardian set to be submitted to and signed by the node.