Skip to content

Commit

Permalink
MimbleWimble(Tests): parse MWEB tx as part of LTC tx
Browse files Browse the repository at this point in the history
Made MWEB transaction a part of LitecoinTransaction, as it
should be. Modified deserialization code to properly handle
reading and writing MimbleWimble transaction. Got rid of
hardcoded offsets.
  • Loading branch information
webwarrior-ws committed Oct 6, 2023
1 parent 6fabc2e commit 23f0e1f
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 29 deletions.
47 changes: 29 additions & 18 deletions src/NLitecoin/Litecoin.fs
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,14 @@ module private TxListExtensions =
type LitecoinTransaction() =
inherit Transaction()

static let mwebExtensionTxFlag = 8uy

member val MimbleWimbleTransaction: Option<MimbleWimble.Transaction> = None with get, set

override self.GetConsensusFactory() = LitecoinConsensusFactory.Instance

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

if self.vin.Count = 0 && witSupported && not hasNoDummy then
// We read a dummy or an empty vin.
let flags = stream.ReadWrite flags
flags <- stream.ReadWrite flags
if flags <> 0uy then
// Assume we read a dummy and a flag.
stream.ReadWrite(&self.vin)
Expand All @@ -79,22 +83,17 @@ type LitecoinTransaction() =
stream.ReadWrite(&self.vout)
self.vout <- self.vout.WithTransaction self

let flags =
if ((flags &&& 1uy) <> 0uy) && witSupported then
// The witness flag is present, and we support witnesses.
let wit = Witness self.Inputs
wit.ReadWrite stream
flags ^^^ 1uy
else
flags
let flags =
if (flags &&& 8uy) <> 0uy then //MWEB extension tx flag
(* The MWEB flag is present, but currently no MWEB data is supported.
* This fix just prevent from throwing exception bellow so cannonical litecoin transaction can be read
*)
flags ^^^ 8uy
else
flags
if ((flags &&& 1uy) <> 0uy) && witSupported then
// The witness flag is present, and we support witnesses.
let wit = Witness self.Inputs
wit.ReadWrite stream
flags <- flags ^^^ 1uy

if (flags &&& mwebExtensionTxFlag) <> 0uy then
let version = ref 0uy
stream.ReadWrite version
self.MimbleWimbleTransaction <- Some(MimbleWimble.Transaction.Read stream)
flags <- flags ^^^ 8uy

if flags <> 0uy then
// Unknown flag in the serialization
Expand All @@ -118,6 +117,12 @@ type LitecoinTransaction() =
else
0uy

let flags =
if self.MimbleWimbleTransaction.IsSome then
flags ||| mwebExtensionTxFlag
else
flags

let flags =
if flags <> 0uy then
// Use extended format in case witnesses are to be serialized.
Expand All @@ -135,6 +140,12 @@ type LitecoinTransaction() =
let wit = Witness self.Inputs
wit.ReadWrite stream

match self.MimbleWimbleTransaction with
| Some mwebTransaction ->
stream.ReadWrite MimbleWimble.Transaction.Version |> ignore
(mwebTransaction :> MimbleWimble.ISerializeable).Write stream
| None -> ()

override self.ReadWrite(stream: BitcoinStream) =
let witSupported =
(((uint32 stream.TransactionOptions) &&& (uint32 TransactionOptions.Witness)) <> 0u) &&
Expand Down
5 changes: 1 addition & 4 deletions src/NLitecoin/MimbleWimble/Types.fs
Original file line number Diff line number Diff line change
Expand Up @@ -705,10 +705,7 @@ type Transaction =
// The transaction body.
Body: TxBody
}
/// see https://github.com/litecoin-project/lips/blob/master/lip-0003.mediawiki#user-content-PegIn_Transactions
static member RegularLTCPeginTranasctionSize = 200

static member RegularTransactionOffset = 9
static member Version = 1uy

/// Parse hex-encoded MimbleWimble transaction
static member ParseString(txString: string) : Transaction =
Expand Down
2 changes: 1 addition & 1 deletion src/NLitecoin/NLitecoin.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@
</PropertyGroup>

<ItemGroup>
<Compile Include="Litecoin.fs" />
<Compile Include="MimbleWimble\Types.fs" />
<Compile Include="MimbleWimble\EC.fs" />
<Compile Include="MimbleWimble\Pedersen.fs" />
<Compile Include="MimbleWimble\Bulletproof.fs" />
<Compile Include="MimbleWimble\TransactionBuilder.fs" />
<Compile Include="MimbleWimble\Wallet.fs" />
<Compile Include="Litecoin.fs" />
</ItemGroup>

<ItemGroup>
Expand Down
21 changes: 15 additions & 6 deletions tests/NLitecoin.MimbleWimble.Tests/TransactionTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ let Setup () =
let ParsePegInTransaction () =
let rawTransaction = IO.File.ReadAllText "transaction1.txt"

let mimbleRawWimbleTransaction = rawTransaction[Transaction.RegularLTCPeginTranasctionSize * 2 ..]
let transaction = Transaction.ParseString mimbleRawWimbleTransaction
let litecoinTransaction =
NBitcoin.Transaction.Parse(rawTransaction, NLitecoin.Litecoin.Instance.Mainnet)

let transaction =
(litecoinTransaction :?> NLitecoin.LitecoinTransaction).MimbleWimbleTransaction.Value

Assert.AreEqual(0, transaction.Body.Inputs.Length)
Assert.AreEqual(1, transaction.Body.Kernels.Length)
Expand All @@ -31,8 +34,11 @@ let ParsePegInTransaction () =
let ParseHogExTransaction () =
let rawTransaction = IO.File.ReadAllText "transaction2.txt"

let mimbleRawWimbleTransaction = rawTransaction[Transaction.RegularTransactionOffset * 2 ..]
let transaction = Transaction.ParseString mimbleRawWimbleTransaction
let litecoinTransaction =
NBitcoin.Transaction.Parse(rawTransaction, NLitecoin.Litecoin.Instance.Mainnet)

let transaction =
(litecoinTransaction :?> NLitecoin.LitecoinTransaction).MimbleWimbleTransaction.Value

Assert.GreaterOrEqual(transaction.Body.Inputs.Length, 1)
Assert.AreEqual(1, transaction.Body.Kernels.Length)
Expand All @@ -48,8 +54,11 @@ let ParseHogExTransaction () =
let ParsePegOutTransaction () =
let rawTransaction = IO.File.ReadAllText "transaction3.txt"

let mimbleRawWimbleTransaction = rawTransaction[Transaction.RegularTransactionOffset * 2 ..]
let transaction = Transaction.ParseString mimbleRawWimbleTransaction
let litecoinTransaction =
NBitcoin.Transaction.Parse(rawTransaction, NLitecoin.Litecoin.Instance.Mainnet)

let transaction =
(litecoinTransaction :?> NLitecoin.LitecoinTransaction).MimbleWimbleTransaction.Value

Assert.GreaterOrEqual(transaction.Body.Inputs.Length, 1)
Assert.AreEqual(1, transaction.Body.Kernels.Length)
Expand Down

0 comments on commit 23f0e1f

Please sign in to comment.