Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
d4e820b
Add Miniscript folder as separate dll
joemphilips Mar 26, 2019
f254c5b
Move Miniscript to independent Directory
joemphilips Mar 26, 2019
0a641be
Stop using the work FNBitcoin
joemphilips Mar 26, 2019
788d459
Fromat: Fix some casing
joemphilips Mar 26, 2019
a53651e
fixup! Move Miniscript to independent Directory
joemphilips Mar 27, 2019
3d2abb3
pack Miniscript without editing .nuspec manually
joemphilips Apr 3, 2019
c76955f
pack Miniscript without editing .nuspec manually.
joemphilips Apr 3, 2019
47e3a46
Start Writing Tests for Miniscript
joemphilips Apr 3, 2019
3c3227e
Update csproj a bit
joemphilips Apr 3, 2019
d43bf48
Include Miniscript to solution
joemphilips Apr 3, 2019
50f9de3
Fix compile error in Miniscript.Tests
joemphilips Apr 3, 2019
2d6a63d
Fix every compile warning when testing Miniscript
joemphilips Apr 4, 2019
d6b8c42
Fix bug in all Miniscript Test
joemphilips Apr 4, 2019
0684c0f
Refactor Miniscript
joemphilips Apr 4, 2019
1a2677d
Rename MiniScript -> Miniscript
joemphilips Apr 4, 2019
7ea97ca
Small refactor
joemphilips Apr 4, 2019
930d210
separate FSharp test and CSharp test for Miniscript
joemphilips Apr 4, 2019
1483d98
Rebame Miniscript.dll -> NBitcoin.Miniscript.dll
joemphilips Apr 5, 2019
80217a5
Restrict public-facing api in Miniscript as strict as possible
joemphilips Apr 6, 2019
1d6803b
Enable to pass `Func` to `Satisfy`
joemphilips Apr 6, 2019
cb21a50
Fix bug when satisfying LockTime
joemphilips Apr 6, 2019
55b2e3d
Update MiniscriptPSBTTests.cs
joemphilips Apr 8, 2019
2da2ff3
Remove all unnecessary files from Miniscript
joemphilips Apr 8, 2019
c871a27
Fix bug in E.Or
joemphilips Apr 8, 2019
d645d9d
Update Miniscript.PSBTExtensions
joemphilips Apr 9, 2019
39e3534
Fix bug in Satisfy
joemphilips Apr 10, 2019
88c8ee5
Delete PSBT.Finalize() and reimplement it as Extension
joemphilips Apr 10, 2019
872fc09
Fix all bug in finalization
joemphilips Apr 10, 2019
7e036ac
Tweak *.[c|f]sproj files
joemphilips Apr 11, 2019
67588fd
Delete useless file in Miniscript.Tests.CSharp
joemphilips Apr 11, 2019
4f9a80f
Add description about netfx.props
joemphilips Apr 11, 2019
ff38b8d
Remove meaningless testcase in SatifyTests.fs
joemphilips Apr 11, 2019
c706db8
Run Miniscript test in appveyor
joemphilips Apr 11, 2019
e443fec
Speed up property test
joemphilips Apr 11, 2019
6facd74
Run Miniscript tests in travis
joemphilips Apr 11, 2019
32ef31f
Specify FSharp.Core as dep in FSharp test and bump Fsharp.Core versio…
joemphilips Apr 11, 2019
43b19b0
Specify framework version in appveyor
joemphilips Apr 11, 2019
fc619da
Pass HTLC test for psbt
joemphilips Apr 12, 2019
cfed1ab
Remove unnecessary props from Miniscript/AssemblyInfo.fs
joemphilips Apr 13, 2019
f7f453a
remove nits
joemphilips Apr 13, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,7 @@ before_install:
script:
- dotnet build ./NBitcoin.Tests/NBitcoin.Tests.csproj /p:TargetFrameworkOverride=$TargetFrameworkOverride -c Release -f netcoreapp2.1 $EXTRA_CONSTANT
- dotnet test --no-build -c Release -f netcoreapp2.1 ./NBitcoin.Tests/NBitcoin.Tests.csproj --filter "RestClient=RestClient|RPCClient=RPCClient|Protocol=Protocol|Core=Core|UnitTest=UnitTest" -p:ParallelizeTestCollections=false
- dotnet build ./NBitcoin.Miniscript.Tests/FSharp/NBitcoin.Miniscript.Tests.FSharp.fsproj /p:TargetFrameworkOverride=$TargetFrameworkOverride -c Release -f netcoreapp2.1 $EXTRA_CONSTANT
- dotnet run --no-build -c Release --project ./NBitcoin.Miniscript.Tests/FSharp/NBitcoin.Miniscript.Tests.FSharp.fsproj -f netcoreapp2.1
- dotnet build ./NBitcoin.Miniscript.Tests/CSharp/NBitcoin.Miniscript.Tests.CSharp.csproj /p:TargetFrameworkOverride=$TargetFrameworkOverride -c Release -f netcoreapp2.1 $EXTRA_CONSTANT
- dotnet test --no-build -c Release -f netcoreapp2.1 ./NBitcoin.Miniscript.Tests/CSharp/NBitcoin.Miniscript.Tests.CSharp.csproj -p:ParallelizeTestCollections=false
4 changes: 2 additions & 2 deletions NBitcoin.Altcoins/NBitcoin.Altcoins.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
</PropertyGroup>
<PropertyGroup>
<Version Condition=" '$(Version)' == '' ">1.0.1.42</Version>
<TargetFrameworks>net461;net452;netstandard1.3;netcoreapp2.1;netstandard2.0</TargetFrameworks>
<TargetFrameworks>net452;net461;netstandard1.3;netcoreapp2.1;netstandard2.0</TargetFrameworks>
<TargetFrameworks Condition="'$(BuildingInsideVisualStudio)' == 'true'">netstandard2.0</TargetFrameworks>
<TargetFrameworks Condition="'$(TargetFrameworkOverride)' != ''">$(TargetFrameworkOverride)</TargetFrameworks>
<NoWarn>1591;1573;1572;1584;1570;3021</NoWarn>
Expand All @@ -34,4 +34,4 @@
<Optimize>true</Optimize>
<DocumentationFile>bin\Release\NBitcoin.Altcoins.XML</DocumentationFile>
</PropertyGroup>
</Project>
</Project>
50 changes: 50 additions & 0 deletions NBitcoin.Miniscript.Tests/CSharp/AssertEx.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using NBitcoin.Crypto;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xunit;

