Skip to content
This repository has been archived by the owner on Aug 16, 2021. It is now read-only.

Commit

Permalink
Merge pull request #152 from dangershony/wallet-feature-p2pk
Browse files Browse the repository at this point in the history
Wallet feature p2pk
  • Loading branch information
bokobza authored Jun 6, 2017
2 parents cd6b19b + b75ac9d commit 500bcf2
Show file tree
Hide file tree
Showing 5 changed files with 187 additions and 134 deletions.
64 changes: 32 additions & 32 deletions Stratis.Bitcoin/Miner/PosMinting.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public class PosMinting
public PosMinting(ConsensusLoop consensusLoop, ConcurrentChain chain, Network network, ConnectionManager connection,
IDateTimeProvider dateTimeProvider, AssemblerFactory blockAssemblerFactory, BlockRepository blockRepository,
BlockStore.ChainBehavior.ChainState chainState, Signals signals, FullNode.CancellationProvider cancellationProvider,
NodeSettings settings, CoinView coinView, StakeChain stakeChain, WalletManager wallet)
NodeSettings settings, CoinView coinView, StakeChain stakeChain, IWalletManager wallet)
{
this.consensusLoop = consensusLoop;
this.chain = chain;
Expand All @@ -73,7 +73,7 @@ public PosMinting(ConsensusLoop consensusLoop, ConcurrentChain chain, Network ne
this.settings = settings;
this.coinView = coinView;
this.stakeChain = stakeChain;
this.wallet = wallet;
this.wallet = wallet as WalletManager;

this.minerSleep = 500; // GetArg("-minersleep", 500);
this.lastCoinStakeSearchTime = Utils.DateTimeToUnixTime(this.dateTimeProvider.GetTimeOffset()); // startup timestamp
Expand Down Expand Up @@ -127,14 +127,14 @@ public void GenerateBlocks(WalletSecret walletSecret)
{
this.LastCoinStakeSearchInterval = 0;

if (this.chain.Tip != this.consensusLoop.Tip)
return;

BlockTemplate pblocktemplate = null;
bool tryToSync = true;

while (true)
{
if (this.chain.Tip != this.consensusLoop.Tip)
return;

while (!this.connection.ConnectedNodes.Any() || chainState.IsInitialBlockDownload)
{
this.LastCoinStakeSearchInterval = 0;
Expand All @@ -148,7 +148,7 @@ public void GenerateBlocks(WalletSecret walletSecret)
if (this.connection.ConnectedNodes.Count() < 3 ||
this.chain.Tip.Header.Time < dateTimeProvider.GetTime() - 10*60)
{
this.cancellationProvider.Cancellation.Token.WaitHandle.WaitOne(TimeSpan.FromMilliseconds(60000));
//this.cancellationProvider.Cancellation.Token.WaitHandle.WaitOne(TimeSpan.FromMilliseconds(60000));
continue;
}
}
Expand All @@ -158,32 +158,33 @@ public void GenerateBlocks(WalletSecret walletSecret)


var pblock = pblocktemplate.Block;
var pindexPrev = this.chain.Tip;
var pindexPrev = this.consensusLoop.Tip;

var stakeTxes = new List<StakeTx>();
var spendable = this.wallet.GetSpendableTransactions();
var spendable = this.wallet.GetSpendableTransactions(1);

var coinset = this.coinView.FetchCoinsAsync(spendable.SelectMany(s => s.Transactions.Select(t => t.Id)).ToArray()).GetAwaiter().GetResult();
foreach (var sets in coinset.UnspentOutputs)

foreach (var unspentInfo in spendable)
{
int index = 0;
foreach (var outputx in sets._Outputs)
foreach (var infoTransaction in unspentInfo.Transactions)
{
if (outputx != null && outputx.Value > Money.Zero)
var set = coinset.UnspentOutputs.FirstOrDefault(f => f?.TransactionId == infoTransaction.Id);
var utxo = set?._Outputs[infoTransaction.Index.Value];

if (utxo != null && utxo.Value > Money.Zero)
{
var stakeTx = new StakeTx();

stakeTx.TxOut = outputx;
stakeTx.OutPoint = new OutPoint(sets.TransactionId, index);
stakeTx.Address = spendable.First(t => t.Address.Transactions.Any(a => a.Id == sets.TransactionId)).Address;
stakeTx.OutputIndex = index;
stakeTx.HashBlock = this.chain.GetBlock((int) sets.Height).HashBlock;
stakeTx.UtxoSet = sets;
stakeTx.TxOut = utxo;
stakeTx.OutPoint = new OutPoint(set.TransactionId, infoTransaction.Index.Value);
stakeTx.Address = unspentInfo.Address;
stakeTx.OutputIndex = infoTransaction.Index.Value;
stakeTx.HashBlock = this.chain.GetBlock((int)set.Height).HashBlock;
stakeTx.UtxoSet = set;
stakeTx.Secret = walletSecret; //temporary
stakeTxes.Add(stakeTx);
}

index++;
}
}

Expand Down Expand Up @@ -237,7 +238,9 @@ private void CheckState(ContextInformation context, ChainedBlock pindexPrev)
this.blockRepository.PutAsync(context.BlockResult.ChainedBlock.HashBlock, new List<Block> { block }).GetAwaiter().GetResult();
this.signals.Blocks.Broadcast(block);

Logs.Mining.LogInformation($"Found new POS block {context.BlockResult.ChainedBlock.HashBlock}");
Logs.Mining.LogInformation($"==================================================================");
Logs.Mining.LogInformation($"Found new POS block hash={context.BlockResult.ChainedBlock.HashBlock} height={context.BlockResult.ChainedBlock.Height}");
Logs.Mining.LogInformation($"==================================================================");

// wait for peers to get the block
Thread.Sleep(1000);
Expand Down Expand Up @@ -348,14 +351,6 @@ public bool CreateCoinStake(List<StakeTx> stakeTxes, ChainedBlock pindexBest, Bl
if (!SelectCoinsForStaking(stakeTxes, nBalance - this.reserveBalance, txNew.Time, out setCoins, out nValueIn))
return false;

//// check if coins are already staking
//// this is different from the c++ implementation
//// which pushes the new block to the main chain
//// and removes it when a longer chain is found
//foreach (var walletTx in setCoins.ToList())
// if (this.minerService.IsStaking(walletTx.TransactionHash, walletTx.OutputIndex))
// setCoins.Remove(walletTx);

if (!setCoins.Any())
return false;

Expand All @@ -371,8 +366,11 @@ public bool CreateCoinStake(List<StakeTx> stakeTxes, ChainedBlock pindexBest, Bl
int maxStakeSearchInterval = 60;
bool fKernelFound = false;

for (uint n = 0; n < Math.Min(nSearchInterval, maxStakeSearchInterval) && !fKernelFound && pindexPrev == this.chain.Tip; n++)
for (uint n = 0; n < Math.Min(nSearchInterval, maxStakeSearchInterval) && !fKernelFound; n++)
{
if (pindexPrev != this.chain.Tip)
return false;

try
{
var prevoutStake = new OutPoint(coin.UtxoSet.TransactionId, coin.OutputIndex);
Expand Down Expand Up @@ -427,8 +425,10 @@ public bool CreateCoinStake(List<StakeTx> stakeTxes, ChainedBlock pindexBest, Bl
}
catch (ConsensusErrorException cex)
{
if (cex.ConsensusError != ConsensusErrors.StakeHashInvalidTarget)
throw;
if (cex.ConsensusError == ConsensusErrors.StakeHashInvalidTarget)
continue;

throw;
}
}

Expand Down
9 changes: 7 additions & 2 deletions Stratis.Bitcoin/Wallet/Controllers/WalletController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,13 @@ public IActionResult GetHistory([FromQuery] WalletHistoryRequest request)
}
}

var changeAddress = addresses.Single(a => a.IsChangeAddress() && a.Transactions.Any(t => t.Id == transaction.Id));
item.Fee = transaction.Amount.Abs() - item.Amount - changeAddress.Transactions.First(t => t.Id == transaction.Id).Amount;
var changeAddress = addresses.SingleOrDefault(a => a.IsChangeAddress() && a.Transactions.Any(t => t.Id == transaction.Id));
item.Fee = transaction.Amount.Abs() - item.Amount - (changeAddress == null ? 0 : changeAddress.Transactions.First(t => t.Id == transaction.Id).Amount);

// generated coins add more coins to the total out
// that makes the fee negative if thats the case ignore the fee
if (item.Fee < 0)
item.Fee = 0;
}

item.Id = transaction.Id;
Expand Down
2 changes: 1 addition & 1 deletion Stratis.Bitcoin/Wallet/IWalletManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public interface IWalletManager : IDisposable
/// List all spendable transactions from all accounts
/// </summary>
/// <returns>A collection of spendable outputs</returns>
List<UnspentInfo> GetSpendableTransactions();
List<UnspentInfo> GetSpendableTransactions(int confirmations = 0);

/// <summary>
/// Creates a wallet and persist it as a file on the local system.
Expand Down
24 changes: 19 additions & 5 deletions Stratis.Bitcoin/Wallet/Wallet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ public IEnumerable<TransactionData> GetTransactionsById(uint256 id)
public IEnumerable<TransactionData> GetSpendableTransactions()
{
var addresses = this.ExternalAddresses.Concat(this.InternalAddresses);
return addresses.SelectMany(a => a.Transactions.Where(t => t.SpentInTransaction == null && t.Amount > Money.Zero));
return addresses.SelectMany(a => a.Transactions.Where(t => t.IsSpendable()));
}

/// <summary>
Expand Down Expand Up @@ -352,6 +352,13 @@ public class HdAddress
[JsonConverter(typeof(ScriptJsonConverter))]
public Script ScriptPubKey { get; set; }

/// <summary>
/// The script pub key for this address.
/// </summary>
[JsonProperty(PropertyName = "pubkey")]
[JsonConverter(typeof(ScriptJsonConverter))]
public Script Pubkey { get; set; }

/// <summary>
/// The Base58 representation of this address.
/// </summary>
Expand Down Expand Up @@ -454,10 +461,17 @@ public class TransactionData
[JsonProperty(PropertyName = "merkleProof", NullValueHandling = NullValueHandling.Ignore)]
public MerkleProof MerkleProof { get; set; }

/// <summary>
/// Determines whether this transaction is confirmed.
/// </summary>
public bool IsConfirmed()
/// <summary>
/// The script pub key for this address.
/// </summary>
[JsonProperty(PropertyName = "scriptPubKey")]
[JsonConverter(typeof(ScriptJsonConverter))]
public Script ScriptPubKey { get; set; }

/// <summary>
/// Determines whether this transaction is confirmed.
/// </summary>
public bool IsConfirmed()
{
return this.BlockHeight != null;
}
Expand Down
Loading

0 comments on commit 500bcf2

Please sign in to comment.