Skip to content

Commit b7f3215

Browse files
author
vboxuser
committed
client/eth: Warn instead of fail on audit coinID/txHash mismatch.
Some RPC providers return unsigned transaction data, causing the deserialized tx hash to differ from the on-chain tx hash (coinID). The contract state is validated against the locator from the contract data, not the tx hash, so the mismatch is not a security concern.
1 parent 0facb08 commit b7f3215

4 files changed

Lines changed: 13 additions & 10 deletions

File tree

client/asset/eth/eth.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5865,20 +5865,25 @@ func (eth *baseWallet) SignCoinMessage(_ asset.Coin, msg dex.Bytes) (pubkeys, si
58655865

58665866
// AuditContract retrieves information about a swap contract on the
58675867
// blockchain. This would be used to verify the counter-party's contract
5868-
// during a swap. coinID is expected to be the transaction id, and must
5869-
// be the same as the hash of serializedTx. contract is expected to be
5870-
// (contractVersion|secretHash) where the secretHash uniquely keys the swap.
5868+
// during a swap. coinID is expected to be the transaction id. contract
5869+
// is expected to be (contractVersion|secretHash) where the secretHash
5870+
// uniquely keys the swap.
58715871
func (w *assetWallet) AuditContract(coinID, contract, serializedTx dex.Bytes, rebroadcast bool) (*asset.AuditInfo, error) {
5872-
w.log.Debugf("AuditContract: coinID len=%d hex=%x", len(coinID), []byte(coinID))
58735872
tx := new(types.Transaction)
58745873
err := tx.UnmarshalBinary(serializedTx)
58755874
if err != nil {
58765875
return nil, fmt.Errorf("AuditContract: failed to unmarshal transaction: %w", err)
58775876
}
58785877

5878+
// The deserialized tx hash may not match coinID if the RPC provider
5879+
// returned the transaction without signature data. This is acceptable
5880+
// because the contract state is validated against the locator from the
5881+
// contract data, not the tx hash. Use the coinID as the canonical hash.
58795882
txHash := tx.Hash()
58805883
if !bytes.Equal(coinID, txHash[:]) {
5881-
return nil, fmt.Errorf("AuditContract: coin id != txHash - coin id: %x, txHash: %s", coinID, tx.Hash())
5884+
w.log.Warnf("AuditContract: coinID %x differs from deserialized txHash %s (unsigned tx from RPC?). Proceeding with contract validation.",
5885+
[]byte(coinID), txHash)
5886+
copy(txHash[:], coinID)
58825887
}
58835888

58845889
version, locator, err := dexeth.DecodeContractData(contract)

client/asset/eth/eth_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4725,8 +4725,9 @@ func testAuditContract(t *testing.T, assetID uint32) {
47254725
Value: dexeth.GweiToWei(1),
47264726
},
47274727
},
4728-
differentHash: true,
4729-
wantErr: true,
4728+
differentHash: true,
4729+
wantRecipient: testAddressA.Hex(),
4730+
wantExpiration: now,
47304731
},
47314732
{
47324733
name: "contract is invalid versioned bytes",

client/core/core.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10288,12 +10288,10 @@ func (c *Core) schedTradeTick(tracker *trackedTrade) {
1028810288
// when a match counter-party reports their initiation transaction.
1028910289
func handleAuditRoute(c *Core, dc *dexConnection, msg *msgjson.Message) error {
1029010290
audit := new(msgjson.Audit)
10291-
c.log.Debugf("handleAuditRoute: raw payload: %s", string(msg.Payload))
1029210291
err := msg.Unmarshal(audit)
1029310292
if err != nil {
1029410293
return fmt.Errorf("audit request parsing error: %w", err)
1029510294
}
10296-
c.log.Debugf("handleAuditRoute: CoinID len=%d hex=%x", len(audit.CoinID), audit.CoinID)
1029710295
var oid order.OrderID
1029810296
copy(oid[:], audit.OrderID)
1029910297

client/core/trade.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3932,7 +3932,6 @@ func (t *trackedTrade) searchAuditInfo(match *matchTracker, coinID []byte, contr
39323932
Expiration: time.Now().Add(24 * time.Hour), // effectively forever
39333933
TryFunc: func() wait.TryDirective {
39343934
var err error
3935-
t.dc.log.Debugf("searchAuditInfo: calling AuditContract with coinID len=%d hex=%x", len(coinID), []byte(coinID))
39363935
auditInfo, err = toWallet.AuditContract(coinID, contract, txData, true)
39373936
if err == nil {
39383937
// Success.

0 commit comments

Comments
 (0)