namespace NBitcoin.Miniscript.Tests.CSharp
{
class AssertEx
{
[DebuggerHidden]
internal static void Error(string msg)
{
Assert.False(true, msg);
}
[DebuggerHidden]
internal static void Equal<T>(T actual, T expected)
{
Assert.Equal(expected, actual);
}
[DebuggerHidden]
internal static void CollectionEquals<T>(T[] actual, T[] expected)
{
if(actual.Length != expected.Length)
Assert.False(true, "Actual.Length(" + actual.Length + ") != Expected.Length(" + expected.Length + ")");

for(int i = 0; i < actual.Length; i++)
{
if(!Object.Equals(actual[i], expected[i]))
Assert.False(true, "Actual[" + i + "](" + actual[i] + ") != Expected[" + i + "](" + expected[i] + ")");
}
}

[DebuggerHidden]
internal static void StackEquals(ContextStack<byte[]> stack1, ContextStack<byte[]> stack2)
{
var hash1 = stack1.Select(o => Hashes.Hash256(o)).ToArray();
var hash2 = stack2.Select(o => Hashes.Hash256(o)).ToArray();
AssertEx.CollectionEquals(hash1, hash2);
}

internal static void CollectionEquals(System.Collections.BitArray bitArray, int p)
{
throw new NotImplementedException();
}
}
}
99 changes: 99 additions & 0 deletions NBitcoin.Miniscript.Tests/CSharp/MiniscriptPSBTTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
using System;
using System.Collections.Generic;
using Xunit;
using NBitcoin.Crypto;
using NBitcoin.BIP174;
using NBitcoin.Miniscript;
using static NBitcoin.Miniscript.AbstractPolicy;
using System.Linq;

