From 07a92233a4cc48a1f30066478a65bec2361e733d Mon Sep 17 00:00:00 2001 From: hundredark Date: Fri, 28 Aug 2026 17:44:23 +0800 Subject: [PATCH] fix check of preprare call --- solana/mvm.go | 6 ++++-- solana/solana.go | 10 ++++++++-- solana/system_call.go | 2 +- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/solana/mvm.go b/solana/mvm.go index 3482888..d6e72df 100644 --- a/solana/mvm.go +++ b/solana/mvm.go @@ -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, "") @@ -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, "") diff --git a/solana/solana.go b/solana/solana.go index 1b1df7c..9d15d09 100644 --- a/solana/solana.go +++ b/solana/solana.go @@ -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()) diff --git a/solana/system_call.go b/solana/system_call.go index acfc9fa..07a57c0 100644 --- a/solana/system_call.go +++ b/solana/system_call.go @@ -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