Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backend(,Backend.Tests): improve marshalling to fix crash #247

Merged
merged 8 commits into from
Jan 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions scripts/bump.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ let filesToBumpMiniVersion: seq<string> =

let filesToBumpFullVersion: seq<string> =
Seq.append filesToBumpMiniVersion [
"src/GWallet.Backend/GWallet.Backend.fsproj"
"src/GWallet.Backend/Properties/CommonAssemblyInfo.fs"
"snap/snapcraft.yaml"
]
Expand Down
6 changes: 5 additions & 1 deletion src/GWallet.Backend.Tests/Deserialization.fs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,15 @@ open GWallet.Backend.UtxoCoin
[<TestFixture>]
type Deserialization() =

[<SetUp>]
member __.``Versioning works``() =
MarshallingData.AssertAssemblyVersion()

[<Test>]
member __.``deserialize cache does not fail``() =

let deserializedCache: DietCache = Marshalling.Deserialize
MarshallingData.SofisticatedCachingDataExampleInJson
MarshallingData.SophisticatedCachingDataExampleInJson

Assert.That(deserializedCache, Is.Not.Null)

Expand Down
1 change: 1 addition & 0 deletions src/GWallet.Backend.Tests/GWallet.Backend.Tests.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<Compile Include="Serialization.fs" />
<Compile Include="Deserialization.fs" />
<Compile Include="ExceptionMarshalling.fs" />
<Compile Include="MetaMarshalling.fs" />
<Compile Include="Program.fs" />
</ItemGroup>
<ItemGroup>
Expand Down
16 changes: 12 additions & 4 deletions src/GWallet.Backend.Tests/MarshallingData.fs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ open GWallet.Backend.Ether
module MarshallingData =

let private executingAssembly = Assembly.GetExecutingAssembly()
let private version = executingAssembly.GetName().Version.ToString()
let private version = VersionHelper.CURRENT_VERSION
let private binPath = executingAssembly.Location |> FileInfo
let private prjPath = Path.Combine(binPath.Directory.FullName, "..") |> DirectoryInfo

Expand Down Expand Up @@ -175,9 +175,9 @@ module MarshallingData =
.Add("0xFOOBARBAZ", [Currency.ETC.ToString()])
let private fiatValues = Map.empty.Add(Currency.ETH.ToString(), 161.796m)
.Add(Currency.ETC.ToString(), 169.99999999m)
let SofisticatedCachingDataExample = { UsdPrice = fiatValues; Addresses = addresses; Balances = balances; }
let SophisticatedCachingDataExample = { UsdPrice = fiatValues; Addresses = addresses; Balances = balances; }

