Skip to content

Commit 89fcf0f

Browse files
committed
bitwindow: handle transient sidechain deposit errors
1 parent 7bb68b9 commit 89fcf0f

1 file changed

Lines changed: 39 additions & 2 deletions

File tree

bitwindow/server/api/wallet/wallet.go

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,20 @@ type Server struct {
124124
walletDir string
125125
}
126126

127+
func isStaleWalletTransactionError(err error) bool {
128+
return err != nil && strings.Contains(err.Error(), "No such mempool or blockchain transaction")
129+
}
130+
131+
func isNonFinalTransactionError(err error) bool {
132+
return err != nil && strings.Contains(err.Error(), "non-final")
133+
}
134+
135+
func isInsufficientReplacementFeeError(err error) bool {
136+
return err != nil &&
137+
strings.Contains(err.Error(), "insufficient fee") &&
138+
strings.Contains(err.Error(), "rejecting replacement")
139+
}
140+
127141
// CreateBitcoinCoreWallet implements walletv1connect.WalletServiceHandler.
128142
// Test endpoint to verify descriptor import to Bitcoin Core.
129143
func (s *Server) CreateBitcoinCoreWallet(ctx context.Context, c *connect.Request[pb.CreateBitcoinCoreWalletRequest]) (*connect.Response[pb.CreateBitcoinCoreWalletResponse], error) {
@@ -802,6 +816,9 @@ func (s *Server) ListTransactions(ctx context.Context, c *connect.Request[pb.Lis
802816

803817
txs, err := wallet.ListTransactions(ctx, connect.NewRequest(&validatorpb.ListTransactionsRequest{}))
804818
if err != nil {
819+
if isStaleWalletTransactionError(err) {
820+
return connect.NewResponse(&pb.ListTransactionsResponse{}), nil
821+
}
805822
return nil, fmt.Errorf("enforcer/wallet: could not list transactions: %w", err)
806823
}
807824

@@ -1067,6 +1084,12 @@ func (s *Server) ListSidechainDeposits(ctx context.Context, c *connect.Request[p
10671084
if strings.Contains(err.Error(), "Missing value from db") {
10681085
return connect.NewResponse(&pb.ListSidechainDepositsResponse{}), nil
10691086
}
1087+
// The enforcer can remember a deposit txid after Bitcoin Core has dropped
1088+
// it from both the mempool and chain. Keep the sidechains UI usable while
1089+
// the wallet history is stale.
1090+
if isStaleWalletTransactionError(err) {
1091+
return connect.NewResponse(&pb.ListSidechainDepositsResponse{}), nil
1092+
}
10701093
return nil, fmt.Errorf("enforcer/wallet: could not list sidechain deposits: %w", err)
10711094
}
10721095

@@ -1142,6 +1165,12 @@ func (s *Server) CreateSidechainDeposit(ctx context.Context, c *connect.Request[
11421165
FeeSats: &wrapperspb.UInt64Value{Value: uint64(fee)},
11431166
}))
11441167
if err != nil {
1168+
if isNonFinalTransactionError(err) {
1169+
return nil, connect.NewError(connect.CodeFailedPrecondition, errors.New("deposit transaction is not final yet; wait for the next mainchain block, then check deposits or retry"))
1170+
}
1171+
if isInsufficientReplacementFeeError(err) {
1172+
return nil, connect.NewError(connect.CodeFailedPrecondition, errors.New("a deposit from this wallet is already waiting in the mainchain mempool; wait for the next mainchain block, then check deposits or retry"))
1173+
}
11451174
return nil, fmt.Errorf("enforcer/wallet: could not create deposit transaction: %w", err)
11461175
}
11471176

@@ -1843,7 +1872,11 @@ func (s *Server) GetStats(ctx context.Context, c *connect.Request[pb.GetStatsReq
18431872
// 2. Get all wallet transactions and count them
18441873
txs, err := wallet.ListTransactions(ctx, connect.NewRequest(&validatorpb.ListTransactionsRequest{}))
18451874
if err != nil {
1846-
return nil, err
1875+
if isStaleWalletTransactionError(err) {
1876+
txs = connect.NewResponse(&validatorpb.ListTransactionsResponse{})
1877+
} else {
1878+
return nil, err
1879+
}
18471880
}
18481881
transactionCount := int64(len(txs.Msg.Transactions))
18491882

@@ -1864,7 +1897,11 @@ func (s *Server) GetStats(ctx context.Context, c *connect.Request[pb.GetStatsReq
18641897
// 3. Get all sidechain deposit transactions and sum their amounts
18651898
sidechainDeposits, err := wallet.ListSidechainDepositTransactions(ctx, connect.NewRequest(&validatorpb.ListSidechainDepositTransactionsRequest{}))
18661899
if err != nil {
1867-
return nil, err
1900+
if isStaleWalletTransactionError(err) || strings.Contains(err.Error(), "Missing value from db") {
1901+
sidechainDeposits = connect.NewResponse(&validatorpb.ListSidechainDepositTransactionsResponse{})
1902+
} else {
1903+
return nil, err
1904+
}
18681905
}
18691906
var depositSum int64
18701907
var depositSumLast30Days int64

0 commit comments

Comments
 (0)