namespace NBitcoin.Miniscript.Tests.CSharp
{
public class MiniscriptPSBTTests
{
private Key[] privKeys { get; }
public Network Network { get; }

public MiniscriptPSBTTests()
{
privKeys = new[] { new Key(), new Key(), new Key(), new Key() };
Network = Network.Main;
}

private TransactionSignature GetDummySig()
{
var hash = new uint256();
var ecdsa = privKeys[0].Sign(hash);
return new TransactionSignature(ecdsa, SigHash.All);
}

[Fact]
public void ShouldSatisfyMiniscript()
{
Copy link
Contributor

Choose a reason for hiding this comment

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

FYI mixed tabs and spaces, misconfigured editor? ;)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

😭
I will fix later.

var policyStr = $"aor(and(pk({privKeys[0].PubKey}), time({10000})), multi(2, {privKeys[0].PubKey}, {privKeys[1].PubKey})";
var ms = Miniscript.FromStringUnsafe(policyStr);
Assert.NotNull(ms);

// We can write AbstractPolicy directly instead of using string representation.
var pubKeys = privKeys.Select(p => p.PubKey).Take(2).ToArray();
var policy = new AsymmetricOr(
new And(
new AbstractPolicy.Key(privKeys[0].PubKey),
new Time(new LockTime(10000))
),
new Multi(2, pubKeys)
);
// And it is EqualityComparable by default. 🎉
var msFromPolicy = Miniscript.FromPolicyUnsafe(policy);
Assert.Equal(ms, msFromPolicy);

Func<PubKey, TransactionSignature> dummySignatureProvider =
pk => pk == privKeys[0].PubKey ? GetDummySig() : null;
Assert.Throws<MiniscriptSatisfyException>(() => ms.SatisfyUnsafe(dummySignatureProvider));

Assert.Throws<MiniscriptSatisfyException>(() => ms.SatisfyUnsafe(dummySignatureProvider, null, 9999u));
var r3 = ms.Satisfy(dummySignatureProvider, null, 10000u);
Assert.True(r3.IsOk);

Func<PubKey, TransactionSignature> dummySignatureProvider2 =
pk => (pk == privKeys[0].PubKey || pk == privKeys[1].PubKey) ? GetDummySig() : null;
var r5 = ms.Satisfy(dummySignatureProvider2);
Assert.True(r5.IsOk);
}

[Fact]
public void ShouldSatisfyPSBTWithComplexScript()
{
// case 1: bip199 HTLC
var alice = privKeys[0];
var bob = privKeys[1];
var bobSecret = new uint256(0xdeadbeef);
var bobHash = new uint256(Hashes.SHA256(bobSecret.ToBytes()), false);
var policyStr = $"aor(and(hash({bobHash}), pk({bob.PubKey})), and(pk({alice.PubKey}), time({10000})))";
var ms = Miniscript.FromStringUnsafe(policyStr);
var script = ms.ToScript();
var funds = Utils.CreateDummyFunds(Network, privKeys, script);
var tx = Utils.CreateTxToSpendFunds(funds, privKeys, script, false, false);
var psbt = PSBT.FromTransaction(tx)
.AddTransactions(funds)
.AddScript(script);

// Can not finalize without signatures.
Assert.Throws<AggregateException>(() => psbt.FinalizeUnsafe(h => h == bobHash ? bobSecret : null, age: 10001u));
// It has signature but it is not matured.
psbt.SignAll(alice);
Assert.Throws<AggregateException>(() => psbt.FinalizeUnsafe(h => h == bobHash ? bobSecret : null, age: 9999u));

// it has both signature and a secret.
psbt.SignAll(bob);
psbt.FinalizeUnsafe(h => h == bobHash ? bobSecret : null);
Assert.True(psbt.CanExtractTX());

var txExtracted = psbt.ExtractTX();
var builder = Network.CreateTransactionBuilder();
builder.AddCoins(Utils.DummyFundsToCoins(funds, script, privKeys[0])).AddKeys(privKeys);
if (!builder.Verify(txExtracted, (Money)null, out var errors))
throw new InvalidOperationException(errors.Aggregate(string.Empty, (a, b) => a + ";\n" + b));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net461;netstandard2.0;netcoreapp2.1;</TargetFrameworks>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FSharp.Core" Version="4.6.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\NBitcoin\NBitcoin.csproj" />
<ProjectReference Include="..\..\NBitcoin.TestFramework\NBitcoin.TestFramework.csproj" />
<ProjectReference Include="..\..\NBitcoin.Tests\NBitcoin.Tests.csproj" />
<ProjectReference Include="..\..\NBitcoin.Miniscript\NBitcoin.Miniscript.fsproj" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\NBitcoin.Miniscript\NBitcoin.Miniscript.fsproj" />
</ItemGroup>

<ItemGroup>
<None Include="data\psbt.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
using static NBitcoin.Utils;
using NBitcoin.BIP174;
using Xunit;
using NBitcoin.Tests;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.IO;
using System;
using NBitcoin.DataEncoders;
using System.Collections.Generic;
using System.Linq;
using static NBitcoin.Tests.Comparer;
using Xunit.Abstractions;

namespace NBitcoin.Tests
namespace NBitcoin.Miniscript.Tests.CSharp
{

public class PSBTTests
{
private readonly ITestOutputHelper Output;
Expand Down Expand Up @@ -146,7 +148,7 @@ public void CanUpdate()
Assert.Single(signedPSBTWithCoins.Inputs[4].PartialSigs);
Assert.Single(signedPSBTWithCoins.Inputs[5].PartialSigs);
var ex = Assert.Throws<AggregateException>(() =>
signedPSBTWithCoins.Finalize()
signedPSBTWithCoins.FinalizeUnsafe()
);
var finalizationErrors = ex.InnerExceptions;
// Only p2wpkh and p2sh-p2wpkh will succeed.
Expand Down Expand Up @@ -191,7 +193,7 @@ public void CanUpdate()

Assert.False(whollySignedPSBT.CanExtractTX());

var finalizedPSBT = whollySignedPSBT.Finalize();
var finalizedPSBT = whollySignedPSBT.FinalizeUnsafe();
Assert.True(finalizedPSBT.CanExtractTX());

var finalTX = finalizedPSBT.ExtractTX();
Expand Down Expand Up @@ -228,7 +230,7 @@ public void ShouldCaptureExceptionInFinalization()
var tx = CreateTxToSpendFunds(funds, keys, redeem, false, false);
var psbt = PSBT.FromTransaction(tx);

var ex = Assert.Throws<AggregateException>(() => psbt.Finalize());
var ex = Assert.Throws<AggregateException>(() => psbt.FinalizeUnsafe());
var errors = ex.InnerExceptions;
Assert.Equal(6, errors.Count);
}
Expand Down Expand Up @@ -377,7 +379,7 @@ public void ShouldPassTheLongestTestInBIP174()
expected = PSBT.Parse((string)testcase["psbtcombined"]);
Assert.Equal(expected, combined);

var finalized = psbt.Finalize();
var finalized = psbt.FinalizeUnsafe();
expected = PSBT.Parse((string)testcase["psbtfinalized"]);
Assert.Equal(expected, finalized);

Expand Down
Loading