public override TransactionOutput GetUnspent(UInt256 hash, ushort index) { TR.Enter(); ReadOptions options = new ReadOptions(); using (options.Snapshot = db.GetSnapshot()) { UnspentCoinState state = db.TryGet <UnspentCoinState>(options, DataEntryPrefix.ST_Coin, hash); if (state == null) { TR.Exit(); return(null); } if (index >= state.Items.Length) { TR.Exit(); return(null); } if (state.Items[index].HasFlag(CoinState.Spent)) { TR.Exit(); return(null); } int height; return(TR.Exit(GetTransaction(options, hash, out height).Outputs[index])); } }
public override bool IsDoubleSpend(Transaction tx) { if (tx.Inputs.Length == 0) { return(false); } ReadOptions options = new ReadOptions(); using (options.Snapshot = db.GetSnapshot()) { foreach (var group in tx.Inputs.GroupBy(p => p.PrevHash)) { UnspentCoinState state = db.TryGet <UnspentCoinState>(options, DataEntryPrefix.ST_Coin, group.Key); if (state == null) { return(true); } if (group.Any(p => p.PrevIndex >= state.Items.Length || state.Items[p.PrevIndex].HasFlag(CoinState.Spent))) { return(true); } } } return(false); }
private void CheckDoubleSpend(IPersistence persistence, Transaction tx) { if (tx.Inputs.Length == 0) { return; } foreach (var group in tx.Inputs.GroupBy(p => p.PrevHash)) { UnspentCoinState state = persistence.UnspentCoins.TryGet(group.Key); if (state == null) { throw new RpcException(-500, $"Unspent coin state for ${group.Key} is null"); } if (group.Any(p => p.PrevIndex >= state.Items.Length || state.Items[p.PrevIndex].HasFlag(CoinState.Spent))) { int idx = 0; foreach (var p in state.Items) { if (p.HasFlag(CoinState.Spent)) { throw new RpcException(-500, $"Input {group.Key.ToString()}:{idx} is marked as spent"); } idx += 1; } throw new RpcException(-500, "At least one input is marked as spent"); } } }
public override bool ContainsUnspent(UInt256 hash, ushort index) { UnspentCoinState state = db.TryGet <UnspentCoinState>(ReadOptions.Default, DataEntryPrefix.ST_Coin, hash); if (state == null) { return(false); } if (index >= state.Items.Length) { return(false); } return(!state.Items[index].HasFlag(CoinState.Spent)); }
public static IEnumerable <TransactionOutput> GetUnspent(this IPersistence persistence, UInt256 hash) { List <TransactionOutput> outputs = new List <TransactionOutput>(); UnspentCoinState state = persistence.UnspentCoins.TryGet(hash); if (state != null) { Transaction tx = persistence.GetTransaction(hash); for (int i = 0; i < state.Items.Length; i++) { if (!state.Items[i].HasFlag(CoinState.Spent)) { outputs.Add(tx.Outputs[i]); } } } return(outputs); }
public static TransactionOutput GetUnspent(this IPersistence persistence, UInt256 hash, ushort index) { UnspentCoinState state = persistence.UnspentCoins.TryGet(hash); if (state == null) { return(null); } if (index >= state.Items.Length) { return(null); } if (state.Items[index].HasFlag(CoinState.Spent)) { return(null); } return(persistence.GetTransaction(hash).Outputs[index]); }
public static bool IsDoubleSpend(this IPersistence persistence, Transaction tx) { if (tx.Inputs.Length == 0) { return(false); } foreach (var group in tx.Inputs.GroupBy(p => p.PrevHash)) { UnspentCoinState state = persistence.UnspentCoins.TryGet(group.Key); if (state == null) { return(true); } if (group.Any(p => p.PrevIndex >= state.Items.Length || state.Items[p.PrevIndex].HasFlag(CoinState.Spent))) { return(true); } } return(false); }
// <summary> /// /// </summary> /// <param name="persistence"></param> /// <param name="tx"></param> /// <returns></returns> public static string IsDoubleSpend(Snapshot snapshot, Transaction tx) { if (tx.Inputs.Length == 0) { return("Input is empty."); } foreach (var group in tx.Inputs.GroupBy(p => p.PrevHash)) { UnspentCoinState state = snapshot.UnspentCoins.TryGet(group.Key); if (state == null) { return("utxo is not exists."); } if (group.Any(p => p.PrevIndex >= state.Items.Length || state.Items[p.PrevIndex].HasFlag(CoinState.Spent))) { return("utox was spent."); } } return("success"); }
public override bool IsDoubleSpend(Core.Transaction tx) { if (tx.Inputs.Length == 0) { return(false); } ReadOptions options = new ReadOptions(); using (options.Snapshot = db.GetSnapshot()) { foreach (var group in tx.Inputs.GroupBy(p => p.PrevHash)) { UnspentCoinState state = db.TryGet <UnspentCoinState>(options, DataEntryPrefix.ST_Coin, group.Key); if (state == null) { bool is_DoubleSpent = true; if (Wallets.EntityFramework.UserWallet.Default != null) { foreach (Quras.Wallets.Coin coin in Wallets.EntityFramework.UserWallet.Default.GetCoins()) { if (group.Key == coin.Reference.PrevHash /* && !coin.State.HasFlag(CoinState.Spent)*/) { is_DoubleSpent = false; break; } } } return(is_DoubleSpent); } if (group.Any(p => p.PrevIndex >= state.Items.Length || state.Items[p.PrevIndex].HasFlag(CoinState.Spent))) { return(true); } } } return(false); }
public override IEnumerable <TransactionOutput> GetUnspent(UInt256 hash) { ReadOptions options = new ReadOptions(); using (options.Snapshot = db.GetSnapshot()) { List <TransactionOutput> outputs = new List <TransactionOutput>(); UnspentCoinState state = db.TryGet <UnspentCoinState>(options, DataEntryPrefix.ST_Coin, hash); if (state != null) { int height; Transaction tx = GetTransaction(options, hash, out height); for (int i = 0; i < state.Items.Length; i++) { if (!state.Items[i].HasFlag(CoinState.Spent)) { outputs.Add(tx.Outputs[i]); } } } return(outputs); } }
public void TestSetup() { uut = new UnspentCoinState(); }