let SofisticatedCachingDataExampleInJson =
let SophisticatedCachingDataExampleInJson =
sprintf """{
"Version": "%s",
"TypeName": "%s",
Expand Down Expand Up @@ -312,7 +312,7 @@ module MarshallingData =
let someEtherTransactionInfo =
{
Proposal = someUnsignedEtherTransactionProposal;
Cache = SofisticatedCachingDataExample;
Cache = SophisticatedCachingDataExample
Metadata = someEtherTxMetadata;
}
let SignedEtherTransactionExample =
Expand All @@ -325,3 +325,11 @@ module MarshallingData =

let UnsignedEtherTransactionExampleInJson =
ReadEmbeddedResource "unsignedAndFormattedEtherTransaction.json"

let AssertAssemblyVersion() =
Assert.That(
VersionHelper.CURRENT_VERSION,
Is.Not.EqualTo "1.0.0.0",
"Proper version was somehow not properly assigned as assembly version"
)

23 changes: 23 additions & 0 deletions src/GWallet.Backend.Tests/MetaMarshalling.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace GWallet.Backend.Tests

open NUnit.Framework

open GWallet.Backend

[<TestFixture>]
type MetaMarshalling() =

[<Test>]
member __.``wrapper's TypeName property doesn't contain assembly-qualified-name``() =
let json = Marshalling.Serialize MarshallingData.SignedBtcTransactionExample
Assert.That(json, Is.Not.Null)
Assert.That(json, Is.Not.Empty)

let wrapper = Marshalling.ExtractWrapper json
Assert.That(wrapper, Is.Not.Null)
Assert.That(wrapper.TypeName, Is.Not.Null)
Assert.That(wrapper.TypeName, Is.Not.Empty)
Assert.That(wrapper.Version, Is.Not.Null)
Assert.That(wrapper.Version, Is.Not.Empty)

Assert.That(wrapper.TypeName, Does.Not.Contain "Version=")
9 changes: 7 additions & 2 deletions src/GWallet.Backend.Tests/Serialization.fs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ open GWallet.Backend

[<TestFixture>]
type Serialization() =

[<SetUp>]
member __.``Versioning works``() =
MarshallingData.AssertAssemblyVersion()

[<Test>]
member __.``basic caching export does not fail``() =
let json = Marshalling.Serialize MarshallingData.EmptyCachingDataExample
Expand All @@ -24,12 +29,12 @@ type Serialization() =
[<Test>]
member __.``complex caching export works``() =

let json = Marshalling.Serialize MarshallingData.SofisticatedCachingDataExample
let json = Marshalling.Serialize MarshallingData.SophisticatedCachingDataExample
Assert.That(json, Is.Not.Null)
Assert.That(json, Is.Not.Empty)

Assert.That(json,
Is.EqualTo (MarshallingData.SofisticatedCachingDataExampleInJson))
Is.EqualTo (MarshallingData.SophisticatedCachingDataExampleInJson))

[<Test>]
member __.``unsigned BTC transaction export``() =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"Version": "{version}",
"TypeName": "GWallet.Backend.SignedTransaction`1[[GWallet.Backend.UtxoCoin.TransactionMetadata, GWallet.Backend, Version={version}, Culture=neutral, PublicKeyToken=null]]",
"TypeName": "GWallet.Backend.SignedTransaction`1[GWallet.Backend.UtxoCoin.TransactionMetadata]",
"Value": {
"TransactionInfo": {
"Proposal": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"Version": "{version}",
"TypeName": "GWallet.Backend.SignedTransaction`1[[GWallet.Backend.Ether.TransactionMetadata, GWallet.Backend, Version={version}, Culture=neutral, PublicKeyToken=null]]",
"TypeName": "GWallet.Backend.SignedTransaction`1[GWallet.Backend.Ether.TransactionMetadata]",
"Value": {
"TransactionInfo": {
"Proposal": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"Version": "{version}",
"TypeName": "GWallet.Backend.SignedTransaction`1[[GWallet.Backend.Ether.TransactionMetadata, GWallet.Backend, Version={version}, Culture=neutral, PublicKeyToken=null]]",
"TypeName": "GWallet.Backend.SignedTransaction`1[GWallet.Backend.Ether.TransactionMetadata]",
"Value": {
"TransactionInfo": {
"Proposal": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"Version": "{version}",
"TypeName": "GWallet.Backend.UnsignedTransaction`1[[GWallet.Backend.UtxoCoin.TransactionMetadata, GWallet.Backend, Version={version}, Culture=neutral, PublicKeyToken=null]]",
"TypeName": "GWallet.Backend.UnsignedTransaction`1[GWallet.Backend.UtxoCoin.TransactionMetadata]",
"Value": {
"Proposal": {
"OriginAddress": "16pKBjGGZkUXo1afyBNf5ttFvV9hauS1kR",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"Version": "{version}",
"TypeName": "GWallet.Backend.UnsignedTransaction`1[[GWallet.Backend.Ether.TransactionMetadata, GWallet.Backend, Version={version}, Culture=neutral, PublicKeyToken=null]]",
"TypeName": "GWallet.Backend.UnsignedTransaction`1[GWallet.Backend.Ether.TransactionMetadata]",
"Value": {
"Proposal": {
"OriginAddress": "0xf3j4m0rjx94sushh03j",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"Version": "{version}",
"TypeName": "GWallet.Backend.UnsignedTransaction`1[[GWallet.Backend.Ether.TransactionMetadata, GWallet.Backend, Version={version}, Culture=neutral, PublicKeyToken=null]]",
"TypeName": "GWallet.Backend.UnsignedTransaction`1[GWallet.Backend.Ether.TransactionMetadata]",
"Value": {
"Proposal": {
"OriginAddress": "0xba766d6d13E2Cc921Bf6e896319D32502af9e37E",
Expand Down
8 changes: 4 additions & 4 deletions src/GWallet.Backend/Account.fs
Original file line number Diff line number Diff line change
Expand Up @@ -641,13 +641,13 @@ module Account =

match transType with
| _ when transType = typeof<SignedTransaction<UtxoCoin.TransactionMetadata>> ->
let deserializedBtcTransaction: SignedTransaction<UtxoCoin.TransactionMetadata> =
let deserializedTransaction: SignedTransaction<UtxoCoin.TransactionMetadata> =
Marshalling.Deserialize json
deserializedBtcTransaction.ToAbstract()
deserializedTransaction.ToAbstract()
| _ when transType = typeof<SignedTransaction<Ether.TransactionMetadata>> ->
let deserializedBtcTransaction: SignedTransaction<Ether.TransactionMetadata> =
let deserializedTransaction: SignedTransaction<Ether.TransactionMetadata> =
Marshalling.Deserialize json
deserializedBtcTransaction.ToAbstract()
deserializedTransaction.ToAbstract()
| _ when transType.GetGenericTypeDefinition() = typedefof<UnsignedTransaction<_>> ->
raise TransactionNotSignedYet
| unexpectedType ->
Expand Down
6 changes: 6 additions & 0 deletions src/GWallet.Backend/GWallet.Backend.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

<PropertyGroup>
<Version>0.4.407.0</Version>
<AssemblyVersion>0.4.407.0</AssemblyVersion>
<FileVersion>0.4.407.0</FileVersion>
</PropertyGroup>

<ItemGroup>
<Compile Include="Properties\CommonAssemblyInfo.fs" />
<Compile Include="Properties\AssemblyInfo.fs" />
Expand Down
45 changes: 38 additions & 7 deletions src/GWallet.Backend/Marshalling.fs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ type MarshallingWrapper<'T> =
{
Value = value
Version = VersionHelper.CURRENT_VERSION
TypeName = typeof<'T>.FullName
TypeName = typeof<'T>.ToString()
}

type private PascalCase2LowercasePlusUnderscoreContractResolver() =
Expand Down Expand Up @@ -145,15 +145,46 @@ module Marshalling =

let private currentVersion = VersionHelper.CURRENT_VERSION

let ExtractType(json: string): Type =
let ExtractWrapper(json: string): MarshallingWrapper<obj> =
if String.IsNullOrEmpty json then
raise <| ArgumentNullException "json"
let wrapper = JsonConvert.DeserializeObject<MarshallingWrapper<obj>> json
if Object.ReferenceEquals(wrapper, null) then
failwith <| SPrintF1 "Failed to extract type from JSON (null check): %s" json
try
Type.GetType wrapper.TypeName
with
| :? NullReferenceException as _nre ->
failwith <| SPrintF1 "Failed to extract type from JSON (NRE): %s" json
if String.IsNullOrEmpty wrapper.TypeName then
failwith <| SPrintF1 "Failed to extract type from JSON (inner null check 1): %s" json
if String.IsNullOrEmpty wrapper.Version then
failwith <| SPrintF1 "Failed to extract type from JSON (inner null check 2): %s" json
wrapper

let ExtractType(json: string): Type =
let wrapper = ExtractWrapper json

let res =
try
// we prefer an ex with innerException than an NRE caused by the
// consumer of this function
let throwOnError = true

Type.GetType(wrapper.TypeName, throwOnError)
with
| :? NullReferenceException as _nre ->
failwith
<| SPrintF1 "Failed to extract type from JSON (NRE): %s" json
| ex ->
let errMsg =
SPrintF2 "Problem when trying to find type '%s' (version '%s')"
wrapper.TypeName
wrapper.Version
raise <| Exception(errMsg, ex)
if isNull res then
failwith
<| SPrintF2
"Could not find type '%s' (version '%s')"
wrapper.TypeName
wrapper.Version
res


// FIXME: should we rather use JContainer.Parse? it seems JObject.Parse wouldn't detect error in this: {A:{"B": 1}}
// (for more info see replies of https://stackoverflow.com/questions/6903477/need-a-string-json-validator )
Expand Down
Loading