Skip to content

Commit

Permalink
separate the pending account structure from other pending outputs (li…
Browse files Browse the repository at this point in the history
…ke founder spend)
  • Loading branch information
dangershony committed Dec 13, 2023
1 parent 81af264 commit 3cde90e
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 79 deletions.
4 changes: 2 additions & 2 deletions src/Angor/Client/Pages/Index.razor
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

<h1>Welcome to Angor !</h1>

<h4>
<h5>
<br />
A decentralized crowdfunding platform built on the Bitcoin network.
<br /><br />
Think of it as a trustless, risk-minimized ICO.
</h4>
</h5>
17 changes: 12 additions & 5 deletions src/Angor/Client/Pages/Spend.razor
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@
{
List<QueryTransaction> trxs = new();
var unconfirmedInfo = _cacheStorage.GetUnconfirmedInfo();
bool modified = false;

foreach (StageData stageData in stageDatas)
{
Expand All @@ -280,19 +281,23 @@
{
item.IsSepnt = true;

_WalletOperations.RemoveInputsAndOutputsFromPending(unconfirmedInfo, item.Trxid);
_WalletOperations.RemoveInputsAndOutputsFromPending(unconfirmedInfo, output.SpentInTransaction);
_cacheStorage.SetUnconfirmedInfo(unconfirmedInfo);
unconfirmedInfo.RemoveInputsFromPending(item.Trxid);
modified = true;

continue;
}

if (unconfirmedInfo.PendingSpent.Any(a => a.ToString() == new Outpoint { transactionId = item.Trxid, outputIndex = item.Outputindex }.ToString()))
if (unconfirmedInfo.PendingSpent.Any(intput => intput.ToString() == new Outpoint { transactionId = item.Trxid, outputIndex = item.Outputindex }.ToString()))
{
item.IsSepnt = true;
}
}
}

if (modified)
{
_cacheStorage.SetUnconfirmedInfo(unconfirmedInfo);
}
}

private async Task ClaimCoins(int stageId)
Expand Down Expand Up @@ -377,8 +382,10 @@
return response;

// add all outptus to the pending list
var accountInfo = storage.GetAccountInfo(network.Name);
var unconfirmedInfo = _cacheStorage.GetUnconfirmedInfo();
_WalletOperations.AddInputsAndOutputsAsPending(unconfirmedInfo, signedTransaction);
_WalletOperations.UpdateAccountUnconfirmedInfoWithSpentTransaction(accountInfo, unconfirmedInfo, signedTransaction);
unconfirmedInfo.AddInputsAsPending(signedTransaction);
_cacheStorage.SetUnconfirmedInfo(unconfirmedInfo);

// mark stage as spent
Expand Down
2 changes: 1 addition & 1 deletion src/Angor/Client/Pages/Wallet.razor
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,7 @@

