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 }