hippius 0.1.0__tar.gz → 0.1.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hippius
3
- Version: 0.1.0
3
+ Version: 0.1.6
4
4
  Summary: Python SDK and CLI for Hippius blockchain storage
5
5
  Home-page: https://github.com/thenervelab/hippius-sdk
6
6
  Author: Dubs
@@ -23,6 +23,7 @@ Requires-Dist: pyperclip (>=1.8.2,<2.0.0) ; extra == "clipboard"
23
23
  Requires-Dist: python-dotenv (>=1.0.0,<2.0.0)
24
24
  Requires-Dist: requests (>=2.28.1,<3.0.0)
25
25
  Requires-Dist: substrate-interface (>=1.4.2,<2.0.0)
26
+ Requires-Dist: zfec (>=1.5.3,<2.0.0)
26
27
  Project-URL: Documentation, https://github.com/thenervelab/hippius-sdk/docs
27
28
  Project-URL: Repository, https://github.com/thenervelab/hippius-sdk
28
29
  Description-Content-Type: text/markdown
@@ -172,6 +173,104 @@ raw_result = client.download_file(encrypted_result['cid'], "still_encrypted.txt"
172
173
  content = client.cat(encrypted_result['cid'], decrypt=True)
173
174
  ```
174
175
 
176
+ ## Erasure Coding
177
+
178
+ Hippius SDK supports Reed-Solomon erasure coding for reliable and resilient file storage. This allows files to be split into chunks with added redundancy, so that the original file can be reconstructed even if some chunks are lost.
179
+
180
+ ### Erasure Coding Concepts
181
+
182
+ - **k**: The number of data chunks needed to reconstruct the original file
183
+ - **m**: The total number of chunks created (m > k)
184
+ - The file can be reconstructed from any k chunks out of m total chunks
185
+ - Higher redundancy (m-k) provides better protection against chunk loss
186
+
187
+ ### Using Erasure Coding
188
+
189
+ ```python
190
+ from hippius_sdk import HippiusClient
191
+
192
+ client = HippiusClient()
193
+
194
+ # Erasure code a file with default parameters (k=3, m=5)
195
+ result = client.erasure_code_file("large_file.mp4")
196
+ metadata_cid = result["metadata_cid"]
197
+
198
+ # Use custom parameters for more redundancy
199
+ result = client.erasure_code_file(
200
+ file_path="important_data.zip",
201
+ k=4, # Need 4 chunks to reconstruct
202
+ m=10, # Create 10 chunks total (6 redundant)
203
+ chunk_size=2097152, # 2MB chunks
204
+ encrypt=True # Encrypt before splitting
205
+ )
206
+
207
+ # Store erasure-coded file in Hippius marketplace
208
+ result = client.store_erasure_coded_file(
209
+ file_path="critical_backup.tar",
210
+ k=3,
211
+ m=5,
212
+ encrypt=True,
213
+ miner_ids=["miner1", "miner2", "miner3"]
214
+ )
215
+
216
+ # Reconstruct a file from its metadata
217
+ reconstructed_path = client.reconstruct_from_erasure_code(
218
+ metadata_cid=metadata_cid,
219
+ output_file="reconstructed_file.mp4"
220
+ )
221
+ ```
222
+
223
+ ### When to Use Erasure Coding
224
+
225
+ Erasure coding is particularly useful for:
226
+
227
+ - Large files where reliability is critical
228
+ - Long-term archival storage
229
+ - Data that must survive partial network failures
230
+ - Situations where higher redundancy is needed without full replication
231
+
232
+ ### Advanced Features
233
+
234
+ #### Small File Handling
235
+
236
+ The SDK automatically adjusts parameters for small files:
237
+
238
+ - If a file is too small to be split into `k` chunks, the SDK will adjust the chunk size
239
+ - For very small files, the content is split into exactly `k` sub-blocks
240
+ - Parameters are always optimized to provide the requested level of redundancy
241
+
242
+ #### Robust Storage in Marketplace
243
+
244
+ When using `store_erasure_coded_file`, the SDK now:
245
+
246
+ - Stores both the metadata file AND all encoded chunks in the marketplace
247
+ - Ensures miners can access all necessary data for redundancy and retrieval
248
+ - Reports total number of files stored for verification
249
+
250
+ #### CLI Commands
251
+
252
+ The CLI provides powerful commands for erasure coding:
253
+
254
+ ```bash
255
+ # Basic usage with automatic parameter adjustment
256
+ hippius erasure-code myfile.txt
257
+
258
+ # Specify custom parameters
259
+ hippius erasure-code large_video.mp4 --k 4 --m 8 --chunk-size 4194304
260
+
261
+ # For smaller files, using smaller parameters
262
+ hippius erasure-code small_doc.txt --k 2 --m 5 --chunk-size 4096
263
+
264
+ # Reconstruct a file from its metadata CID
265
+ hippius reconstruct QmMetadataCID reconstructed_file.mp4
266
+ ```
267
+
268
+ The CLI provides detailed output during the process, including:
269
+ - Automatic parameter adjustments for optimal encoding
270
+ - Progress of chunk creation and upload
271
+ - Storage confirmation in the marketplace
272
+ - Instructions for reconstruction
273
+
175
274
  ## Command Line Interface
176
275
 
177
276
  The Hippius SDK includes a powerful command-line interface (CLI) that provides access to all major features of the SDK directly from your terminal.
@@ -240,6 +339,19 @@ hippius store my_file.txt --encrypt
240
339
  hippius download QmCID123 output_file.txt --decrypt
241
340
  ```
242
341
 
342
+ ### Erasure Coding
343
+
344
+ ```bash
345
+ # Erasure code a file with default parameters (k=3, m=5)
346
+ hippius erasure-code large_file.mp4
347
+
348
+ # Erasure code with custom parameters
349
+ hippius erasure-code important_data.zip --k 4 --m 10 --chunk-size 2097152 --encrypt
350
+
351
+ # Reconstruct a file from its metadata
352
+ hippius reconstruct QmMetadataCID reconstructed_file.mp4
353
+ ```
354
+
243
355
  ### Using Environment Variables
244
356
 
245
357
  The CLI automatically reads from your `.env` file for common settings:
@@ -143,6 +143,104 @@ raw_result = client.download_file(encrypted_result['cid'], "still_encrypted.txt"
143
143
  content = client.cat(encrypted_result['cid'], decrypt=True)
144
144
  ```
145
145
 
146
+ ## Erasure Coding
147
+
148
+ Hippius SDK supports Reed-Solomon erasure coding for reliable and resilient file storage. This allows files to be split into chunks with added redundancy, so that the original file can be reconstructed even if some chunks are lost.
149
+
150
+ ### Erasure Coding Concepts
151
+
152
+ - **k**: The number of data chunks needed to reconstruct the original file
153
+ - **m**: The total number of chunks created (m > k)
154
+ - The file can be reconstructed from any k chunks out of m total chunks
155
+ - Higher redundancy (m-k) provides better protection against chunk loss
156
+
157
+ ### Using Erasure Coding
158
+
159
+ ```python
160
+ from hippius_sdk import HippiusClient
161
+
162
+ client = HippiusClient()
163
+
164
+ # Erasure code a file with default parameters (k=3, m=5)
165
+ result = client.erasure_code_file("large_file.mp4")
166
+ metadata_cid = result["metadata_cid"]
167
+
168
+ # Use custom parameters for more redundancy
169
+ result = client.erasure_code_file(
170
+ file_path="important_data.zip",
171
+ k=4, # Need 4 chunks to reconstruct
172
+ m=10, # Create 10 chunks total (6 redundant)
173
+ chunk_size=2097152, # 2MB chunks
174
+ encrypt=True # Encrypt before splitting
175
+ )
176
+
177
+ # Store erasure-coded file in Hippius marketplace
178
+ result = client.store_erasure_coded_file(
179
+ file_path="critical_backup.tar",
180
+ k=3,
181
+ m=5,
182
+ encrypt=True,
183
+ miner_ids=["miner1", "miner2", "miner3"]
184
+ )
185
+
186
+ # Reconstruct a file from its metadata
187
+ reconstructed_path = client.reconstruct_from_erasure_code(
188
+ metadata_cid=metadata_cid,
189
+ output_file="reconstructed_file.mp4"
190
+ )
191
+ ```
192
+
193
+ ### When to Use Erasure Coding
194
+
195
+ Erasure coding is particularly useful for:
196
+
197
+ - Large files where reliability is critical
198
+ - Long-term archival storage
199
+ - Data that must survive partial network failures
200
+ - Situations where higher redundancy is needed without full replication
201
+
202
+ ### Advanced Features
203
+
204
+ #### Small File Handling
205
+
206
+ The SDK automatically adjusts parameters for small files:
207
+
208
+ - If a file is too small to be split into `k` chunks, the SDK will adjust the chunk size
209
+ - For very small files, the content is split into exactly `k` sub-blocks
210
+ - Parameters are always optimized to provide the requested level of redundancy
211
+
212
+ #### Robust Storage in Marketplace
213
+
214
+ When using `store_erasure_coded_file`, the SDK now:
215
+
216
+ - Stores both the metadata file AND all encoded chunks in the marketplace
217
+ - Ensures miners can access all necessary data for redundancy and retrieval
218
+ - Reports total number of files stored for verification
219
+
220
+ #### CLI Commands
221
+
222
+ The CLI provides powerful commands for erasure coding:
223
+
224
+ ```bash
225
+ # Basic usage with automatic parameter adjustment
226
+ hippius erasure-code myfile.txt
227
+
228
+ # Specify custom parameters
229
+ hippius erasure-code large_video.mp4 --k 4 --m 8 --chunk-size 4194304
230
+
231
+ # For smaller files, using smaller parameters
232
+ hippius erasure-code small_doc.txt --k 2 --m 5 --chunk-size 4096
233
+
234
+ # Reconstruct a file from its metadata CID
235
+ hippius reconstruct QmMetadataCID reconstructed_file.mp4
236
+ ```
237
+
238
+ The CLI provides detailed output during the process, including:
239
+ - Automatic parameter adjustments for optimal encoding
240
+ - Progress of chunk creation and upload
241
+ - Storage confirmation in the marketplace
242
+ - Instructions for reconstruction
243
+
146
244
  ## Command Line Interface
147
245
 
148
246
  The Hippius SDK includes a powerful command-line interface (CLI) that provides access to all major features of the SDK directly from your terminal.
@@ -211,6 +309,19 @@ hippius store my_file.txt --encrypt
211
309
  hippius download QmCID123 output_file.txt --decrypt
212
310
  ```
213
311
 
312
+ ### Erasure Coding
313
+
314
+ ```bash
315
+ # Erasure code a file with default parameters (k=3, m=5)
316
+ hippius erasure-code large_file.mp4
317
+
318
+ # Erasure code with custom parameters
319
+ hippius erasure-code important_data.zip --k 4 --m 10 --chunk-size 2097152 --encrypt
320
+
321
+ # Reconstruct a file from its metadata
322
+ hippius reconstruct QmMetadataCID reconstructed_file.mp4
323
+ ```
324
+
214
325
  ### Using Environment Variables
215
326
 
216
327
  The CLI automatically reads from your `.env` file for common settings:
@@ -435,25 +435,202 @@ def handle_files(client, account_address, debug=False, show_all_miners=False):
435
435
  return 0
436
436
 
437
437
 
438
+ def handle_erasure_code(
439
+ client, file_path, k, m, chunk_size, miner_ids, encrypt=None, verbose=True
440
+ ):
441
+ """Handle the erasure-code command"""
442
+ if not os.path.exists(file_path):
443
+ print(f"Error: File {file_path} not found")
444
+ return 1
445
+
446
+ # Check if zfec is installed
447
+ try:
448
+ import zfec
449
+ except ImportError:
450
+ print(
451
+ "Error: zfec is required for erasure coding. Install it with: pip install zfec"
452
+ )
453
+ print("Then update your environment: poetry add zfec")
454
+ return 1
455
+
456
+ # Parse miner IDs if provided
457
+ miner_id_list = None
458
+ if miner_ids:
459
+ miner_id_list = [m.strip() for m in miner_ids.split(",") if m.strip()]
460
+ if verbose:
461
+ print(f"Targeting {len(miner_id_list)} miners: {', '.join(miner_id_list)}")
462
+
463
+ # Get the file size and adjust parameters if needed
464
+ file_size = os.path.getsize(file_path)
465
+ file_size_mb = file_size / (1024 * 1024)
466
+
467
+ print(f"Processing {file_path} ({file_size_mb:.2f} MB) with erasure coding...")
468
+
469
+ # Check if the file is too small for the current chunk size and k value
470
+ original_k = k
471
+ original_m = m
472
+ original_chunk_size = chunk_size
473
+
474
+ # Calculate how many chunks we would get with current settings
475
+ potential_chunks = max(1, file_size // chunk_size)
476
+
477
+ # If we can't get at least k chunks, adjust the chunk size
478
+ if potential_chunks < k:
479
+ # Calculate a new chunk size that would give us exactly k chunks
480
+ new_chunk_size = max(1024, file_size // k) # Ensure at least 1KB chunks
481
+
482
+ print(f"Warning: File is too small for the requested parameters.")
483
+ print(f"Original parameters: k={k}, m={m}, chunk size={chunk_size/1024/1024:.2f} MB")
484
+ print(f"Would create only {potential_chunks} chunks, which is less than k={k}")
485
+ print(f"Automatically adjusting chunk size to {new_chunk_size/1024/1024:.6f} MB to create at least {k} chunks")
486
+
487
+ chunk_size = new_chunk_size
488
+
489
+ print(f"Final parameters: k={k}, m={m} (need {k} of {m} chunks to reconstruct)")
490
+ print(f"Chunk size: {chunk_size/1024/1024:.6f} MB")
491
+
492
+ if encrypt:
493
+ print("Encryption: Enabled")
494
+
495
+ start_time = time.time()
496
+
497
+ try:
498
+ # Use the store_erasure_coded_file method directly from HippiusClient
499
+ result = client.store_erasure_coded_file(
500
+ file_path=file_path,
501
+ k=k,
502
+ m=m,
503
+ chunk_size=chunk_size,
504
+ encrypt=encrypt,
505
+ miner_ids=miner_id_list,
506
+ max_retries=3,
507
+ verbose=verbose,
508
+ )
509
+
510
+ elapsed_time = time.time() - start_time
511
+
512
+ print(f"\nErasure coding and storage completed in {elapsed_time:.2f} seconds!")
513
+
514
+ # Display metadata
515
+ metadata = result.get("metadata", {})
516
+ metadata_cid = result.get("metadata_cid", "unknown")
517
+ total_files_stored = result.get("total_files_stored", 0)
518
+
519
+ original_file = metadata.get("original_file", {})
520
+ erasure_coding = metadata.get("erasure_coding", {})
521
+
522
+ print("\nErasure Coding Summary:")
523
+ print(
524
+ f" Original file: {original_file.get('name')} ({original_file.get('size', 0)/1024/1024:.2f} MB)"
525
+ )
526
+ print(f" File ID: {erasure_coding.get('file_id')}")
527
+ print(f" Parameters: k={erasure_coding.get('k')}, m={erasure_coding.get('m')}")
528
+ print(f" Total chunks: {len(metadata.get('chunks', []))}")
529
+ print(f" Total files stored in marketplace: {total_files_stored}")
530
+ print(f" Metadata CID: {metadata_cid}")
531
+
532
+ # If we stored in the marketplace
533
+ if "transaction_hash" in result:
534
+ print(
535
+ f"\nStored in marketplace. Transaction hash: {result['transaction_hash']}"
536
+ )
537
+
538
+ # Instructions for reconstruction
539
+ print("\nTo reconstruct this file, you will need:")
540
+ print(f" 1. The metadata CID: {metadata_cid}")
541
+ print(" 2. Access to at least k chunks for each original chunk")
542
+ print("\nReconstruction command:")
543
+ print(
544
+ f" hippius reconstruct {metadata_cid} reconstructed_{original_file.get('name')}"
545
+ )
546
+
547
+ return 0
548
+
549
+ except Exception as e:
550
+ print(f"Error during erasure coding: {e}")
551
+
552
+ # Provide helpful advice based on the error
553
+ if "Wrong length" in str(e) and "input blocks" in str(e):
554
+ print("\nThis error typically occurs with very small files.")
555
+ print("Suggestions:")
556
+ print(" 1. Try using a smaller chunk size: --chunk-size 4096")
557
+ print(" 2. Try using a smaller k value: --k 2")
558
+ print(" 3. For very small files, consider using regular storage instead of erasure coding.")
559
+
560
+ return 1
561
+
562
+
563
+ def handle_reconstruct(client, metadata_cid, output_file, verbose=True):
564
+ """Handle the reconstruct command for erasure-coded files"""
565
+ # Check if zfec is installed
566
+ try:
567
+ import zfec
568
+ except ImportError:
569
+ print(
570
+ "Error: zfec is required for erasure coding. Install it with: pip install zfec"
571
+ )
572
+ print("Then update your environment: poetry add zfec")
573
+ return 1
574
+
575
+ print(f"Reconstructing file from metadata CID: {metadata_cid}")
576
+ print(f"Output file: {output_file}")
577
+
578
+ start_time = time.time()
579
+
580
+ try:
581
+ # Use the reconstruct_from_erasure_code method
582
+ result = client.reconstruct_from_erasure_code(
583
+ metadata_cid=metadata_cid, output_file=output_file, verbose=verbose
584
+ )
585
+
586
+ elapsed_time = time.time() - start_time
587
+ print(f"\nFile reconstruction completed in {elapsed_time:.2f} seconds!")
588
+ print(f"Reconstructed file saved to: {result}")
589
+
590
+ return 0
591
+
592
+ except Exception as e:
593
+ print(f"Error during file reconstruction: {e}")
594
+ return 1
595
+
596
+
438
597
  def main():
439
- """Main entry point for the Hippius CLI."""
598
+ """Main CLI entry point for hippius command."""
599
+ # Set up the argument parser
440
600
  parser = argparse.ArgumentParser(
441
601
  description="Hippius SDK Command Line Interface",
442
602
  formatter_class=argparse.RawDescriptionHelpFormatter,
443
603
  epilog="""
444
- Examples:
445
- hippius download QmCID123 downloaded_file.txt
446
- hippius exists QmCID123
447
- hippius cat QmCID123
448
- hippius store test_file.txt
449
- hippius store-dir ./test_directory
604
+ examples:
605
+ # Store a file
606
+ hippius store example.txt
607
+
608
+ # Store a directory
609
+ hippius store-dir ./my_directory
610
+
611
+ # Download a file
612
+ hippius download QmHash output.txt
613
+
614
+ # Check if a CID exists
615
+ hippius exists QmHash
616
+
617
+ # View the content of a CID
618
+ hippius cat QmHash
619
+
620
+ # View your available credits
450
621
  hippius credits
451
- hippius credits 5H1QBRF7T7dgKwzVGCgS4wioudvMRf9K4NEDzfuKLnuyBNzH
622
+
623
+ # View your stored files
452
624
  hippius files
453
- hippius files 5H1QBRF7T7dgKwzVGCgS4wioudvMRf9K4NEDzfuKLnuyBNzH
625
+
626
+ # View all miners for stored files
454
627
  hippius files --all-miners
455
- hippius keygen
456
- hippius keygen --copy
628
+
629
+ # Erasure code a file (Reed-Solomon)
630
+ hippius erasure-code large_file.mp4 --k 3 --m 5
631
+
632
+ # Reconstruct an erasure-coded file
633
+ hippius reconstruct QmMetadataHash reconstructed_file.mp4
457
634
  """,
458
635
  )
459
636
 
@@ -588,6 +765,53 @@ Examples:
588
765
  "--copy", action="store_true", help="Copy the generated key to the clipboard"
589
766
  )
590
767
 
768
+ # Erasure code command
769
+ erasure_code_parser = subparsers.add_parser(
770
+ "erasure-code", help="Erasure code a file"
771
+ )
772
+ erasure_code_parser.add_argument("file_path", help="Path to file to erasure code")
773
+ erasure_code_parser.add_argument(
774
+ "--k",
775
+ type=int,
776
+ default=3,
777
+ help="Number of data chunks needed to reconstruct (default: 3)",
778
+ )
779
+ erasure_code_parser.add_argument(
780
+ "--m", type=int, default=5, help="Total number of chunks to create (default: 5)"
781
+ )
782
+ erasure_code_parser.add_argument(
783
+ "--chunk-size",
784
+ type=int,
785
+ default=1048576,
786
+ help="Chunk size in bytes (default: 1MB)",
787
+ )
788
+ erasure_code_parser.add_argument(
789
+ "--miner-ids", help="Comma-separated list of miner IDs"
790
+ )
791
+ erasure_code_parser.add_argument(
792
+ "--encrypt", action="store_true", help="Encrypt the file"
793
+ )
794
+ erasure_code_parser.add_argument(
795
+ "--no-encrypt", action="store_true", help="Do not encrypt the file"
796
+ )
797
+ erasure_code_parser.add_argument(
798
+ "--verbose", action="store_true", help="Enable verbose output", default=True
799
+ )
800
+
801
+ # Reconstruct command
802
+ reconstruct_parser = subparsers.add_parser(
803
+ "reconstruct", help="Reconstruct an erasure-coded file"
804
+ )
805
+ reconstruct_parser.add_argument(
806
+ "metadata_cid", help="Metadata CID of the erasure-coded file"
807
+ )
808
+ reconstruct_parser.add_argument(
809
+ "output_file", help="Path to save reconstructed file"
810
+ )
811
+ reconstruct_parser.add_argument(
812
+ "--verbose", action="store_true", help="Enable verbose output", default=True
813
+ )
814
+
591
815
  args = parser.parse_args()
592
816
 
593
817
  if not args.command:
@@ -647,6 +871,23 @@ Examples:
647
871
  else False,
648
872
  )
649
873
 
874
+ elif args.command == "erasure-code":
875
+ return handle_erasure_code(
876
+ client,
877
+ args.file_path,
878
+ args.k,
879
+ args.m,
880
+ args.chunk_size,
881
+ miner_ids,
882
+ encrypt=args.encrypt,
883
+ verbose=args.verbose,
884
+ )
885
+
886
+ elif args.command == "reconstruct":
887
+ return handle_reconstruct(
888
+ client, args.metadata_cid, args.output_file, verbose=args.verbose
889
+ )
890
+
650
891
  except Exception as e:
651
892
  print(f"Error: {e}")
652
893
  return 1