Skip to content

Commit 36856e4

Browse files
author
corey
committed
fix
1 parent e362de2 commit 36856e4

File tree

3 files changed

+38
-8
lines changed

3 files changed

+38
-8
lines changed

token-price-oracle/client/l2_client.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,18 @@ func NewL2Client(rpcURL string, cfg *config.Config) (*L2Client, error) {
7070
fromAddr := common.HexToAddress(cfg.ExternalSignAddress)
7171
ethSigner := types.NewLondonSigner(chainID)
7272

73-
// Create opts with a placeholder signer for building transactions
74-
// The actual signing will be done by external signer
73+
// Create opts with a placeholder signer for building transactions.
74+
// This allows contract bindings to construct transaction objects so we can
75+
// extract the calldata and target address. The placeholder signature is never
76+
// actually broadcast - the real signing happens via external signer.
77+
// SAFETY: NoSend is always true, and tx_manager.go only extracts To() and Data()
78+
// from the placeholder tx, then creates a new properly signed transaction.
7579
l2Client.opts = &bind.TransactOpts{
7680
From: fromAddr,
77-
NoSend: true, // We'll handle sending manually
81+
NoSend: true, // CRITICAL: Must always be true for external signing mode
7882
Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) {
79-
// This is a placeholder signer - we don't actually sign here
80-
// The transaction will be signed by external signer later
81-
// We need to return the transaction with correct signer hash for gas estimation
83+
// Placeholder signer - returns tx with dummy signature to satisfy bind package.
84+
// This tx is NEVER sent; only used to extract calldata for external signing.
8285
return tx.WithSignature(ethSigner, make([]byte, 65))
8386
},
8487
}

token-price-oracle/config/config.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,8 +229,8 @@ func LoadConfig(ctx *cli.Context) (*Config, error) {
229229
if cfg.ExternalSignAddress == "" || cfg.ExternalSignUrl == "" ||
230230
cfg.ExternalSignAppid == "" || cfg.ExternalSignChain == "" ||
231231
cfg.ExternalSignRsaPriv == "" {
232-
return nil, fmt.Errorf("external sign is enabled but missing required config: address=%s, url=%s, appid=%s, chain=%s",
233-
cfg.ExternalSignAddress, cfg.ExternalSignUrl, cfg.ExternalSignAppid, cfg.ExternalSignChain)
232+
return nil, fmt.Errorf("external sign is enabled but missing required config: address=%s, url=%s, appid=%s, chain=%s, rsa_priv_set=%t",
233+
cfg.ExternalSignAddress, cfg.ExternalSignUrl, cfg.ExternalSignAppid, cfg.ExternalSignChain, cfg.ExternalSignRsaPriv != "")
234234
}
235235

236236
// Validate address format

token-price-oracle/updater/tx_manager.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,33 @@ func (m *TxManager) sendWithExternalSign(ctx context.Context, txFunc func(*bind.
116116
return nil, fmt.Errorf("external signer is not initialized")
117117
}
118118

119+
fromAddr := m.l2Client.WalletAddress()
120+
121+
// Check if there are pending transactions by comparing nonces
122+
confirmedNonce, err := m.l2Client.GetClient().NonceAt(ctx, fromAddr, nil)
123+
if err != nil {
124+
return nil, fmt.Errorf("failed to get confirmed nonce: %w", err)
125+
}
126+
127+
pendingNonce, err := m.l2Client.GetClient().PendingNonceAt(ctx, fromAddr)
128+
if err != nil {
129+
return nil, fmt.Errorf("failed to get pending nonce: %w", err)
130+
}
131+
132+
if pendingNonce > confirmedNonce {
133+
// There are pending transactions, don't send new one
134+
log.Warn("Found pending transactions, skipping this round",
135+
"address", fromAddr.Hex(),
136+
"confirmed_nonce", confirmedNonce,
137+
"pending_nonce", pendingNonce,
138+
"pending_count", pendingNonce-confirmedNonce)
139+
return nil, fmt.Errorf("pending transactions exist (confirmed: %d, pending: %d)", confirmedNonce, pendingNonce)
140+
}
141+
142+
log.Info("No pending transactions, proceeding to send",
143+
"address", fromAddr.Hex(),
144+
"nonce", confirmedNonce)
145+
119146
// Get transaction options (returns a copy) with NoSend=true to get calldata
120147
auth := m.l2Client.GetOpts()
121148
auth.Context = ctx

0 commit comments

Comments
 (0)