Skip to content

fixing pending spent bug#742

Open
nikunjkumar05 wants to merge 7 commits intoblock-core:mainfrom
nikunjkumar05:dev
Open

fixing pending spent bug#742
nikunjkumar05 wants to merge 7 commits intoblock-core:mainfrom
nikunjkumar05:dev

Conversation

@nikunjkumar05
Copy link
Copy Markdown
Contributor

Fixes #738
adding a function ResetPendingSpentForTransaction to clear flag for rejected/failed tx

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes the “UTXOs stuck in PendingSpent” scenario by introducing a rollback mechanism when a transaction broadcast is rejected, helping ensure wallet state doesn’t permanently lock spendable outputs.

Changes:

  • Added ResetPendingSpentForTransaction to clear PendingSpent on UTXOs used as inputs to a given transaction.
  • Extended PublishTransactionAsync to optionally accept AccountInfo and rollback PendingSpent when the indexer rejects the transaction.
  • Refactored CopyPendingSpentUtxos to more efficiently carry forward PendingSpent flags and to explicitly drop them when the outpoint is no longer present.


public async Task<OperationResult<Transaction>> PublishTransactionAsync(Network network,Transaction signedTransaction)
public async Task<OperationResult<Transaction>> PublishTransactionAsync(
Network network,
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PublishTransactionAsync now has an extra AccountInfo? accountInfo = null parameter, but WalletOperations implements IWalletOperations, whose interface method still takes only (Network, Transaction). As-is, this will no longer satisfy the interface contract and will break callers compiled against the interface. Consider either updating IWalletOperations.PublishTransactionAsync to include the optional parameter (and updating all call sites), or adding an overload with the original 2-parameter signature that delegates to the new implementation.

Suggested change
Network network,
Network network,
Transaction signedTransaction)
{
return await PublishTransactionAsync(network, signedTransaction, null);
}
public async Task<OperationResult<Transaction>> PublishTransactionAsync(
Network network,

Copilot uses AI. Check for mistakes.
Comment on lines +387 to +394
if (accountInfo != null)
{
_logger.LogWarning(
"Transaction {TxId} rejected by indexer ({Reason}). Rolling back PendingSpent flags.",
signedTransaction.GetHash(), res);

ResetPendingSpentForTransaction(accountInfo, signedTransaction);
}
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rollback logic only runs when accountInfo is provided, but existing internal usage (e.g., SendAmountToAddress calling PublishTransactionAsync(network, signedTransaction)) will pass null and therefore never clears PendingSpent on rejection. If this path is expected to be covered by the fix, consider threading AccountInfo through the calling API (or ensuring the relevant caller passes it) so the rollback can actually occur.

Copilot uses AI. Check for mistakes.
Comment on lines +321 to +336
public void ResetPendingSpentForTransaction(AccountInfo accountInfo, Transaction transaction)
{
var inputOutpoints = transaction.Inputs
.Select(i => i.PrevOut.ToString())
.ToHashSet();

foreach (var utxo in accountInfo.AllUtxos())
{
if (inputOutpoints.Contains(utxo.outpoint.ToString()))
{
utxo.PendingSpent = false;
_logger.LogInformation(
"Released PendingSpent on {Outpoint} after transaction rollback.", utxo.outpoint);
}
}
}
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ResetPendingSpentForTransaction is currently public but is only used internally within WalletOperations. If this is meant to be called externally (e.g., from UI/state management), it should be added to IWalletOperations; otherwise consider reducing its visibility (e.g., private) to avoid expanding the public surface unintentionally.

Copilot uses AI. Check for mistakes.
Comment on lines +387 to +394
if (accountInfo != null)
{
_logger.LogWarning(
"Transaction {TxId} rejected by indexer ({Reason}). Rolling back PendingSpent flags.",
signedTransaction.GetHash(), res);

ResetPendingSpentForTransaction(accountInfo, signedTransaction);
}
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There’s no test coverage validating that a rejected publish triggers PendingSpent rollback (and that only the transaction’s input UTXOs are reset). Since Angor.Shared.Tests already has WalletOperationsTest, consider adding a unit test that mocks IIndexerService.PublishTransactionAsync to return an error string and asserts PendingSpent is cleared for the matching outpoints when accountInfo is supplied.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dangershony I didn't undetstand this particular review

@dangershony
Copy link
Copy Markdown
Member

some tests are failing

@nikunjkumar05
Copy link
Copy Markdown
Contributor Author

image image

Is this correct copilot give me this

@nikunjkumar05
Copy link
Copy Markdown
Contributor Author

I think it is ready for review

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Comment thread src/sdk/Angor.Sdk/Funding/Investor/Operations/PublishInvestment.cs
Comment on lines +567 to +569
liveUtxo.PendingSpent = true;
_logger.LogInformation(
"{Address} carrying PendingSpent forward for in-flight utxo {Outpoint}.",
Comment on lines 376 to +395
@@ -367,6 +385,15 @@ public async Task<OperationResult<Transaction>> PublishTransactionAsync(Network
if (string.IsNullOrEmpty(res))
return new OperationResult<Transaction> { Success = true, Data = signedTransaction };

if (accountInfo != null)
{
_logger.LogWarning(
"Transaction {TxId} rejected by indexer ({Reason}). Rolling back PendingSpent flags.",
signedTransaction.GetHash(), res);

ResetPendingSpentForTransaction(accountInfo, signedTransaction);
}
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@nikunjkumar05
Copy link
Copy Markdown
Contributor Author

@copilot apply changes based on the comments in this thread

@dangershony
Copy link
Copy Markdown
Member

this is not urgent so i will look in to this pr later

@nikunjkumar05
Copy link
Copy Markdown
Contributor Author

No worries I am just trying Copilot Ai for review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BUG in Walletoperations.cs

3 participants