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

Add decimals to BigDecimal constructor #2255

Merged
merged 2 commits into from
Jan 21, 2021
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
29 changes: 26 additions & 3 deletions src/neo/BigDecimal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,39 @@ public struct BigDecimal
public byte Decimals => decimals;
public int Sign => value.Sign;

/// <summary>
/// Create BigDecimal from BigInteger
/// </summary>
/// <param name="value">Value</param>
/// <param name="decimals">Decimals</param>
public BigDecimal(BigInteger value, byte decimals)
{
this.value = value;
this.decimals = decimals;
}

public BigDecimal(decimal value)
/// <summary>
/// Create BigDecimal from decimal
/// </summary>
/// <param name="value">Value</param>
public unsafe BigDecimal(decimal value)
{
this.decimals = BitConverter.GetBytes(decimal.GetBits(value)[3])[2];
this.value = new BigInteger(decimal.Multiply((Decimal)Math.Pow(10, this.decimals), value));
ReadOnlySpan<byte> buffer = new ReadOnlySpan<byte>(&value, sizeof(decimal));
this.decimals = buffer[14];
this.value = new BigInteger(decimal.Multiply((decimal)Math.Pow(10, decimals), value));
}

/// <summary>
/// Create BigDecimal from decimal
/// </summary>
/// <param name="value">Value</param>
/// <param name="decimals">Decimals</param>
public unsafe BigDecimal(decimal value, byte decimals)
{
ReadOnlySpan<byte> buffer = new ReadOnlySpan<byte>(&value, sizeof(decimal));
if (buffer[14] > decimals) throw new ArgumentException(null, nameof(value));
this.value = new BigInteger(decimal.Multiply((decimal)Math.Pow(10, decimals), value));
this.decimals = decimals;
}

public BigDecimal ChangeDecimals(byte decimals)
Expand Down
2 changes: 1 addition & 1 deletion src/neo/Wallets/Wallet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ public BigDecimal GetBalance(UInt160 asset_id, params UInt160[] accounts)
}
using ApplicationEngine engine = ApplicationEngine.Run(script, gas: 20000000L * accounts.Length);
if (engine.State.HasFlag(VMState.FAULT))
return new BigDecimal(0, 0);
return new BigDecimal(BigInteger.Zero, 0);
byte decimals = (byte)engine.ResultStack.Pop().GetInteger();
BigInteger amount = engine.ResultStack.Pop().GetInteger();
return new BigDecimal(amount, decimals);
Expand Down
3 changes: 2 additions & 1 deletion tests/neo.UnitTests/Ledger/UT_Blockchain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Neo.Wallets.NEP6;
using System;
using System.Linq;
using System.Numerics;
using System.Reflection;

namespace Neo.UnitTests.Ledger
Expand Down Expand Up @@ -119,7 +120,7 @@ private Transaction CreateValidTx(NEP6Wallet wallet, UInt160 account, uint nonce
{
AssetId = NativeContract.GAS.Hash,
ScriptHash = account,
Value = new BigDecimal(1,8)
Value = new BigDecimal(BigInteger.One,8)
}
},
account);
Expand Down
24 changes: 12 additions & 12 deletions tests/neo.UnitTests/Network/P2P/Payloads/UT_Transaction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ public void FeeIsMultiSigContract()
{
AssetId = NativeContract.GAS.Hash,
ScriptHash = acc.ScriptHash,
Value = new BigDecimal(1,8)
Value = new BigDecimal(BigInteger.One,8)
}
}, acc.ScriptHash);

Expand Down Expand Up @@ -210,7 +210,7 @@ public void FeeIsSignatureContractDetailed()
{
AssetId = NativeContract.GAS.Hash,
ScriptHash = acc.ScriptHash,
Value = new BigDecimal(1,8)
Value = new BigDecimal(BigInteger.One,8)
}
}, acc.ScriptHash);

