Skip to content

Commit 3cccaab

Browse files
committed
fix: revert voting
1 parent 61c3723 commit 3cccaab

File tree

4 files changed

+25
-16
lines changed

4 files changed

+25
-16
lines changed

universalClient/tss/txbroadcaster/broadcaster_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ func (m *mockTxBuilder) BroadcastOutboundSigningRequest(ctx context.Context, req
5050
return args.String(0), args.Error(1)
5151
}
5252

53-
func (m *mockTxBuilder) VerifyBroadcastedTx(ctx context.Context, txHash string) (bool, uint64, uint8, error) {
53+
func (m *mockTxBuilder) VerifyBroadcastedTx(ctx context.Context, txHash string) (bool, uint64, uint64, uint8, error) {
5454
args := m.Called(ctx, txHash)
55-
return args.Bool(0), args.Get(1).(uint64), args.Get(2).(uint8), args.Error(3)
55+
return args.Bool(0), args.Get(1).(uint64), args.Get(2).(uint64), args.Get(3).(uint8), args.Error(4)
5656
}
5757

5858
type mockChainClient struct{ builder *mockTxBuilder }

universalClient/tss/txresolver/evm.go

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,23 @@ import (
1414
// 2. If NOT FOUND for maxNotFoundRetries consecutive polls (~5 min): vote failure and REVERT.
1515
// This covers cases where the tx was dropped from the mempool (gas spike, nonce replaced).
1616
// 3. If FOUND but not enough confirmations yet: wait (retry next tick).
17-
// 4. If FOUND with enough confirmations and receipt status == 0 (reverted): vote failure and REVERT.
18-
// 5. If FOUND with enough confirmations and receipt status == 1 (success): mark COMPLETED, success vote will be done by destination chain event listening.
17+
// 4. If FOUND with enough confirmations and receipt status == 0 (reverted): vote failure and REVERT
18+
// with the receipt's block height and tx hash.
19+
// 5. If FOUND with enough confirmations and receipt status == 1 (success): mark COMPLETED,
20+
// success vote will be done by destination chain event listening.
1921
//
2022
// The failure vote triggers a refund of user funds on Push chain.
23+
//
24+
// Observation semantics for the user:
25+
// - txHash + blockHeight → tx landed on chain (success or revert)
26+
// - no txHash + no blockHeight → protocol issue (tx dropped, invalid hash, etc.)
2127
func (r *Resolver) resolveEVM(ctx context.Context, event *store.Event, chainID, rawTxHash string) {
2228
txID, utxID, err := extractOutboundIDs(event)
2329
if err != nil {
2430
r.logger.Warn().Err(err).Str("event_id", event.EventID).Msg("failed to extract outbound IDs")
2531
return
2632
}
27-
found, confirmations, status, err := r.verifyTxOnChain(ctx, chainID, rawTxHash)
33+
found, blockHeight, confirmations, status, err := r.verifyTxOnChain(ctx, chainID, rawTxHash)
2834
if err != nil {
2935
r.logger.Debug().Err(err).Str("event_id", event.EventID).Msg("tx verification error")
3036
return
@@ -38,7 +44,8 @@ func (r *Resolver) resolveEVM(ctx context.Context, event *store.Event, chainID,
3844

3945
if count >= maxNotFoundRetries {
4046
delete(r.notFoundCounts, event.EventID)
41-
_ = r.voteFailureAndMarkReverted(ctx, event, txID, utxID, rawTxHash, "tx not found on destination chain after max retries")
47+
// Protocol issue: tx dropped/not found — no txHash, no height
48+
_ = r.voteFailureAndMarkReverted(ctx, event, txID, utxID, "", 0, "tx not found on destination chain after max retries")
4249
}
4350
return
4451
}
@@ -53,7 +60,8 @@ func (r *Resolver) resolveEVM(ctx context.Context, event *store.Event, chainID,
5360

5461
// Enough confirmations: finalize based on status
5562
if status == 0 {
56-
_ = r.voteFailureAndMarkReverted(ctx, event, txID, utxID, rawTxHash, "tx execution reverted on destination chain")
63+
// Destination chain revert — attach receipt block height and tx hash
64+
_ = r.voteFailureAndMarkReverted(ctx, event, txID, utxID, rawTxHash, blockHeight, "tx execution reverted on destination chain")
5765
return
5866
}
5967

@@ -67,14 +75,14 @@ func (r *Resolver) resolveEVM(ctx context.Context, event *store.Event, chainID,
6775
Uint64("confirmations", confirmations).Msg("broadcasted EVM tx marked COMPLETED")
6876
}
6977

70-
func (r *Resolver) verifyTxOnChain(ctx context.Context, chainID, txHash string) (bool, uint64, uint8, error) {
78+
func (r *Resolver) verifyTxOnChain(ctx context.Context, chainID, txHash string) (bool, uint64, uint64, uint8, error) {
7179
client, err := r.chains.GetClient(chainID)
7280
if err != nil {
73-
return false, 0, 0, err
81+
return false, 0, 0, 0, err
7482
}
7583
builder, err := client.GetTxBuilder()
7684
if err != nil {
77-
return false, 0, 0, err
85+
return false, 0, 0, 0, err
7886
}
7987
return builder.VerifyBroadcastedTx(ctx, txHash)
8088
}

universalClient/tss/txresolver/resolver.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ func (r *Resolver) resolveEvent(ctx context.Context, event *store.Event) {
115115
r.logger.Warn().Err(extractErr).Str("event_id", event.EventID).Msg("invalid broadcasted tx hash and failed to extract outbound IDs")
116116
return
117117
}
118-
_ = r.voteFailureAndMarkReverted(ctx, event, txID, utxID, "", "invalid broadcasted tx hash format")
118+
_ = r.voteFailureAndMarkReverted(ctx, event, txID, utxID, "", 0, "invalid broadcasted tx hash format")
119119
return
120120
}
121121

@@ -128,15 +128,16 @@ func (r *Resolver) resolveEvent(ctx context.Context, event *store.Event) {
128128
r.resolveSVM(event, chainID)
129129
}
130130

131-
func (r *Resolver) voteFailureAndMarkReverted(ctx context.Context, event *store.Event, txID, utxID, txHash, errorMsg string) error {
131+
func (r *Resolver) voteFailureAndMarkReverted(ctx context.Context, event *store.Event, txID, utxID, txHash string, blockHeight uint64, errorMsg string) error {
132132
if r.pushSigner == nil {
133133
r.logger.Warn().Str("event_id", event.EventID).Msg("pushSigner not configured, cannot vote failure")
134134
return nil
135135
}
136136
observation := &uexecutortypes.OutboundObservation{
137-
Success: false,
138-
TxHash: txHash,
139-
ErrorMsg: errorMsg,
137+
Success: false,
138+
BlockHeight: blockHeight,
139+
TxHash: txHash,
140+
ErrorMsg: errorMsg,
140141
}
141142
voteTxHash, err := r.pushSigner.VoteOutbound(ctx, txID, utxID, observation)
142143
if err != nil {

universalClient/tss/txresolver/resolver_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ func TestVoteFailureAndMarkReverted(t *testing.T) {
251251
})
252252

253253
event := &store.Event{EventID: "ev-1"}
254-
err := resolver.voteFailureAndMarkReverted(context.Background(), event, "tx-1", "utx-1", "0xhash", "some error")
254+
err := resolver.voteFailureAndMarkReverted(context.Background(), event, "tx-1", "utx-1", "0xhash", 12345, "some error")
255255
assert.NoError(t, err)
256256
})
257257
}

0 commit comments

Comments
 (0)