Merge branch 'master' into feature/rewardbot-tests

# Conflicts:
#	Tests/CodexTests/UtilityTests/DiscordBotTests.cs
This commit is contained in:
Ben 2024-05-22 11:11:47 +02:00
commit b1818400ca
No known key found for this signature in database
GPG Key ID: 541B9D8C9F1426A1
17 changed files with 164 additions and 48 deletions

View File

@ -1,4 +1,5 @@
using System.Globalization;
using System.Numerics;
using System.Reflection;
namespace ArgsUniform
@ -105,6 +106,7 @@ namespace ArgsUniform
if (uniformProperty.PropertyType.IsEnum) return AssignEnum(result, uniformProperty, value);
if (uniformProperty.PropertyType == typeof(bool)) return AssignBool(result, uniformProperty, value);
if (uniformProperty.PropertyType == typeof(ulong)) return AssignUlong(result, uniformProperty, value);
if (uniformProperty.PropertyType == typeof(BigInteger)) return AssignBigInt(result, uniformProperty, value);
throw new NotSupportedException(
$"Unsupported property type '${uniformProperty.PropertyType}' " +
@ -144,6 +146,16 @@ namespace ArgsUniform
return false;
}
private bool AssignBigInt(T result, PropertyInfo uniformProperty, object value)
{
if (BigInteger.TryParse(value.ToString(), CultureInfo.InvariantCulture, out BigInteger i))
{
uniformProperty.SetValue(result, i);
return true;
}
return false;
}
private static bool AssignBool(T result, PropertyInfo uniformProperty, object value)
{
var s = value.ToString();

View File

@ -67,7 +67,7 @@ namespace CodexContractsPlugin
public string MintTestTokens(EthAddress ethAddress, TestToken testTokens)
{
return StartInteraction().MintTestTokens(ethAddress, testTokens.Amount, Deployment.TokenAddress);
return StartInteraction().MintTestTokens(ethAddress, testTokens.TstWei, Deployment.TokenAddress);
}
public TestToken GetTestTokenBalance(IHasEthAddress owner)
@ -78,7 +78,7 @@ namespace CodexContractsPlugin
public TestToken GetTestTokenBalance(EthAddress ethAddress)
{
var balance = StartInteraction().GetBalance(Deployment.TokenAddress, ethAddress.Address);
return balance.TestTokens();
return balance.TstWei();
}
public Request[] GetStorageRequests(BlockInterval blockRange)

View File

@ -44,7 +44,7 @@ namespace CodexContractsPlugin
}
}
public string MintTestTokens(EthAddress address, decimal amount, string tokenAddress)
public string MintTestTokens(EthAddress address, BigInteger amount, string tokenAddress)
{
log.Debug($"{amount} -> {address} (token: {tokenAddress})");
return MintTokens(address.Address, amount, tokenAddress);
@ -85,7 +85,7 @@ namespace CodexContractsPlugin
}
}
private string MintTokens(string account, decimal amount, string tokenAddress)
private string MintTokens(string account, BigInteger amount, string tokenAddress)
{
log.Debug($"({tokenAddress}) {amount} --> {account}");
if (string.IsNullOrEmpty(account)) throw new ArgumentException("Invalid arguments for MintTestTokens");
@ -93,7 +93,7 @@ namespace CodexContractsPlugin
var function = new MintTokensFunction
{
Holder = account,
Amount = amount.ToBig()
Amount = amount
};
return gethNode.SendTransaction(tokenAddress, function);

View File

@ -1,45 +1,102 @@
namespace CodexContractsPlugin
using System.Numerics;
namespace CodexContractsPlugin
{
public class TestToken : IComparable<TestToken>
{
public TestToken(decimal amount)
public static BigInteger WeiFactor = new BigInteger(1000000000000000000);
public TestToken(BigInteger tstWei)
{
Amount = amount;
TstWei = tstWei;
Tst = tstWei / WeiFactor;
}
public decimal Amount { get; }
public BigInteger TstWei { get; }
public BigInteger Tst { get; }
public int CompareTo(TestToken? other)
{
return Amount.CompareTo(other!.Amount);
return TstWei.CompareTo(other!.TstWei);
}
public override bool Equals(object? obj)
{
return obj is TestToken token && Amount == token.Amount;
return obj is TestToken token && TstWei == token.TstWei;
}
public override int GetHashCode()
{
return HashCode.Combine(Amount);
return HashCode.Combine(TstWei);
}
public override string ToString()
{
return $"{Amount} TestTokens";
var weiOnly = TstWei % WeiFactor;
var tokens = new List<string>();
if (Tst > 0) tokens.Add($"{Tst} TST");
if (weiOnly > 0) tokens.Add($"{weiOnly} TSTWEI");
return string.Join(" + ", tokens);
}
public static TestToken operator +(TestToken a, TestToken b)
{
return new TestToken(a.TstWei + b.TstWei);
}
public static bool operator <(TestToken a, TestToken b)
{
return a.TstWei < b.TstWei;
}
public static bool operator >(TestToken a, TestToken b)
{
return a.TstWei > b.TstWei;
}
public static bool operator ==(TestToken a, TestToken b)
{
return a.TstWei == b.TstWei;
}
public static bool operator !=(TestToken a, TestToken b)
{
return a.TstWei != b.TstWei;
}
}
public static class TokensIntExtensions
public static class TestTokensExtensions
{
public static TestToken TestTokens(this int i)
public static TestToken TstWei(this int i)
{
return TestTokens(Convert.ToDecimal(i));
return TstWei(Convert.ToDecimal(i));
}
public static TestToken TestTokens(this decimal i)
public static TestToken TstWei(this decimal i)
{
return new TestToken(new BigInteger(i));
}
public static TestToken TstWei(this BigInteger i)
{
return new TestToken(i);
}
public static TestToken Tst(this int i)
{
return Tst(Convert.ToDecimal(i));
}
public static TestToken Tst(this decimal i)
{
return new TestToken(new BigInteger(i) * TestToken.WeiFactor);
}
public static TestToken Tst(this BigInteger i)
{
return new TestToken(i * TestToken.WeiFactor);
}
}
}

View File

@ -168,7 +168,7 @@ namespace CodexPlugin
public bool IsStorageNode { get; private set; }
public bool IsValidator { get; private set; }
public Ether InitialEth { get; private set; } = 0.Eth();
public TestToken InitialTestTokens { get; private set; } = 0.TestTokens();
public TestToken InitialTestTokens { get; private set; } = 0.Tst();
public EthAccount EthAccount { get; private set; } = EthAccount.GenerateNew();
public IMarketplaceSetup AsStorageNode()
@ -202,7 +202,7 @@ namespace CodexPlugin
result += IsStorageNode ? "(storageNode)" : "()";
result += IsValidator ? "(validator)" : "() ";
result += $"Address: '{EthAccount.EthAddress}' ";
result += $"InitialEth/TT({InitialEth.Eth}/{InitialTestTokens.Amount})";
result += $"{InitialEth.Eth} / {InitialTestTokens}";
result += "] ";
return result;
}