Expand Down Expand Up @@ -318,7 +318,7 @@ public void FeeIsSignatureContract_TestScope_Global()
using (ScriptBuilder sb = new ScriptBuilder())
{
// self-transfer of 1e-8 GAS
BigInteger value = (new BigDecimal(1, 8)).Value;
BigInteger value = (new BigDecimal(BigInteger.One, 8)).Value;
sb.EmitDynamicCall(NativeContract.GAS.Hash, "transfer", acc.ScriptHash, acc.ScriptHash, value, null);
sb.Emit(OpCode.ASSERT);
script = sb.ToArray();
Expand Down Expand Up @@ -404,7 +404,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_GAS()
using (ScriptBuilder sb = new ScriptBuilder())
{
// self-transfer of 1e-8 GAS
BigInteger value = (new BigDecimal(1, 8)).Value;
BigInteger value = (new BigDecimal(BigInteger.One, 8)).Value;
sb.EmitDynamicCall(NativeContract.GAS.Hash, "transfer", acc.ScriptHash, acc.ScriptHash, value, null);
sb.Emit(OpCode.ASSERT);
script = sb.ToArray();
Expand Down Expand Up @@ -491,7 +491,7 @@ public void FeeIsSignatureContract_TestScope_CalledByEntry_Plus_GAS()
using (ScriptBuilder sb = new ScriptBuilder())
{
// self-transfer of 1e-8 GAS
System.Numerics.BigInteger value = (new BigDecimal(1, 8)).Value;
System.Numerics.BigInteger value = (new BigDecimal(BigInteger.One, 8)).Value;
sb.EmitDynamicCall(NativeContract.GAS.Hash, "transfer", acc.ScriptHash, acc.ScriptHash, value, null);
sb.Emit(OpCode.ASSERT);
script = sb.ToArray();
Expand Down Expand Up @@ -579,7 +579,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_FAULT()
using (ScriptBuilder sb = new ScriptBuilder())
{
// self-transfer of 1e-8 GAS
System.Numerics.BigInteger value = (new BigDecimal(1, 8)).Value;
System.Numerics.BigInteger value = (new BigDecimal(BigInteger.One, 8)).Value;
sb.EmitDynamicCall(NativeContract.GAS.Hash, "transfer", acc.ScriptHash, acc.ScriptHash, value);
sb.Emit(OpCode.ASSERT);
script = sb.ToArray();
Expand Down Expand Up @@ -631,7 +631,7 @@ public void FeeIsSignatureContract_TestScope_CurrentHash_NEO_GAS()
using (ScriptBuilder sb = new ScriptBuilder())
{
// self-transfer of 1e-8 GAS
BigInteger value = (new BigDecimal(1, 8)).Value;
BigInteger value = (new BigDecimal(BigInteger.One, 8)).Value;
sb.EmitDynamicCall(NativeContract.GAS.Hash, "transfer", acc.ScriptHash, acc.ScriptHash, value, null);
sb.Emit(OpCode.ASSERT);
script = sb.ToArray();
Expand Down Expand Up @@ -721,7 +721,7 @@ public void FeeIsSignatureContract_TestScope_NoScopeFAULT()
using (ScriptBuilder sb = new ScriptBuilder())
{
// self-transfer of 1e-8 GAS
BigInteger value = (new BigDecimal(1, 8)).Value;
BigInteger value = (new BigDecimal(BigInteger.One, 8)).Value;
sb.EmitDynamicCall(NativeContract.GAS.Hash, "transfer", acc.ScriptHash, acc.ScriptHash, value);
sb.Emit(OpCode.ASSERT);
script = sb.ToArray();
Expand Down Expand Up @@ -984,7 +984,7 @@ public void FeeIsSignatureContract_TestScope_FeeOnly_Default()
using (ScriptBuilder sb = new ScriptBuilder())
{
// self-transfer of 1e-8 GAS
BigInteger value = (new BigDecimal(1, 8)).Value;
BigInteger value = (new BigDecimal(BigInteger.One, 8)).Value;
sb.EmitDynamicCall(NativeContract.GAS.Hash, "transfer", acc.ScriptHash, acc.ScriptHash, value, null);
sb.Emit(OpCode.ASSERT);
script = sb.ToArray();
Expand Down Expand Up @@ -1128,7 +1128,7 @@ public void Test_VerifyStateIndependent()
{
AssetId = NativeContract.GAS.Hash,
ScriptHash = acc.ScriptHash,
Value = new BigDecimal(1,8)
Value = new BigDecimal(BigInteger.One,8)
}
}, acc.ScriptHash);

Expand Down Expand Up @@ -1201,7 +1201,7 @@ public void Test_VerifyStateDependent()
{
AssetId = NativeContract.GAS.Hash,
ScriptHash = acc.ScriptHash,
Value = new BigDecimal(1,8)
Value = new BigDecimal(BigInteger.One,8)
}
}, acc.ScriptHash);

Expand Down Expand Up @@ -1271,7 +1271,7 @@ public void Test_Verify()
{
AssetId = NativeContract.GAS.Hash,
ScriptHash = acc.ScriptHash,
Value = new BigDecimal(1,8)
Value = new BigDecimal(BigInteger.One,8)
}
}, acc.ScriptHash);

Expand Down
14 changes: 7 additions & 7 deletions tests/neo.UnitTests/UT_BigDecimal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,23 @@ public void TestBigDecimalConstructor()
value.Value.Should().Be(new BigInteger(-10));
value.Decimals.Should().Be(0);

value = new BigDecimal(123.456789M);
value = new BigDecimal(123.456789M, 6);
value.Value.Should().Be(new BigInteger(123456789));
value.Decimals.Should().Be(6);

value = new BigDecimal(-123.45M);
value.Value.Should().Be(new BigInteger(-12345));
value.Decimals.Should().Be(2);
value = new BigDecimal(-123.45M, 3);
value.Value.Should().Be(new BigInteger(-123450));
value.Decimals.Should().Be(3);

value = new BigDecimal(123.45M);
value = new BigDecimal(123.45M, 2);
value.Value.Should().Be(new BigInteger(12345));
value.Decimals.Should().Be(2);

value = new BigDecimal(123M);
value = new BigDecimal(123M, 0);
value.Value.Should().Be(new BigInteger(123));
value.Decimals.Should().Be(0);

value = new BigDecimal(0M);
value = new BigDecimal(0M, 0);
value.Value.Should().Be(new BigInteger(0));
value.Decimals.Should().Be(0);
}
Expand Down
17 changes: 9 additions & 8 deletions tests/neo.UnitTests/Wallets/UT_Wallet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using Neo.Wallets;
using System;
using System.Collections.Generic;
using System.Numerics;