if (res.Success)
{
_walletOperations.UpdateAccountInfoWithSpentTransaction(accountInfo, unconfirmedInfo, res.Data);
_walletOperations.UpdateAccountUnconfirmedInfoWithSpentTransaction(accountInfo, unconfirmedInfo, res.Data);
accountBalanceInfo = AccountBalanceInfo.GetBalance(accountInfo, unconfirmedInfo);
storage.SetAccountInfo(network.Name, accountInfo);
_cacheStorage.SetUnconfirmedInfo(unconfirmedInfo);
Expand Down
5 changes: 1 addition & 4 deletions src/Angor/Shared/IWalletOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,5 @@ Transaction AddFeeAndSignTransaction(string changeAddress, Transaction transacti
WalletWords walletWords, AccountInfo accountInfo, UnconfirmedInfo unconfirmedInfo,
FeeEstimation feeRate);

void UpdateAccountInfoWithSpentTransaction(AccountInfo accountInfo, UnconfirmedInfo unconfirmedInfo, Transaction transaction);

void AddInputsAndOutputsAsPending(UnconfirmedInfo unconfirmedInfo, Blockcore.Consensus.TransactionInfo.Transaction transaction);
void RemoveInputsAndOutputsFromPending(UnconfirmedInfo unconfirmedInfo, string trxid);
void UpdateAccountUnconfirmedInfoWithSpentTransaction(AccountInfo accountInfo, UnconfirmedInfo unconfirmedInfo, Transaction transaction);
}
4 changes: 2 additions & 2 deletions src/Angor/Shared/Models/AccountBalanceInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ public class AccountBalanceInfo
public static AccountBalanceInfo GetBalance(AccountInfo account, UnconfirmedInfo unconfirmedInfo)
{
var balance = account.AddressesInfo.Concat(account.ChangeAddressesInfo).SelectMany(s => s.UtxoData).Sum(s => s.value);
var balanceSpent = unconfirmedInfo.PendingSpent.Sum(s => s.value);
var balanceSpent = unconfirmedInfo.AccountPendingSpent.Sum(s => s.value);

var balanceUnconfirmed = unconfirmedInfo.PendingReceive.Sum(s => s.value);
var balanceUnconfirmed = unconfirmedInfo.AccountPendingReceive.Sum(s => s.value);

return new AccountBalanceInfo
{
Expand Down
5 changes: 5 additions & 0 deletions src/Angor/Shared/Models/Outpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,9 @@ public OutPoint ToOutPoint()
{
return new OutPoint(uint256.Parse(transactionId), outputIndex);
}

public static Outpoint FromOutPoint(OutPoint outPoint)
{
return new Outpoint { outputIndex = (int)outPoint.N, transactionId = outPoint.Hash.ToString() };
}
}
32 changes: 30 additions & 2 deletions src/Angor/Shared/Models/UnconfirmedInfo.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,35 @@
using Blockcore.Networks;

namespace Angor.Shared.Models;

public class UnconfirmedInfo
{
public List<UtxoData> PendingReceive { get; set; } = new();
public List<UtxoData> PendingSpent { get; set; } = new();
public List<UtxoData> AccountPendingReceive { get; set; } = new();
public List<UtxoData> AccountPendingSpent { get; set; } = new();

public List<Outpoint> PendingSpent { get; set; } = new();

public void RemoveInputsFromPending(string trxid)
{
foreach (var input in PendingSpent.ToList())
{
if (input.transactionId == trxid)
{
PendingSpent.Remove(input);
}
}
}

public void AddInputsAsPending(Blockcore.Consensus.TransactionInfo.Transaction transaction)
{
var inputs = transaction.Inputs.Select(_ => _.PrevOut).ToList();

foreach (var outPoint in inputs)
{
if (PendingSpent.All(input => input.ToString() != outPoint.ToString()))
{
PendingSpent.Add(Outpoint.FromOutPoint(outPoint));
}
}
}
}
75 changes: 12 additions & 63 deletions src/Angor/Shared/WalletOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,10 @@ public async Task<OperationResult<Transaction>> SendAmountToAddress(WalletWords
return await PublishTransactionAsync(network, signedTransaction);
}

private void UpdatePendingLists(AccountInfo accountInfo, UnconfirmedInfo unconfirmedInfo)
private void UpdateAccountPendingLists(AccountInfo accountInfo, UnconfirmedInfo unconfirmedInfo)
{
// remove from the pending remove list if it was removed from the indexer
var pendingRemove = unconfirmedInfo.PendingSpent.ToList();
var pendingRemove = unconfirmedInfo.AccountPendingSpent.ToList();
foreach (var utxoData in pendingRemove)
{
foreach (var addressInfo in accountInfo.AddressesInfo.Concat(accountInfo.ChangeAddressesInfo))
Expand All @@ -143,14 +143,14 @@ private void UpdatePendingLists(AccountInfo accountInfo, UnconfirmedInfo unconfi
{
if (addressInfo.UtxoData.All(_ => _.outpoint.ToString() != utxoData.outpoint.ToString()))
{
unconfirmedInfo.PendingSpent.Remove(utxoData);
unconfirmedInfo.AccountPendingSpent.Remove(utxoData);
}
}
}
}

// remove from the pending add if it was removed from the indexer
var pendingAdd = unconfirmedInfo.PendingReceive.ToList();
var pendingAdd = unconfirmedInfo.AccountPendingReceive.ToList();
foreach (var utxoData in pendingAdd)
{
foreach (var addressInfo in accountInfo.AddressesInfo.Concat(accountInfo.ChangeAddressesInfo))
Expand All @@ -159,65 +159,14 @@ private void UpdatePendingLists(AccountInfo accountInfo, UnconfirmedInfo unconfi
{
if (addressInfo.UtxoData.Any(_ => _.outpoint.ToString() == utxoData.outpoint.ToString()))
{
unconfirmedInfo.PendingReceive.Remove(utxoData);
unconfirmedInfo.AccountPendingReceive.Remove(utxoData);
}
}
}
}
}

public void RemoveInputsAndOutputsFromPending(UnconfirmedInfo unconfirmedInfo, string trxid)
{
foreach (var utxoData in unconfirmedInfo.PendingSpent.ToList())
{
if (utxoData.outpoint.transactionId == trxid)
{
unconfirmedInfo.PendingSpent.Remove(utxoData);
}
}

foreach (var utxoData in unconfirmedInfo.PendingReceive.ToList())
{
if (utxoData.outpoint.transactionId == trxid)
{
unconfirmedInfo.PendingReceive.Remove(utxoData);
}
}
}

public void AddInputsAndOutputsAsPending(UnconfirmedInfo unconfirmedInfo, Blockcore.Consensus.TransactionInfo.Transaction transaction)
{
var inputs = transaction.Inputs.Select(_ => _.PrevOut).ToList();
var outputs = transaction.Outputs.AsIndexedOutputs();

foreach (var outPoint in inputs)
{
if (unconfirmedInfo.PendingSpent.All(_ => _.outpoint.ToString() != outPoint.ToString()))
{
unconfirmedInfo.PendingSpent.Add(new UtxoData
{
outpoint = new Outpoint { outputIndex = (int)outPoint.N, transactionId = outPoint.Hash.ToString() },
});
}
}

foreach (var output in outputs)
{
var outpoint = new Outpoint { outputIndex = (int)output.N, transactionId = transaction.GetHash().ToString() };

if (unconfirmedInfo.PendingReceive.All(_ => _.outpoint != outpoint))
{
unconfirmedInfo.PendingReceive.Add(new UtxoData
{
scriptHex = output.TxOut.ScriptPubKey.ToHex(),
outpoint = outpoint,
value = output.TxOut.Value
});
}
}
}

public void UpdateAccountInfoWithSpentTransaction(AccountInfo accountInfo, UnconfirmedInfo unconfirmedInfo, Blockcore.Consensus.TransactionInfo.Transaction transaction)
public void UpdateAccountUnconfirmedInfoWithSpentTransaction(AccountInfo accountInfo, UnconfirmedInfo unconfirmedInfo, Transaction transaction)
{
Network network = _networkConfiguration.GetNetwork();

Expand All @@ -233,9 +182,9 @@ public void UpdateAccountInfoWithSpentTransaction(AccountInfo accountInfo, Uncon
{
if (utxoData.outpoint.ToString() == outPoint.ToString())
{
if (unconfirmedInfo.PendingSpent.All(_ => _.outpoint.ToString() != utxoData.outpoint.ToString()))
if (unconfirmedInfo.AccountPendingSpent.All(_ => _.outpoint.ToString() != utxoData.outpoint.ToString()))
{
unconfirmedInfo.PendingSpent.Add(utxoData);
unconfirmedInfo.AccountPendingSpent.Add(utxoData);
}
}
}
Expand All @@ -248,9 +197,9 @@ public void UpdateAccountInfoWithSpentTransaction(AccountInfo accountInfo, Uncon
{
var outpoint = new Outpoint { outputIndex = (int)output.N, transactionId = transaction.GetHash().ToString() };

if (unconfirmedInfo.PendingReceive.All(_ => _.outpoint != outpoint))
if (unconfirmedInfo.AccountPendingReceive.All(_ => _.outpoint != outpoint))
{
unconfirmedInfo.PendingReceive.Add(new UtxoData
unconfirmedInfo.AccountPendingReceive.Add(new UtxoData
{
address = addressInfo.Address,
scriptHex = output.TxOut.ScriptPubKey.ToHex(),
Expand Down Expand Up @@ -288,7 +237,7 @@ public List<UtxoDataWithPath> FindOutputsForTransaction(long sendAmountat, Accou
.OrderBy(o => o.utxo.blockIndex)
.ThenByDescending(o => o.utxo.value))
{
if (unconfirmedInfo.PendingSpent.Any(p => p.outpoint.ToString() == utxoData.utxo.outpoint.ToString()))
if (unconfirmedInfo.AccountPendingSpent.Any(p => p.outpoint.ToString() == utxoData.utxo.outpoint.ToString()))
{
continue;
}
Expand Down Expand Up @@ -442,7 +391,7 @@ public async Task UpdateAccountInfoWithNewAddressesAsync(AccountInfo accountInfo
accountInfo.ChangeAddressesInfo.Add(changeAddressInfo);
}

UpdatePendingLists(accountInfo, unconfirmedInfo);
UpdateAccountPendingLists(accountInfo, unconfirmedInfo);
}

private async Task<(int,List<AddressInfo>)> FetchAddressesDataForPubKeyAsync(int scanIndex, string ExtendedPubKey, Network network, bool isChange)
Expand Down

0 comments on commit 3cde90e

Please sign in to comment.