View File

@ -74,10 +74,10 @@ namespace CodexPlugin
public StorageAvailability Map(CodexOpenApi.SalesAvailabilityREAD read)
{
return new StorageAvailability(
totalSpace: new Utils.ByteSize(Convert.ToInt64(read.TotalSize)),
totalSpace: new ByteSize(Convert.ToInt64(read.TotalSize)),
maxDuration: TimeSpan.FromSeconds(Convert.ToDouble(read.Duration)),
minPriceForTotalSpace: new TestToken(Convert.ToDecimal(read.MinPrice)),
maxCollateral: new TestToken(Convert.ToDecimal(read.MaxCollateral))
minPriceForTotalSpace: new TestToken(BigInteger.Parse(read.MinPrice)),
maxCollateral: new TestToken(BigInteger.Parse(read.MaxCollateral))
)
{
Id = read.Id
@ -165,8 +165,7 @@ namespace CodexPlugin
private string ToDecInt(TestToken t)
{
var i = new BigInteger(t.Amount);
return i.ToString("D");
return t.TstWei.ToString("D");
}
}
}

View File

@ -12,8 +12,8 @@ namespace CodexPlugin
}
public ContentId ContentId { get; set; }
public TestToken PricePerSlotPerSecond { get; set; } = 1.TestTokens();
public TestToken RequiredCollateral { get; set; } = 1.TestTokens();
public TestToken PricePerSlotPerSecond { get; set; } = 1.TstWei();
public TestToken RequiredCollateral { get; set; } = 1.TstWei();
public uint MinRequiredNumberOfNodes { get; set; }
public uint NodeFailureTolerance { get; set; }
public int ProofProbability { get; set; }

View File