namespace Neo.UnitTests.Wallets
{
Expand Down Expand Up @@ -206,7 +207,7 @@ public void TestGetAvailable()
entry.GetInteroperable<AccountState>().Balance = 10000 * NativeContract.GAS.Factor;
snapshot.Commit();

wallet.GetAvailable(NativeContract.GAS.Hash).Should().Be(new BigDecimal(1000000000000, 8));
wallet.GetAvailable(NativeContract.GAS.Hash).Should().Be(new BigDecimal(new BigInteger(1000000000000M), 8));

entry = snapshot.GetAndChange(key, () => new StorageItem(new AccountState()));
entry.GetInteroperable<AccountState>().Balance = 0;
Expand All @@ -228,8 +229,8 @@ public void TestGetBalance()
entry.GetInteroperable<AccountState>().Balance = 10000 * NativeContract.GAS.Factor;
snapshot.Commit();

wallet.GetBalance(UInt160.Zero, new UInt160[] { account.ScriptHash }).Should().Be(new BigDecimal(0, 0));
wallet.GetBalance(NativeContract.GAS.Hash, new UInt160[] { account.ScriptHash }).Should().Be(new BigDecimal(1000000000000, 8));
wallet.GetBalance(UInt160.Zero, new UInt160[] { account.ScriptHash }).Should().Be(new BigDecimal(BigInteger.Zero, 0));
wallet.GetBalance(NativeContract.GAS.Hash, new UInt160[] { account.ScriptHash }).Should().Be(new BigDecimal(new BigInteger(1000000000000M), 8));

entry = snapshot.GetAndChange(key, () => new StorageItem(new AccountState()));
entry.GetInteroperable<AccountState>().Balance = 0;
Expand Down Expand Up @@ -294,7 +295,7 @@ public void TestMakeTransaction1()
{
AssetId = NativeContract.GAS.Hash,
ScriptHash = account.ScriptHash,
Value = new BigDecimal(1,8),
Value = new BigDecimal(BigInteger.One,8),
Data = "Dec 12th"
}
}, UInt160.Zero);
Expand All @@ -306,7 +307,7 @@ public void TestMakeTransaction1()
{
AssetId = NativeContract.GAS.Hash,
ScriptHash = account.ScriptHash,
Value = new BigDecimal(1,8),
Value = new BigDecimal(BigInteger.One,8),
Data = "Dec 12th"
}
}, account.ScriptHash);
Expand All @@ -318,7 +319,7 @@ public void TestMakeTransaction1()
{
AssetId = UInt160.Zero,
ScriptHash = account.ScriptHash,
Value = new BigDecimal(1,8),
Value = new BigDecimal(BigInteger.One,8),
Data = "Dec 12th"
}
}, account.ScriptHash);
Expand All @@ -342,7 +343,7 @@ public void TestMakeTransaction1()
{
AssetId = NativeContract.GAS.Hash,
ScriptHash = account.ScriptHash,
Value = new BigDecimal(1,8)
Value = new BigDecimal(BigInteger.One,8)
}
});
tx.Should().NotBeNull();
Expand All @@ -353,7 +354,7 @@ public void TestMakeTransaction1()
{
AssetId = NativeContract.NEO.Hash,
ScriptHash = account.ScriptHash,
Value = new BigDecimal(1,8),
Value = new BigDecimal(BigInteger.One,8),
Data = "Dec 12th"
}
});
Expand Down