Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 4 additions & 2 deletions solana/mvm.go
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,9 @@ func (node *Node) processConfirmNonce(ctx context.Context, req *store.Request) (
prepare.Public = hex.EncodeToString(user.FingerprintWithEmptyPath())
prepare.State = common.RequestStatePending

err = node.VerifySubSystemCallEnvelope(tx, node.getMTGAddress(ctx))
// A fee-only prepare transfers SOL from the payer, so it does not
// necessarily require the MTG authority to sign.
err = node.VerifySubSystemCallEnvelope(tx, node.getMTGAddress(ctx), false)
logger.Printf("node.VerifySubSystemCallEnvelope(%s) => %v", prepare.RequestId, err)
if err != nil {
return node.failRequest(ctx, req, "")
Expand Down Expand Up @@ -784,7 +786,7 @@ func (node *Node) processObserverCreateDepositCall(ctx context.Context, req *sto
logger.Printf("node.getSubSystemCallFromExtra(%v) => %v %v", req, call, err)
return node.failRequest(ctx, req, "")
}
err = node.VerifySubSystemCallEnvelope(tx, userAddress)
err = node.VerifySubSystemCallEnvelope(tx, userAddress, true)
logger.Printf("node.VerifySubSystemCallEnvelope(%s) => %v", call.RequestId, err)
if err != nil {
return node.failRequest(ctx, req, "")
Expand Down
10 changes: 8 additions & 2 deletions solana/solana.go
Original file line number Diff line number Diff line change
Expand Up @@ -932,14 +932,20 @@ func (node *Node) VerifySubSystemCall(ctx context.Context, tx *solana.Transactio
return nil
}

func (node *Node) VerifySubSystemCallEnvelope(tx *solana.Transaction, authority solana.PublicKey) error {
// VerifySubSystemCallEnvelope restricts signers to the payer and the expected
// authority. Some payer-funded prepare calls do not use the authority at all.
func (node *Node) VerifySubSystemCallEnvelope(tx *solana.Transaction, authority solana.PublicKey, authorityRequired bool) error {
payer := node.SolanaPayer()
if len(tx.Message.AccountKeys) == 0 || tx.Message.AccountKeys[0] != payer {
return fmt.Errorf("invalid subsystem fee payer")
}
expectedSigners := solana.PublicKeySlice{payer}
if authority != payer {
expectedSigners = append(expectedSigners, authority)
if tx.IsSigner(authority) {
expectedSigners = append(expectedSigners, authority)
} else if authorityRequired {
return fmt.Errorf("missing subsystem authority signer: %s", authority)
}
}
if !slices.Equal(tx.Message.Signers(), expectedSigners) {
return fmt.Errorf("invalid subsystem signers: %v", tx.Message.Signers())
Expand Down
2 changes: 1 addition & 1 deletion solana/system_call.go
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ func (node *Node) getPostProcessCall(ctx context.Context, req *store.Request, fl
if call.Type == store.CallTypePrepare {
authority = node.getMTGAddress(ctx)
}
err = node.VerifySubSystemCallEnvelope(tx, authority)
err = node.VerifySubSystemCallEnvelope(tx, authority, true)
logger.Printf("node.VerifySubSystemCallEnvelope(%s) => %v", post.RequestId, err)
if err != nil {
return nil, err
Expand Down
Loading