Mapper.cs
  1  using Newtonsoft.Json.Linq;
  2  using System.Numerics;
  3  using Utils;
  4  
  5  namespace CodexClient
  6  {
  7      public class Mapper
  8      {
  9          public DebugInfo Map(CodexOpenApi.DebugInfo debugInfo)
 10          {
 11              return new DebugInfo
 12              {
 13                  Id = debugInfo.Id,
 14                  Spr = debugInfo.Spr,
 15                  Addrs = debugInfo.Addrs.ToArray(),
 16                  AnnounceAddresses = debugInfo.AnnounceAddresses.ToArray(),
 17                  Version = Map(debugInfo.Codex),
 18                  Table = Map(debugInfo.Table)
 19              };
 20          }
 21  
 22          public LocalDatasetList Map(CodexOpenApi.DataList dataList)
 23          {
 24              return new LocalDatasetList
 25              {
 26                  Content = dataList.Content.Select(Map).ToArray()
 27              };
 28          }
 29  
 30          public LocalDataset Map(CodexOpenApi.DataItem dataItem)
 31          {
 32              return new LocalDataset
 33              {
 34                  Cid = new ContentId(dataItem.Cid),
 35                  Manifest = MapManifest(dataItem.Manifest)
 36              };
 37          }
 38  
 39          public CodexOpenApi.SalesAvailability Map(CreateStorageAvailability availability)
 40          {
 41              return new CodexOpenApi.SalesAvailability
 42              {
 43                  Duration = ToLong(availability.MaxDuration.TotalSeconds),
 44                  MinPricePerBytePerSecond = ToDecInt(availability.MinPricePerBytePerSecond),
 45                  TotalCollateral = ToDecInt(availability.TotalCollateral),
 46                  TotalSize = availability.TotalSpace.SizeInBytes
 47              };
 48          }
 49  
 50          public CodexOpenApi.StorageRequestCreation Map(StoragePurchaseRequest purchase)
 51          {
 52              return new CodexOpenApi.StorageRequestCreation
 53              {
 54                  Duration = ToLong(purchase.Duration.TotalSeconds),
 55                  ProofProbability = ToDecInt(purchase.ProofProbability),
 56                  PricePerBytePerSecond = ToDecInt(purchase.PricePerBytePerSecond),
 57                  CollateralPerByte = ToDecInt(purchase.CollateralPerByte),
 58                  Expiry = ToLong(purchase.Expiry.TotalSeconds),
 59                  Nodes = Convert.ToInt32(purchase.MinRequiredNumberOfNodes),
 60                  Tolerance = Convert.ToInt32(purchase.NodeFailureTolerance)
 61              };
 62          }
 63  
 64          public StorageAvailability[] Map(ICollection<CodexOpenApi.SalesAvailabilityREAD> availabilities)
 65          {
 66              return availabilities.Select(a => Map(a)).ToArray();
 67          }
 68  
 69          public StorageAvailability Map(CodexOpenApi.SalesAvailabilityREAD availability)
 70          {
 71              return new StorageAvailability
 72              (
 73                  availability.Id,
 74                  ToByteSize(availability.TotalSize),
 75                  ToTimespan(availability.Duration),
 76                  new TestToken(ToBigInt(availability.MinPricePerBytePerSecond)),
 77                  new TestToken(ToBigInt(availability.TotalCollateral)),
 78                  ToByteSize(availability.FreeSize)
 79              );
 80          }
 81  
 82          public StoragePurchase Map(CodexOpenApi.Purchase purchase)
 83          {
 84              return new StoragePurchase
 85              {
 86                  Request = Map(purchase.Request),
 87                  State = Map(purchase.State),
 88                  Error = purchase.Error
 89              };
 90          }
 91  
 92          public StoragePurchaseState Map(CodexOpenApi.PurchaseState purchaseState)
 93          {
 94              // Explicit mapping: If the API changes, we will get compile errors here.
 95              // That's what we want.
 96              switch (purchaseState)
 97              {
 98                  case CodexOpenApi.PurchaseState.Cancelled:
 99                      return StoragePurchaseState.Cancelled;
100                  case CodexOpenApi.PurchaseState.Errored:
101                      return StoragePurchaseState.Errored;
102                  case CodexOpenApi.PurchaseState.Failed:
103                      return StoragePurchaseState.Failed;
104                  case CodexOpenApi.PurchaseState.Finished:
105                      return StoragePurchaseState.Finished;
106                  case CodexOpenApi.PurchaseState.Pending:
107                      return StoragePurchaseState.Pending;
108                  case CodexOpenApi.PurchaseState.Started:
109                      return StoragePurchaseState.Started;
110                  case CodexOpenApi.PurchaseState.Submitted:
111                      return StoragePurchaseState.Submitted;
112                  case CodexOpenApi.PurchaseState.Unknown:
113                      return StoragePurchaseState.Unknown;
114              }
115  
116              throw new Exception("API incompatibility detected. Unknown purchaseState: " + purchaseState.ToString());
117          }
118  
119          public StorageRequest Map(CodexOpenApi.StorageRequest request)
120          {
121              return new StorageRequest
122              {
123                  Ask = Map(request.Ask),
124                  Content = Map(request.Content),
125                  Id = request.Id,
126                  Client = request.Client,
127                  Expiry = request.Expiry,
128                  Nonce = request.Nonce
129              };
130          }
131  
132          public StorageAsk Map(CodexOpenApi.StorageAsk ask)
133          {
134              return new StorageAsk
135              {
136                  Duration = ask.Duration,
137                  MaxSlotLoss = ask.MaxSlotLoss,
138                  ProofProbability = ask.ProofProbability,
139                  PricePerBytePerSecond = ask.PricePerBytePerSecond,
140                  Slots = ask.Slots,
141                  SlotSize = ask.SlotSize
142              };
143          }
144  
145          public StorageContent Map(CodexOpenApi.Content content)
146          {
147              return new StorageContent
148              {
149                  Cid = content.Cid
150              };
151          }
152  
153          public CodexSpace Map(CodexOpenApi.Space space)
154          {
155              return new CodexSpace
156              {
157                  QuotaMaxBytes = space.QuotaMaxBytes,
158                  QuotaReservedBytes = space.QuotaReservedBytes,
159                  QuotaUsedBytes = space.QuotaUsedBytes,
160                  TotalBlocks = space.TotalBlocks
161              };
162          }
163  
164          private DebugInfoVersion Map(CodexOpenApi.CodexVersion obj)
165          {
166              return new DebugInfoVersion
167              {
168                  Version = obj.Version,
169                  Revision = obj.Revision,
170                  Contracts = obj.Contracts
171              };
172          }
173  
174          private DebugInfoTable Map(CodexOpenApi.PeersTable obj)
175          {
176              return new DebugInfoTable
177              {
178                  LocalNode = Map(obj.LocalNode),
179                  Nodes = Map(obj.Nodes)
180              };
181          }
182  
183          private DebugInfoTableNode Map(CodexOpenApi.Node? token)
184          {
185              if (token == null) return new DebugInfoTableNode();
186              return new DebugInfoTableNode
187              {
188                  Address = token.Address,
189                  NodeId = token.NodeId,
190                  PeerId = token.PeerId,
191                  Record = token.Record,
192                  Seen = token.Seen
193              };
194          }
195  
196          private DebugInfoTableNode[] Map(ICollection<CodexOpenApi.Node> nodes)
197          {
198              if (nodes == null || nodes.Count == 0)
199              {
200                  return new DebugInfoTableNode[0];
201              }
202  
203              return nodes.Select(Map).ToArray();
204          }
205  
206          private Manifest MapManifest(CodexOpenApi.ManifestItem manifest)
207          {
208              return new Manifest
209              {
210                  BlockSize = new ByteSize(Convert.ToInt64(manifest.BlockSize)),
211                  DatasetSize = new ByteSize(Convert.ToInt64(manifest.DatasetSize)),
212                  RootHash = manifest.TreeCid,
213                  Protected = manifest.Protected
214              };
215          }
216  
217          private JArray JArray(IDictionary<string, object> map, string name)
218          {
219              return (JArray)map[name];
220          }
221  
222          private JObject JObject(IDictionary<string, object> map, string name)
223          {
224              return (JObject)map[name];
225          }
226  
227          private string StringOrEmpty(JObject obj, string name)
228          {
229              if (obj.TryGetValue(name, out var token))
230              {
231                  var str = (string?)token;
232                  if (!string.IsNullOrEmpty(str)) return str;
233              }
234              return string.Empty;
235          }
236  
237          private bool Bool(JObject obj, string name)
238          {
239              if (obj.TryGetValue(name, out var token))
240              {
241                  return (bool)token;
242              }
243              return false;
244          }
245  
246          private string ToDecInt(double d)
247          {
248              var i = new BigInteger(d);
249              return i.ToString("D");
250          }
251  
252          private string ToDecInt(TestToken t)
253          {
254              return t.TstWei.ToString("D");
255          }
256  
257          private TestToken ToTestToken(string s)
258          {
259              return new TestToken(ToBigInt(s));
260          }
261  
262          private long ToLong(double value)
263          {
264              return Convert.ToInt64(value);
265          }
266  
267          private BigInteger ToBigInt(string tokens)
268          {
269              return BigInteger.Parse(tokens);
270          }
271  
272          private TimeSpan ToTimespan(long duration)
273          {
274              return TimeSpan.FromSeconds(duration);
275          }
276  
277          private ByteSize ToByteSize(long size)
278          {
279              return new ByteSize(size);
280          }
281      }
282  }