Skip to content

Commit 5f5e144

Browse files
committed
MimbleWimble(Tests): implement MW types
Add types needed for MimbleWimble transactions and implement serialization. Made all MimbleWimble types implement ISerializable and interface and Read static method. Reuse NBitcoin's BitcoinStream for serialization and deserialization, but don't use its IBitcoinSerializable interface because it mixes reading and writing in one method. Added new test project for MimbleWimble tests. Added test for peg-in transaction. Added property-based tests for serialization and deserilaization. Added test that deserilizes transaction generated and serialized by modified litecoin test (see [1]). Added tests for parsing peg-out transaction and MW to MW (HogEx) transaction. [1] https://github.com/litecoin-project/litecoin/blob/5ac781487cc9589131437b23c69829f04002b97e/src/libmw/test/tests/models/tx/Test_Transaction.cpp
1 parent 527a9be commit 5f5e144

13 files changed

+988
-20
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@
77
/src/NLitecoin/bin
88
/tests/NLitecoin.Tests/obj
99
/tests/NLitecoin.Tests/bin
10+
/tests/NLitecoin.MimbleWimble.Tests/obj
11+
/tests/NLitecoin.MimbleWimble.Tests/bin

NLitecoin.sln

+8-2
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio Version 17
44
VisualStudioVersion = 17.6.33829.357
55
MinimumVisualStudioVersion = 10.0.40219.1
6-
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "NLitecoin", "src\NLitecoin\NLitecoin.fsproj", "{1128287F-0435-4FA9-B4DD-420A9E1FDB23}"
6+
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "NLitecoin", "src\NLitecoin\NLitecoin.fsproj", "{1128287F-0435-4FA9-B4DD-420A9E1FDB23}"
77
EndProject
8-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NLitecoin.Tests", "tests\NLitecoin.Tests\NLitecoin.Tests.csproj", "{F954D3AC-36BC-483E-8DB1-4CC65DF1694D}"
8+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NLitecoin.Tests", "tests\NLitecoin.Tests\NLitecoin.Tests.csproj", "{F954D3AC-36BC-483E-8DB1-4CC65DF1694D}"
9+
EndProject
10+
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "NLitecoin.MimbleWimble.Tests", "tests\NLitecoin.MimbleWimble.Tests\NLitecoin.MimbleWimble.Tests.fsproj", "{6A67D54D-BE2C-449F-88D2-D6739A5F3F89}"
911
EndProject
1012
Global
1113
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -21,6 +23,10 @@ Global
2123
{F954D3AC-36BC-483E-8DB1-4CC65DF1694D}.Debug|Any CPU.Build.0 = Debug|Any CPU
2224
{F954D3AC-36BC-483E-8DB1-4CC65DF1694D}.Release|Any CPU.ActiveCfg = Release|Any CPU
2325
{F954D3AC-36BC-483E-8DB1-4CC65DF1694D}.Release|Any CPU.Build.0 = Release|Any CPU
26+
{6A67D54D-BE2C-449F-88D2-D6739A5F3F89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27+
{6A67D54D-BE2C-449F-88D2-D6739A5F3F89}.Debug|Any CPU.Build.0 = Debug|Any CPU
28+
{6A67D54D-BE2C-449F-88D2-D6739A5F3F89}.Release|Any CPU.ActiveCfg = Release|Any CPU
29+
{6A67D54D-BE2C-449F-88D2-D6739A5F3F89}.Release|Any CPU.Build.0 = Release|Any CPU
2430
EndGlobalSection
2531
GlobalSection(SolutionProperties) = preSolution
2632
HideSolutionNode = FALSE

src/NLitecoin/Litecoin.fs

+29-18
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,14 @@ module private TxListExtensions =
5050
type LitecoinTransaction() =
5151
inherit Transaction()
5252

53+
static let mwebExtensionTxFlag = 8uy
54+
55+
member val MimbleWimbleTransaction: Option<MimbleWimble.Transaction> = None with get, set
56+
5357
override self.GetConsensusFactory() = LitecoinConsensusFactory.Instance
5458

5559
member private self.Read (stream: BitcoinStream) (witSupported: bool) =
56-
let flags = 0uy
60+
let mutable flags = 0uy
5761
self.nVersion <- stream.ReadWrite self.nVersion
5862
// Try to read the vin. In case the dummy is there, this will be read as an empty vector.
5963
stream.ReadWrite(&self.vin)
@@ -64,7 +68,7 @@ type LitecoinTransaction() =
6468

6569
if self.vin.Count = 0 && witSupported && not hasNoDummy then
6670
// We read a dummy or an empty vin.
67-
let flags = stream.ReadWrite flags
71+
flags <- stream.ReadWrite flags
6872
if flags <> 0uy then
6973
// Assume we read a dummy and a flag.
7074
stream.ReadWrite(&self.vin)
@@ -79,22 +83,17 @@ type LitecoinTransaction() =
7983
stream.ReadWrite(&self.vout)
8084
self.vout <- self.vout.WithTransaction self
8185

82-
let flags =
83-
if ((flags &&& 1uy) <> 0uy) && witSupported then
84-
// The witness flag is present, and we support witnesses.
85-
let wit = Witness self.Inputs
86-
wit.ReadWrite stream
87-
flags ^^^ 1uy
88-
else
89-
flags
90-
let flags =
91-
if (flags &&& 8uy) <> 0uy then //MWEB extension tx flag
92-
(* The MWEB flag is present, but currently no MWEB data is supported.
93-
* This fix just prevent from throwing exception bellow so cannonical litecoin transaction can be read
94-
*)
95-
flags ^^^ 8uy
96-
else
97-
flags
86+
if ((flags &&& 1uy) <> 0uy) && witSupported then
87+
// The witness flag is present, and we support witnesses.
88+
let wit = Witness self.Inputs
89+
wit.ReadWrite stream
90+
flags <- flags ^^^ 1uy
91+
92+
if (flags &&& mwebExtensionTxFlag) <> 0uy then
93+
let version = ref 0uy
94+
stream.ReadWrite version
95+
self.MimbleWimbleTransaction <- Some(MimbleWimble.Transaction.Read stream)
96+
flags <- flags ^^^ 8uy
9897

9998
if flags <> 0uy then
10099
// Unknown flag in the serialization
@@ -118,6 +117,12 @@ type LitecoinTransaction() =
118117
else
119118
0uy
120119

120+
let flags =
121+
if self.MimbleWimbleTransaction.IsSome then
122+
flags ||| mwebExtensionTxFlag
123+
else
124+
flags
125+
121126
let flags =
122127
if flags <> 0uy then
123128
// Use extended format in case witnesses are to be serialized.
@@ -135,6 +140,12 @@ type LitecoinTransaction() =
135140
let wit = Witness self.Inputs
136141
wit.ReadWrite stream
137142

143+
match self.MimbleWimbleTransaction with
144+
| Some mwebTransaction ->
145+
stream.ReadWrite MimbleWimble.Transaction.Version |> ignore
146+
(mwebTransaction :> MimbleWimble.ISerializeable).Write stream
147+
| None -> ()
148+
138149
override self.ReadWrite(stream: BitcoinStream) =
139150
let witSupported =
140151
(((uint32 stream.TransactionOptions) &&& (uint32 TransactionOptions.Witness)) <> 0u) &&

0 commit comments

Comments
 (0)