Skip to content

Commit

Permalink
Blockr + RPC Transaction repository implementation + optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
NicolasDorier committed Oct 4, 2014
1 parent 268814c commit 9a5e496
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 6 deletions.
7 changes: 7 additions & 0 deletions NBitcoin.Tests/ColoredCoinsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,13 @@ public ScriptId Id
}
}

//[Fact]
//public void TestFun()
//{
// var repo = new NoSqlColoredTransactionRepository(new BlockrTransactionRepository());
// var colored = ColoredTransaction.FetchColors(new uint256("b4399a545c4ddd640920d63af75e7367fe4d94b2d7f7a3423105e25ac5f165a6"), repo);

//}

[Fact]
[Trait("UnitTest", "UnitTest")]
Expand Down
69 changes: 69 additions & 0 deletions NBitcoin/BlockrTransactionRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace NBitcoin
{
[Serializable]
public class BlockrException : Exception
{
public BlockrException(JObject response)
: base(response["message"] == null ? "Error from Blockr" : response["message"].ToString())
{
Code = response["code"] == null ? 0 : response["code"].Value<int>();
Status = response["status"] == null ? null : response["status"].ToString();
}

public int Code
{
get;
set;
}
public string Status
{
get;
set;
}
}
public class BlockrTransactionRepository : ITransactionRepository
{
public BlockrTransactionRepository()
{

}



#region ITransactionRepository Members

public Transaction Get(uint256 txId)
{
while(true)
{
WebClient client = new WebClient();
var result = client.DownloadString("http://btc.blockr.io/api/v1/tx/raw/" + txId);
var json = JObject.Parse(result);
var status = json["status"];
var code = json["code"];
if(status != null && status.ToString() == "error")
{
throw new BlockrException(json);
}
var tx = new Transaction(json["data"]["tx"]["hex"].ToString());
return tx;
}
}

public void Put(uint256 txId, Transaction tx)
{
throw new NotSupportedException();
}

#endregion
}
}
2 changes: 2 additions & 0 deletions NBitcoin/NBitcoin.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
<Compile Include="NoSqlTransactionRepository.cs" />
<Compile Include="ObjectStream.cs" />
<Compile Include="OpenAsset\Asset.cs" />
<Compile Include="BlockrTransactionRepository.cs" />
<Compile Include="OpenAsset\CachedColoredTransactionRepository.cs" />
<Compile Include="OpenAsset\ColoredTransaction.cs" />
<Compile Include="OpenAsset\Extensions.cs" />
Expand All @@ -102,6 +103,7 @@
<Compile Include="Protocol\Payloads\MempoolPayload.cs" />
<Compile Include="Protocol\Payloads\RejectPayload.cs" />
<Compile Include="Protocol\PerformanceCounter.cs" />
<Compile Include="RPCTransactionRepository.cs" />
<Compile Include="RPC\BlockExplorerFormatter.cs" />
<Compile Include="RPC\RawFormatter.cs" />
<Compile Include="RPC\RPCClient.cs" />
Expand Down
18 changes: 15 additions & 3 deletions NBitcoin/OpenAsset/ColoredTransaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ public static ColoredTransaction FetchColors(Transaction tx, IColoredTransaction
}
public static ColoredTransaction FetchColors(uint256 txId, IColoredTransactionRepository repo)
{
if(repo == null)
throw new ArgumentNullException("repo");
repo = EnsureCachedRepository(repo);
var colored = repo.Get(txId);
if(colored != null)
return colored;
Expand All @@ -85,8 +88,9 @@ public static ColoredTransaction FetchColors(uint256 txId, Transaction tx, IColo
if(result != null)
return result;

ColoredTransaction lastColored = null;
//The following code is to prevent recursion of FetchColors that would fire a StackOverflow if the origin of traded asset were deep in the transaction dependency tree
repo = new CachedColoredTransactionRepository(repo);
repo = EnsureCachedRepository(repo);
HashSet<uint256> invalidColored = new HashSet<uint256>();
Stack<Tuple<uint256, Transaction>> ancestors = new Stack<Tuple<uint256, Transaction>>();
ancestors.Push(Tuple.Create(txId, tx));
Expand Down Expand Up @@ -117,12 +121,20 @@ public static ColoredTransaction FetchColors(uint256 txId, Transaction tx, IColo
}
if(isComplete)
{
FetchColorsWithAncestorsSolved(txId, tx, repo);
lastColored = FetchColorsWithAncestorsSolved(txId, tx, repo);
ancestors.Pop();
}
}

return FetchColorsWithAncestorsSolved(txId, tx, repo);
return lastColored;
}

private static IColoredTransactionRepository EnsureCachedRepository(IColoredTransactionRepository repo)
{
if(repo is CachedColoredTransactionRepository)
return repo;
repo = new CachedColoredTransactionRepository(repo);
return repo;
}

private static ColoredTransaction FetchColorsWithAncestorsSolved(uint256 txId, Transaction tx, IColoredTransactionRepository repo)
Expand Down
11 changes: 8 additions & 3 deletions NBitcoin/OpenAsset/NoSqlColoredTransactionRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,21 @@ namespace NBitcoin.OpenAsset
public class NoSqlColoredTransactionRepository : IColoredTransactionRepository
{
public NoSqlColoredTransactionRepository()
: this(new NoSqlTransactionRepository(), new InMemoryNoSqlRepository())
: this(null, null)
{

}
public NoSqlColoredTransactionRepository(ITransactionRepository transactionRepository)
: this(transactionRepository, null)
{

}
public NoSqlColoredTransactionRepository(ITransactionRepository transactionRepository, NoSqlRepository repository)
{
if(transactionRepository == null)
throw new ArgumentNullException("transactionRepository");
transactionRepository = new NoSqlTransactionRepository();
if(repository == null)
throw new ArgumentNullException("repository");
repository = new InMemoryNoSqlRepository();
_Transactions = transactionRepository;
_Repository = repository;
}
Expand Down
33 changes: 33 additions & 0 deletions NBitcoin/RPCTransactionRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using NBitcoin.RPC;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NBitcoin
{
public class RPCTransactionRepository : ITransactionRepository
{
RPCClient _Client;
public RPCTransactionRepository(RPCClient client)
{
if(client == null)
throw new ArgumentNullException("client");
_Client = client;
}
#region ITransactionRepository Members

public Transaction Get(uint256 txId)
{
return _Client.GetRawTransaction(txId, false);
}

public void Put(uint256 txId, Transaction tx)
{
throw new NotSupportedException();
}

#endregion
}
}

0 comments on commit 9a5e496

Please sign in to comment.