@ -13,8 +13,8 @@ namespace CodexTests.BasicTests
[Test]
public void MarketplaceExample()
{
var hostInitialBalance = 234.TestTokens();
var clientInitialBalance = 100000.TestTokens();
var hostInitialBalance = 234.TstWei();
var clientInitialBalance = 100000.TstWei();
var fileSize = 10.MB();
var geth = Ci.StartGethNode(s => s.IsMiner().WithName("disttest-geth"));
@ -33,7 +33,7 @@ namespace CodexTests.BasicTests
.AsStorageNode()
.AsValidator()));
var expectedHostBalance = (numberOfHosts * hostInitialBalance.Amount).TestTokens();
var expectedHostBalance = (numberOfHosts * hostInitialBalance.TstWei).TstWei();
foreach (var host in hosts)
{
AssertBalance(contracts, host, Is.EqualTo(expectedHostBalance));
@ -41,8 +41,8 @@ namespace CodexTests.BasicTests
var availability = new StorageAvailability(
totalSpace: 10.GB(),
maxDuration: TimeSpan.FromMinutes(30),
minPriceForTotalSpace: 1.TestTokens(),
maxCollateral: 20.TestTokens()
minPriceForTotalSpace: 1.TstWei(),
maxCollateral: 20.TstWei()
);
host.Marketplace.MakeStorageAvailable(availability);
}
@ -60,8 +60,8 @@ namespace CodexTests.BasicTests
var purchase = new StoragePurchaseRequest(contentId)
{
PricePerSlotPerSecond = 2.TestTokens(),
RequiredCollateral = 10.TestTokens(),
PricePerSlotPerSecond = 2.TstWei(),
RequiredCollateral = 10.TstWei(),
MinRequiredNumberOfNodes = 5,
NodeFailureTolerance = 2,
ProofProbability = 5,

View File

@ -22,7 +22,7 @@ namespace CodexTests.DownloadConnectivityTests
var geth = Ci.StartGethNode(s => s.IsMiner());
var contracts = Ci.StartCodexContracts(geth);
StartCodex(2, s => s.EnableMarketplace(geth, contracts, m => m
.WithInitial(10.Eth(), 1000.TestTokens())));
.WithInitial(10.Eth(), 1000.TstWei())));
AssertAllNodesConnected();
}

View File

@ -32,7 +32,7 @@ namespace CodexTests.PeerDiscoveryTests
var geth = Ci.StartGethNode(s => s.IsMiner());
var contracts = Ci.StartCodexContracts(geth);
StartCodex(2, s => s.EnableMarketplace(geth, contracts, m => m
.WithInitial(10.Eth(), 1000.TestTokens())));
.WithInitial(10.Eth(), 1000.TstWei())));
AssertAllNodesConnected();
}

View File

