diff --git a/ProjectPlugins/CodexClient/StoragePurchaseContract.cs b/ProjectPlugins/CodexClient/StoragePurchaseContract.cs
index 4d9baf54..b0dde5ba 100644
--- a/ProjectPlugins/CodexClient/StoragePurchaseContract.cs
+++ b/ProjectPlugins/CodexClient/StoragePurchaseContract.cs
@@ -143,7 +143,7 @@ namespace CodexClient
private void LogSubmittedDuration()
{
Log($"Pending to Submitted in {Time.FormatDuration(PendingToSubmitted)} " +
- $"( < {Time.FormatDuration(gracePeriod)})");
+ $"( < {Time.FormatDuration(Purchase.Expiry + gracePeriod)})");
}
private void LogStartedDuration()
diff --git a/Tools/AutoClient/AutoClient.csproj b/Tools/AutoClient/AutoClient.csproj
index 362698f9..bbe873f1 100644
--- a/Tools/AutoClient/AutoClient.csproj
+++ b/Tools/AutoClient/AutoClient.csproj
@@ -9,6 +9,7 @@
+
diff --git a/Tools/AutoClient/Configuration.cs b/Tools/AutoClient/Configuration.cs
index 3638665c..edb0c658 100644
--- a/Tools/AutoClient/Configuration.cs
+++ b/Tools/AutoClient/Configuration.cs
@@ -41,6 +41,9 @@ namespace AutoClient
[Uniform("folderToStore", "fts", "FOLDERTOSTORE", false, "When set, autoclient will attempt to upload and purchase storage for every non-JSON file in the provided folder.")]
public string FolderToStore { get; set; } = "/data/EthereumMainnetPreMergeEraFiles";
+ [Uniform("ethAddressFile", "eaf", "ETHADDRESSFILE", false, "File with eth address used by codex node. Used for balance checking if geth/contracts information is provided.")]
+ public string EthAddressFile { get; set; } = "/root/codex-testnet-starter/scripts/eth.address";
+
public string LogPath
{
get
diff --git a/Tools/AutoClient/Modes/FolderStore/BalanceChecker.cs b/Tools/AutoClient/Modes/FolderStore/BalanceChecker.cs
new file mode 100644
index 00000000..895651ae
--- /dev/null
+++ b/Tools/AutoClient/Modes/FolderStore/BalanceChecker.cs
@@ -0,0 +1,113 @@
+using GethConnector;
+using Logging;
+using Utils;
+
+namespace AutoClient.Modes.FolderStore
+{
+ public class BalanceChecker
+ {
+ private readonly LogPrefixer log;
+ private readonly GethConnector.GethConnector? connector;
+ private readonly EthAddress? address;
+
+ public BalanceChecker(App app)
+ {
+ log = new LogPrefixer(app.Log, "(Balance) ");
+
+ connector = GethConnector.GethConnector.Initialize(app.Log);
+ address = LoadAddress(app);
+ }
+
+ private EthAddress? LoadAddress(App app)
+ {
+ try
+ {
+ if (string.IsNullOrEmpty(app.Config.EthAddressFile)) return null;
+ if (!File.Exists(app.Config.EthAddressFile)) return null;
+
+ return new EthAddress(
+ File.ReadAllText(app.Config.EthAddressFile)
+ .Trim()
+ .Replace("\n", "")
+ .Replace(Environment.NewLine, "")
+ );
+ }
+ catch (Exception exc)
+ {
+ log.Error($"Failed to load eth address from file: {exc}");
+ return null;
+ }
+ }
+
+ public void Check()
+ {
+ if (connector == null)
+ {
+ Log("Connector not configured. Can't check balances.");
+ return;
+ }
+ if (address == null)
+ {
+ Log("EthAddress not found. Can't check balances.");
+ return;
+ }
+
+ try
+ {
+ PerformCheck();
+ }
+ catch (Exception exc)
+ {
+ Log($"Exception while checking balances: {exc}");
+ }
+ }
+
+ private void PerformCheck()
+ {
+ var geth = connector!.GethNode;
+ var contracts = connector!.CodexContracts;
+ var addr = address!;
+
+ var eth = geth.GetEthBalance(addr);
+ var tst = contracts.GetTestTokenBalance(addr);
+
+ Log($"Balances: [{eth}] - [{tst}]");
+
+ if (eth.Eth < 1) TryAddEth(geth, addr);
+ if (tst.Tst < 1) TryAddTst(contracts, addr);
+ }
+
+ private void TryAddEth(GethPlugin.IGethNode geth, EthAddress addr)
+ {
+ try
+ {
+ var amount = 100.Eth();
+ var result = geth.SendEth(addr, amount);
+ Log($"Successfull added {amount} - {result}");
+ }
+ catch (Exception exc)
+ {
+ Log("Failed to add eth: " + exc);
+ }
+ }
+
+ private void TryAddTst(CodexContractsPlugin.ICodexContracts contracts, EthAddress addr)
+ {
+ try
+ {
+ var amount = 100.Tst();
+ var result = contracts.MintTestTokens(addr, amount);
+ Log($"Successfull added {amount} - {result}");
+ }
+ catch (Exception exc)
+ {
+ Log("Failed to add testtokens: " + exc);
+ }
+ }
+
+ private void Log(string msg)
+ {
+ log.Log(msg);
+ }
+ }
+}
diff --git a/Tools/AutoClient/Modes/FolderStore/FolderSaver.cs b/Tools/AutoClient/Modes/FolderStore/FolderSaver.cs
index 517120f5..5c22aa8d 100644
--- a/Tools/AutoClient/Modes/FolderStore/FolderSaver.cs
+++ b/Tools/AutoClient/Modes/FolderStore/FolderSaver.cs
@@ -9,6 +9,7 @@ namespace AutoClient.Modes.FolderStore
private readonly CodexWrapper instance;
private readonly JsonFile statusFile;
private readonly FolderStatus status;
+ private readonly BalanceChecker balanceChecker;
private int changeCounter = 0;
private int failureCount = 0;
@@ -16,6 +17,7 @@ namespace AutoClient.Modes.FolderStore
{
this.app = app;
this.instance = instance;
+ balanceChecker = new BalanceChecker(app);
statusFile = new JsonFile(app, Path.Combine(app.Config.FolderToStore, FolderSaverFilename));
status = statusFile.Load();
@@ -27,6 +29,7 @@ namespace AutoClient.Modes.FolderStore
if (!folderFiles.Any()) throw new Exception("No files found in " + app.Config.FolderToStore);
changeCounter = 0;
+ balanceChecker.Check();
foreach (var folderFile in folderFiles)
{
if (cts.IsCancellationRequested) return;
@@ -46,6 +49,7 @@ namespace AutoClient.Modes.FolderStore
if (changeCounter > 5)
{
changeCounter = 0;
+ balanceChecker.Check();
SaveFolderSaverJsonFile();
}