diff --git a/ProjectPlugins/CodexClient/MarketplaceTypes.cs b/ProjectPlugins/CodexClient/MarketplaceTypes.cs index b9f80228..39a0fc31 100644 --- a/ProjectPlugins/CodexClient/MarketplaceTypes.cs +++ b/ProjectPlugins/CodexClient/MarketplaceTypes.cs @@ -10,7 +10,7 @@ namespace CodexClient ContentId = cid; } - public ContentId ContentId { get; set; } + public ContentId ContentId { get; } public TestToken PricePerBytePerSecond { get; set; } = 1.TstWei(); public TestToken CollateralPerByte { get; set; } = 1.TstWei(); public uint MinRequiredNumberOfNodes { get; set; } diff --git a/Tests/CodexReleaseTests/DataTests/DecodeTest.cs b/Tests/CodexReleaseTests/DataTests/DecodeTest.cs new file mode 100644 index 00000000..d6f35732 --- /dev/null +++ b/Tests/CodexReleaseTests/DataTests/DecodeTest.cs @@ -0,0 +1,47 @@ +using System.Security.Cryptography; +using CodexReleaseTests.MarketTests; +using Nethereum.JsonRpc.Client; +using NUnit.Framework; +using Utils; + +namespace CodexReleaseTests.DataTests +{ + public class DecodeTest : MarketplaceAutoBootstrapDistTest + { + protected override int NumberOfHosts => 0; + protected override int NumberOfClients => 2; + protected override ByteSize HostAvailabilitySize => 0.Bytes(); + protected override TimeSpan HostAvailabilityMaxDuration => TimeSpan.FromSeconds(0.0); + + [Test] + public void DecodeDataset() + { + var clients = StartClients(); + + var file = GenerateTestFile(10.MB()); + var bCid = clients[0].UploadFile(file); + var request = clients[0].Marketplace.RequestStorage(new CodexClient.StoragePurchaseRequest(bCid) + { + Expiry = TimeSpan.FromMinutes(5.0), + Duration = TimeSpan.FromMinutes(100.0), + CollateralPerByte = 100.Tst(), + MinRequiredNumberOfNodes = 6, + NodeFailureTolerance = 3, + PricePerBytePerSecond = 100.Tst(), + ProofProbability = 20 + }); + var eCid = request.ContentId; + + Assert.That(bCid.Id, Is.Not.EqualTo(eCid.Id)); + + var basic = clients[0].DownloadManifestOnly(bCid); + var encoded = clients[0].DownloadManifestOnly(eCid); + Assert.That(basic.Manifest.Protected, Is.False); + Assert.That(encoded.Manifest.Protected, Is.True); + + var decoded = clients[1].DownloadContent(eCid); + + file.AssertIsEqual(decoded); + } + } +} diff --git a/Tools/AutoClient/Modes/FolderStore/FileSaver.cs b/Tools/AutoClient/Modes/FolderStore/FileSaver.cs index 733044d2..f45e7eb9 100644 --- a/Tools/AutoClient/Modes/FolderStore/FileSaver.cs +++ b/Tools/AutoClient/Modes/FolderStore/FileSaver.cs @@ -114,7 +114,16 @@ namespace AutoClient.Modes.FolderStore if (isFound) { Log("BasicCid found in local files."); - return true; + + if (IsCidBasic(entry.BasicCid)) + { + Log("BasicCid is confirmed to not be encoded."); + return true; + } + + entry.BasicCid = string.Empty; + Log("Warning: Cid stored as basic was actually encoded!"); + return false; } } catch (Exception exc) @@ -181,6 +190,13 @@ namespace AutoClient.Modes.FolderStore entry.EncodedCid = request.Purchase.ContentId.Id; entry.PurchaseId = request.PurchaseId; entry.PurchaseFinishedUtc = DateTime.UtcNow + request.Purchase.Duration; + + if (!IsCidEncoded(entry.EncodedCid)) + { + log.Error("CID received from storage request is not protected/encoded."); + throw new Exception("CID received from storage request was not protected."); + } + saveChanges(); Log("Saved new purchaseId: " + entry.PurchaseId); return request; @@ -257,6 +273,39 @@ namespace AutoClient.Modes.FolderStore } } + private bool IsCidEncoded(string cid) + { + try + { + return GetManifestIsProtected(cid); + } + catch (Exception ex) + { + log.Error(nameof(IsCidEncoded) + ": " + ex); + return false; + } + } + + private bool IsCidBasic(string cid) + { + try + { + return !GetManifestIsProtected(cid); + } + catch (Exception ex) + { + log.Error(nameof(IsCidBasic) + ": " + ex); + return false; + } + } + + private bool GetManifestIsProtected(string cid) + { + var id = new ContentId(cid); + var manifest = instance.Node.DownloadManifestOnly(id); + return manifest.Manifest.Protected; + } + private void Log(string msg) { log.Log(msg);