@ -15,8 +15,8 @@ namespace CodexTests.UtilityTests
public class DiscordBotTests : AutoBootstrapDistTest
{
private readonly RewardRepo repo = new RewardRepo();
private readonly TestToken hostInitialBalance = 3000000.TestTokens();
private readonly TestToken clientInitialBalance = 1000000000.TestTokens();
private readonly TestToken hostInitialBalance = 3000000.TstWei();
private readonly TestToken clientInitialBalance = 1000000000.TstWei();
[Test]
public void BotRewardTest()
@ -68,8 +68,8 @@ namespace CodexTests.UtilityTests
var contentId = client.UploadFile(testFile);
var purchase = new StoragePurchaseRequest(contentId)
{
PricePerSlotPerSecond = 2.TestTokens(),
RequiredCollateral = 10.TestTokens(),
PricePerSlotPerSecond = 2.TstWei(),
RequiredCollateral = 10.TstWei(),
MinRequiredNumberOfNodes = GetNumberOfRequiredHosts(),
NodeFailureTolerance = 2,
ProofProbability = 5,
@ -146,7 +146,7 @@ namespace CodexTests.UtilityTests
var availability = new StorageAvailability(
totalSpace: GetFileSizePlus(5),
maxDuration: TimeSpan.FromMinutes(30),
minPriceForTotalSpace: 1.TestTokens(),
minPriceForTotalSpace: 1.TstWei(),
maxCollateral: hostInitialBalance
);

View File

@ -0,0 +1,46 @@
using CodexContractsPlugin;
using NUnit.Framework;
using System.Numerics;
namespace FrameworkTests.CodexContractsPlugin
{
[TestFixture]
public class TestTokenTests
{
private const decimal factor = 1000000000000000000m;
[Test]
public void RepresentsSmallAmount()
{
var t = 10.TstWei();
Assert.That(t.TstWei, Is.EqualTo(new BigInteger(10)));
Assert.That(t.Tst, Is.EqualTo(new BigInteger(0)));
Assert.That(t.ToString(), Is.EqualTo("10 TSTWEI"));
}
[Test]
public void RepresentsLargeAmount()
{
var t = 10.Tst();
var expected = new BigInteger(10 * factor);
Assert.That(t.TstWei, Is.EqualTo(expected));
Assert.That(t.Tst, Is.EqualTo(new BigInteger(10)));
Assert.That(t.ToString(), Is.EqualTo("10 TST"));
}
[Test]
public void RepresentsLongAmount()
{
var a = 10.Tst();
var b = 20.TstWei();
var t = a + b;
var expected = new BigInteger((10 * factor) + 20);
Assert.That(t.TstWei, Is.EqualTo(expected));
Assert.That(t.Tst, Is.EqualTo(new BigInteger(10)));
Assert.That(t.ToString(), Is.EqualTo("10 TST + 20 TSTWEI"));
}
}
}

View File

@ -16,6 +16,7 @@
<ItemGroup>
<ProjectReference Include="..\..\Framework\NethereumWorkflow\NethereumWorkflow.csproj" />
<ProjectReference Include="..\..\Framework\Utils\Utils.csproj" />
<ProjectReference Include="..\..\ProjectPlugins\CodexContractsPlugin\CodexContractsPlugin.csproj" />
</ItemGroup>
</Project>

View File

@ -32,7 +32,7 @@ namespace BiblioTech.Commands
}
var eth = 0.Eth();
var testTokens = 0.TestTokens();
var testTokens = 0.TstWei();
await Task.Run(() =>
{

View File

@ -51,7 +51,7 @@ namespace BiblioTech.Commands
{
if (ShouldMintTestTokens(contracts, addr))
{
var tokens = Program.Config.MintTT.TestTokens();
var tokens = Program.Config.MintTT.TstWei();
var transaction = contracts.MintTestTokens(addr, tokens);
report.Add($"Minted {tokens} {FormatTransactionLink(transaction)}");
return new Transaction<TestToken>(tokens, transaction);
@ -77,7 +77,7 @@ namespace BiblioTech.Commands
private bool ShouldMintTestTokens(ICodexContracts contracts, EthAddress addr)
{
var testTokens = contracts.GetTestTokenBalance(addr);
return testTokens.Amount < Program.Config.MintTT;
return testTokens < Program.Config.MintTT.TstWei();
}
private bool ShouldSendEth(IGethNode gethNode, EthAddress addr)

View File

@ -1,4 +1,5 @@
using ArgsUniform;
using System.Numerics;
namespace BiblioTech
{
@ -31,8 +32,8 @@ namespace BiblioTech
[Uniform("send-eth", "se", "SENDETH", true, "Amount of Eth send by the mint command.")]
public int SendEth { get; set; } = 10;
[Uniform("mint-tt", "mt", "MINTTT", true, "Amount of TestTokens minted by the mint command.")]
public int MintTT { get; set; } = 1073741824;
[Uniform("mint-tt", "mt", "MINTTT", true, "Amount of TSTWEI minted by the mint command.")]
public BigInteger MintTT { get; set; } = 1073741824;
[Uniform("no-discord", "nd", "NODISCORD", false, "For debugging: Bypasses all Discord API calls.")]
public int NoDiscord { get; set; } = 0;

View File

@ -43,7 +43,7 @@ namespace CodexNetDeployer
{
s.EnableMarketplace(gethNode, contracts, m =>
{
m.WithInitial(100.Eth(), config.InitialTestTokens.TestTokens());
m.WithInitial(100.Eth(), config.InitialTestTokens.TstWei());
if (validatorsLeft > 0) m.AsValidator();
if (config.ShouldMakeStorageAvailable) m.AsStorageNode();
});
@ -71,8 +71,8 @@ namespace CodexNetDeployer
var availability = new StorageAvailability(
totalSpace: config.StorageSell!.Value.MB(),
maxDuration: TimeSpan.FromSeconds(config.MaxDuration),
minPriceForTotalSpace: config.MinPrice.TestTokens(),
maxCollateral: config.MaxCollateral.TestTokens()
minPriceForTotalSpace: config.MinPrice.TstWei(),
maxCollateral: config.MaxCollateral.TstWei()
);
var response = codexNode.Marketplace.MakeStorageAvailable(availability);