lunalib 1.5.2__py3-none-any.whl → 1.6.0__py3-none-any.whl
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.
- lunalib/core/blockchain.py +1 -1
- lunalib/gtx/digital_bill.py +10 -2
- lunalib/gtx/genesis.py +23 -24
- lunalib/mining/__init__.py +1 -0
- lunalib/mining/miner.py +94 -4
- lunalib/transactions/security.py +8 -8
- lunalib/transactions/transactions.py +27 -27
- {lunalib-1.5.2.dist-info → lunalib-1.6.0.dist-info}/METADATA +7 -1
- {lunalib-1.5.2.dist-info → lunalib-1.6.0.dist-info}/RECORD +11 -11
- {lunalib-1.5.2.dist-info → lunalib-1.6.0.dist-info}/WHEEL +0 -0
- {lunalib-1.5.2.dist-info → lunalib-1.6.0.dist-info}/top_level.txt +0 -0
lunalib/core/blockchain.py
CHANGED
|
@@ -736,7 +736,7 @@ class BlockchainManager:
|
|
|
736
736
|
transactions.append(enhanced_tx)
|
|
737
737
|
print(f"⬇️ Found outgoing transaction: {amount} LUN + {fee} fee")
|
|
738
738
|
|
|
739
|
-
print(f"
|
|
739
|
+
print(f" Scan complete for block #{block.get('index')}: {len(transactions)} transactions found")
|
|
740
740
|
return transactions
|
|
741
741
|
def _handle_regular_transfers(self, tx: Dict, address_lower: str) -> Dict:
|
|
742
742
|
"""Handle regular transfer transactions that might be in different formats"""
|
lunalib/gtx/digital_bill.py
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
def safe_print(*args, **kwargs):
|
|
3
|
+
encoding = sys.stdout.encoding or 'utf-8'
|
|
4
|
+
try:
|
|
5
|
+
print(*args, **kwargs)
|
|
6
|
+
except UnicodeEncodeError:
|
|
7
|
+
print(*(str(a).encode(encoding, errors='replace').decode(encoding) for a in args), **kwargs)
|
|
8
|
+
safe_print("Warning: cryptography library not available. Using fallback methods.")
|
|
1
9
|
import time
|
|
2
10
|
import hashlib
|
|
3
11
|
import secrets
|
|
@@ -12,7 +20,7 @@ try:
|
|
|
12
20
|
from cryptography.exceptions import InvalidSignature
|
|
13
21
|
CRYPTOGRAPHY_AVAILABLE = True
|
|
14
22
|
except ImportError:
|
|
15
|
-
|
|
23
|
+
safe_print("Warning: cryptography library not available. Using fallback methods.")
|
|
16
24
|
CRYPTOGRAPHY_AVAILABLE = False
|
|
17
25
|
|
|
18
26
|
from .bill_registry import BillRegistry
|
|
@@ -182,7 +190,7 @@ class DigitalBill:
|
|
|
182
190
|
|
|
183
191
|
return self.signature
|
|
184
192
|
except Exception as e:
|
|
185
|
-
|
|
193
|
+
safe_print(f"Cryptographic signing failed, using fallback: {e}")
|
|
186
194
|
return self._sign_fallback(private_key)
|
|
187
195
|
|
|
188
196
|
def _sign_fallback(self, private_key):
|
lunalib/gtx/genesis.py
CHANGED
|
@@ -48,7 +48,7 @@ class GTXGenesis:
|
|
|
48
48
|
return {'valid': False, 'error': 'Bill not found in registry'}
|
|
49
49
|
|
|
50
50
|
# DEBUG: Print what we received
|
|
51
|
-
|
|
51
|
+
safe_print(f"DEBUG: Full bill record: {bill_record}")
|
|
52
52
|
|
|
53
53
|
# Extract the actual bill_data from the metadata field
|
|
54
54
|
bill_data = bill_record.get('metadata', {})
|
|
@@ -56,7 +56,7 @@ class GTXGenesis:
|
|
|
56
56
|
return {'valid': False, 'error': 'No bill data found in metadata'}
|
|
57
57
|
|
|
58
58
|
# DEBUG: Print the extracted bill_data
|
|
59
|
-
|
|
59
|
+
safe_print(f"DEBUG: Extracted bill_data: {bill_data}")
|
|
60
60
|
|
|
61
61
|
# Extract signature components from bill_data (not from bill_record)
|
|
62
62
|
public_key = bill_data.get('public_key')
|
|
@@ -68,10 +68,10 @@ class GTXGenesis:
|
|
|
68
68
|
timestamp = bill_data.get('timestamp', 0)
|
|
69
69
|
bill_type = bill_data.get('type', 'GTX_Genesis')
|
|
70
70
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
safe_print(f"🔍 GTXGenesis.verify_bill() for {front_serial}:")
|
|
72
|
+
safe_print(f" Signature: {signature}")
|
|
73
|
+
safe_print(f" Public Key: {public_key}")
|
|
74
|
+
safe_print(f" Metadata Hash: {metadata_hash}")
|
|
75
75
|
|
|
76
76
|
# Use the same verification logic as the endpoint
|
|
77
77
|
verification_method = "unknown"
|
|
@@ -81,7 +81,7 @@ class GTXGenesis:
|
|
|
81
81
|
if metadata_hash and signature == metadata_hash:
|
|
82
82
|
signature_valid = True
|
|
83
83
|
verification_method = "signature_is_metadata_hash"
|
|
84
|
-
|
|
84
|
+
safe_print(f"✅ Verified: signature matches metadata_hash")
|
|
85
85
|
|
|
86
86
|
# METHOD 2: Check hash of public_key + metadata_hash
|
|
87
87
|
elif signature_valid is None and metadata_hash and public_key and signature:
|
|
@@ -90,7 +90,7 @@ class GTXGenesis:
|
|
|
90
90
|
if signature == expected_signature:
|
|
91
91
|
signature_valid = True
|
|
92
92
|
verification_method = "metadata_hash_signature"
|
|
93
|
-
|
|
93
|
+
safe_print(f"Verified: hash(public_key + metadata_hash)")
|
|
94
94
|
|
|
95
95
|
# METHOD 3: Check DigitalBill calculated hash
|
|
96
96
|
elif signature_valid is None:
|
|
@@ -122,32 +122,31 @@ class GTXGenesis:
|
|
|
122
122
|
if signature == calculated_hash:
|
|
123
123
|
signature_valid = True
|
|
124
124
|
verification_method = "digital_bill_calculate_hash"
|
|
125
|
-
|
|
125
|
+
safe_print(f"Verified: DigitalBill.calculate_hash()")
|
|
126
126
|
print(f" Calculated hash: {calculated_hash}")
|
|
127
127
|
|
|
128
128
|
# Approach 2: Use the verify() method (checks all signature types)
|
|
129
129
|
elif digital_bill.verify():
|
|
130
130
|
signature_valid = True
|
|
131
131
|
verification_method = "digital_bill_verify_method"
|
|
132
|
-
|
|
132
|
+
safe_print(f"Verified: DigitalBill.verify()")
|
|
133
133
|
|
|
134
134
|
# Approach 3: Check if signature matches metadata_hash generation
|
|
135
135
|
elif signature == digital_bill._generate_metadata_hash():
|
|
136
136
|
signature_valid = True
|
|
137
137
|
verification_method = "digital_bill_metadata_hash"
|
|
138
|
-
|
|
138
|
+
safe_print(f"Verified: matches generated metadata_hash")
|
|
139
139
|
|
|
140
140
|
else:
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
141
|
+
safe_print(f"DigitalBill verification failed:")
|
|
142
|
+
safe_print(f" Calculated hash: {calculated_hash}")
|
|
143
|
+
safe_print(f" Signature: {signature}")
|
|
144
|
+
safe_print(f" Metadata hash: {metadata_hash}")
|
|
145
|
+
safe_print(f" Public key: {public_key}")
|
|
147
146
|
except Exception as e:
|
|
148
|
-
|
|
147
|
+
safe_print(f"DigitalBill verification error: {e}")
|
|
149
148
|
import traceback
|
|
150
|
-
|
|
149
|
+
safe_print(f"Traceback: {traceback.format_exc()}")
|
|
151
150
|
|
|
152
151
|
# METHOD 4: Check simple concatenation hash
|
|
153
152
|
elif signature_valid is None and signature:
|
|
@@ -156,7 +155,7 @@ class GTXGenesis:
|
|
|
156
155
|
if signature == expected_simple_hash:
|
|
157
156
|
signature_valid = True
|
|
158
157
|
verification_method = "simple_hash"
|
|
159
|
-
|
|
158
|
+
safe_print(f"✅ Verified: hash(serial+denom+issued+timestamp)")
|
|
160
159
|
|
|
161
160
|
# METHOD 5: Check bill JSON hash
|
|
162
161
|
elif signature_valid is None:
|
|
@@ -173,19 +172,19 @@ class GTXGenesis:
|
|
|
173
172
|
if signature == bill_json_hash:
|
|
174
173
|
signature_valid = True
|
|
175
174
|
verification_method = "bill_json_hash"
|
|
176
|
-
|
|
175
|
+
safe_print(f"Verified: hash(bill_data_json)")
|
|
177
176
|
|
|
178
177
|
# Final fallback: accept any non-empty signature temporarily
|
|
179
178
|
if signature_valid is None and signature and len(signature) > 10:
|
|
180
179
|
signature_valid = True
|
|
181
180
|
verification_method = "fallback_accept"
|
|
182
|
-
|
|
181
|
+
safe_print(f"Using fallback acceptance for signature")
|
|
183
182
|
|
|
184
183
|
# If all methods failed
|
|
185
184
|
if signature_valid is None:
|
|
186
185
|
signature_valid = False
|
|
187
186
|
verification_method = "all_failed"
|
|
188
|
-
|
|
187
|
+
safe_print(f"All verification methods failed")
|
|
189
188
|
|
|
190
189
|
# Return result in same format as endpoint
|
|
191
190
|
if signature_valid:
|
|
@@ -337,7 +336,7 @@ class GTXGenesis:
|
|
|
337
336
|
return computed_hash == bill_info['hash']
|
|
338
337
|
|
|
339
338
|
except Exception as e:
|
|
340
|
-
|
|
339
|
+
safe_print(f"Bill verification error: {e}")
|
|
341
340
|
return False
|
|
342
341
|
|
|
343
342
|
def _get_denomination_breakdown(self, bills: List[Dict]) -> Dict[int, int]:
|
lunalib/mining/__init__.py
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .miner import GenesisMiner
|
lunalib/mining/miner.py
CHANGED
|
@@ -74,7 +74,7 @@ class GenesisMiner:
|
|
|
74
74
|
|
|
75
75
|
safe_print(f"✅ Successfully mined GTX ${denomination:,} bill!")
|
|
76
76
|
safe_print(f"⏱️ Mining time: {mining_time:.2f}s")
|
|
77
|
-
safe_print(f"
|
|
77
|
+
safe_print(f" Hash attempts: {mining_result['nonce']:,}")
|
|
78
78
|
safe_print(f"🔗 Bill hash: {mining_result['hash'][:32]}...")
|
|
79
79
|
|
|
80
80
|
# Convert to GTX Genesis transaction
|
|
@@ -174,7 +174,7 @@ class GenesisMiner:
|
|
|
174
174
|
safe_print(f"✅ Successfully mined and validated Transaction Block #{block_height}!")
|
|
175
175
|
safe_print(f"⏱️ Mining time: {mining_time:.2f}s")
|
|
176
176
|
safe_print(f"💰 Block reward: {block['reward']:.6f} LUN")
|
|
177
|
-
safe_print(f"
|
|
177
|
+
safe_print(f" Transactions: {block['transaction_count']}")
|
|
178
178
|
safe_print(f"🔗 Block hash: {mining_result['hash'][:32]}...")
|
|
179
179
|
|
|
180
180
|
# Submit block to blockchain
|
|
@@ -298,7 +298,7 @@ class GenesisMiner:
|
|
|
298
298
|
# Calculate merkleroot from transactions
|
|
299
299
|
merkleroot = self._calculate_merkleroot(transactions)
|
|
300
300
|
|
|
301
|
-
print(f"
|
|
301
|
+
print(f" Mining proof components:")
|
|
302
302
|
print(f" Block hash: {block_hash[:16]}...")
|
|
303
303
|
print(f" Difficulty: {difficulty}")
|
|
304
304
|
print(f" Nonce: {nonce}")
|
|
@@ -623,4 +623,94 @@ class GenesisMiner:
|
|
|
623
623
|
return {
|
|
624
624
|
"network_connected": False,
|
|
625
625
|
"error": str(e)
|
|
626
|
-
}
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
class Miner:
|
|
629
|
+
"""
|
|
630
|
+
Miner class that uses lunalib directly to mine transfers, GTX genesis blocks, and rewards.
|
|
631
|
+
"""
|
|
632
|
+
|
|
633
|
+
def __init__(self, config, data_manager, mining_started_callback=None, mining_completed_callback=None, block_mined_callback=None):
|
|
634
|
+
self.config = config
|
|
635
|
+
self.data_manager = data_manager
|
|
636
|
+
self.is_mining = False
|
|
637
|
+
self.blocks_mined = 0
|
|
638
|
+
self.total_reward = 0.0
|
|
639
|
+
self.mining_started_callback = mining_started_callback
|
|
640
|
+
self.mining_completed_callback = mining_completed_callback
|
|
641
|
+
self.block_mined_callback = block_mined_callback
|
|
642
|
+
|
|
643
|
+
self.mining_history = self.data_manager.load_mining_history()
|
|
644
|
+
|
|
645
|
+
# Use lunalib components
|
|
646
|
+
self.blockchain_manager = BlockchainManager(endpoint_url=config.node_url)
|
|
647
|
+
self.difficulty_system = DifficultySystem()
|
|
648
|
+
self.cuda_manager = CUDAManager()
|
|
649
|
+
|
|
650
|
+
self.current_hash = ""
|
|
651
|
+
self.current_nonce = 0
|
|
652
|
+
self.hash_rate = 0
|
|
653
|
+
self.mining_thread = None
|
|
654
|
+
self.should_stop_mining = False
|
|
655
|
+
|
|
656
|
+
def start_mining(self, mining_type: str):
|
|
657
|
+
"""
|
|
658
|
+
Start mining based on the type: 'transfer', 'gtx_genesis', or 'reward'.
|
|
659
|
+
"""
|
|
660
|
+
if self.is_mining:
|
|
661
|
+
return
|
|
662
|
+
|
|
663
|
+
self.is_mining = True
|
|
664
|
+
self.should_stop_mining = False
|
|
665
|
+
|
|
666
|
+
if self.mining_started_callback:
|
|
667
|
+
self.mining_started_callback()
|
|
668
|
+
|
|
669
|
+
if mining_type == 'transfer':
|
|
670
|
+
self.mine_transfers()
|
|
671
|
+
elif mining_type == 'gtx_genesis':
|
|
672
|
+
self.mine_genesis_blocks()
|
|
673
|
+
elif mining_type == 'reward':
|
|
674
|
+
self.mine_rewards()
|
|
675
|
+
else:
|
|
676
|
+
raise ValueError("Invalid mining type. Choose 'transfer', 'gtx_genesis', or 'reward'.")
|
|
677
|
+
|
|
678
|
+
def stop_mining(self):
|
|
679
|
+
"""Stop the mining process."""
|
|
680
|
+
self.is_mining = False
|
|
681
|
+
self.should_stop_mining = True
|
|
682
|
+
if self.mining_thread and self.mining_thread.is_alive():
|
|
683
|
+
self.mining_thread.join()
|
|
684
|
+
|
|
685
|
+
def mine_transfers(self):
|
|
686
|
+
"""Mine transfer transactions."""
|
|
687
|
+
while self.is_mining:
|
|
688
|
+
# Fetch transactions from the mempool
|
|
689
|
+
transactions = self.mempool_manager.get_pending_transactions()
|
|
690
|
+
if not transactions:
|
|
691
|
+
continue
|
|
692
|
+
|
|
693
|
+
# Mine a block with the transactions
|
|
694
|
+
block = self.blockchain_manager.create_block(transactions)
|
|
695
|
+
self.blockchain_manager.add_block(block)
|
|
696
|
+
self.mining_stats["transfers_mined"] += 1
|
|
697
|
+
|
|
698
|
+
def mine_genesis_blocks(self):
|
|
699
|
+
"""Mine GTX genesis blocks."""
|
|
700
|
+
while self.is_mining:
|
|
701
|
+
# Create a genesis block
|
|
702
|
+
genesis_block = self.blockchain_manager.create_genesis_block()
|
|
703
|
+
self.blockchain_manager.add_block(genesis_block)
|
|
704
|
+
self.mining_stats["genesis_blocks_mined"] += 1
|
|
705
|
+
|
|
706
|
+
def mine_rewards(self):
|
|
707
|
+
"""Mine rewards."""
|
|
708
|
+
while self.is_mining:
|
|
709
|
+
# Simulate mining rewards
|
|
710
|
+
reward = self.blockchain_manager.generate_reward()
|
|
711
|
+
self.blockchain_manager.add_reward(reward)
|
|
712
|
+
self.mining_stats["rewards_mined"] += 1
|
|
713
|
+
|
|
714
|
+
def get_mining_stats(self):
|
|
715
|
+
"""Return the current mining statistics."""
|
|
716
|
+
return self.mining_stats
|
lunalib/transactions/security.py
CHANGED
|
@@ -123,22 +123,22 @@ class TransactionSecurity:
|
|
|
123
123
|
|
|
124
124
|
# For unsigned test transactions
|
|
125
125
|
if signature in ["system", "unsigned", "test"]:
|
|
126
|
-
|
|
126
|
+
safe_print(f"[SECURITY] Skipping signature check for system/unsigned transaction")
|
|
127
127
|
return True
|
|
128
128
|
|
|
129
129
|
# Check SM2 signature length (should be 128 hex chars = 64 bytes)
|
|
130
130
|
if len(signature) != 128:
|
|
131
|
-
|
|
131
|
+
safe_print(f"[SECURITY] Invalid SM2 signature length: {len(signature)} (expected 128)")
|
|
132
132
|
return False
|
|
133
133
|
|
|
134
134
|
# Check if all characters are valid hex
|
|
135
135
|
if not all(c in "0123456789abcdefABCDEF" for c in signature):
|
|
136
|
-
|
|
136
|
+
safe_print(f"[SECURITY] Signature contains non-hex characters")
|
|
137
137
|
return False
|
|
138
138
|
|
|
139
139
|
# Check public key format (should start with '04' for uncompressed)
|
|
140
140
|
if not public_key.startswith('04'):
|
|
141
|
-
|
|
141
|
+
safe_print(f"[SECURITY] Invalid public key format: {public_key[:20]}...")
|
|
142
142
|
return False
|
|
143
143
|
|
|
144
144
|
# Use KeyManager for verification if available
|
|
@@ -148,15 +148,15 @@ class TransactionSecurity:
|
|
|
148
148
|
|
|
149
149
|
# Verify signature
|
|
150
150
|
is_valid = self.key_manager.verify_signature(signing_data, signature, public_key)
|
|
151
|
-
|
|
151
|
+
safe_print(f"[SECURITY] SM2 signature verification: {is_valid}")
|
|
152
152
|
return is_valid
|
|
153
153
|
|
|
154
154
|
# Fallback: Basic format check if SM2 not available
|
|
155
|
-
|
|
155
|
+
safe_print(f"[SECURITY] SM2 not available, using basic signature validation")
|
|
156
156
|
return len(signature) == 128 and signature.startswith(('04', '03', '02'))
|
|
157
157
|
|
|
158
158
|
except Exception as e:
|
|
159
|
-
|
|
159
|
+
safe_print(f"[SECURITY] Signature validation error: {e}")
|
|
160
160
|
return False
|
|
161
161
|
|
|
162
162
|
def _get_signing_data(self, transaction: Dict) -> str:
|
|
@@ -183,7 +183,7 @@ class TransactionSecurity:
|
|
|
183
183
|
|
|
184
184
|
def _validate_signature(self, transaction: Dict) -> bool:
|
|
185
185
|
"""Legacy signature validation (for backward compatibility)"""
|
|
186
|
-
|
|
186
|
+
safe_print(f"[SECURITY] Using legacy signature validation")
|
|
187
187
|
return self._validate_signature_sm2(transaction)
|
|
188
188
|
|
|
189
189
|
def _check_rate_limit(self, address: str) -> bool:
|
|
@@ -235,55 +235,55 @@ class TransactionManager:
|
|
|
235
235
|
|
|
236
236
|
# System transactions are always valid
|
|
237
237
|
if signature in ["system", "unsigned", "test"]:
|
|
238
|
-
|
|
238
|
+
safe_print(f"[TRANSACTIONS] Skipping signature check for {signature} transaction")
|
|
239
239
|
return True
|
|
240
240
|
|
|
241
241
|
if not self.key_manager:
|
|
242
|
-
|
|
242
|
+
safe_print("[TRANSACTIONS] No key manager available for verification")
|
|
243
243
|
return False
|
|
244
244
|
|
|
245
245
|
# Check SM2 signature format
|
|
246
246
|
if len(signature) != 128:
|
|
247
|
-
|
|
247
|
+
safe_print(f"[TRANSACTIONS] Invalid SM2 signature length: {len(signature)} (expected 128)")
|
|
248
248
|
return False
|
|
249
249
|
|
|
250
250
|
# Get signing data (without public_key!)
|
|
251
251
|
sign_data = self._get_signing_data(transaction)
|
|
252
252
|
public_key = transaction.get("public_key", "")
|
|
253
253
|
|
|
254
|
-
|
|
255
|
-
|
|
254
|
+
safe_print(f"[TRANSACTIONS VERIFY] Signing data length: {len(sign_data)}")
|
|
255
|
+
safe_print(f"[TRANSACTIONS VERIFY] Signing data (first 100 chars): {sign_data[:100]}")
|
|
256
256
|
|
|
257
257
|
# Try to verify with KeyManager
|
|
258
|
-
|
|
258
|
+
safe_print(f"[TRANSACTIONS] Attempting verification...")
|
|
259
259
|
is_valid = self.key_manager.verify_signature(sign_data, signature, public_key)
|
|
260
260
|
|
|
261
|
-
|
|
261
|
+
safe_print(f"[TRANSACTIONS] SM2 signature verification result: {is_valid}")
|
|
262
262
|
|
|
263
263
|
return is_valid
|
|
264
264
|
|
|
265
265
|
except Exception as e:
|
|
266
|
-
|
|
266
|
+
safe_print(f"[TRANSACTIONS] Verification error: {e}")
|
|
267
267
|
import traceback
|
|
268
268
|
traceback.print_exc()
|
|
269
269
|
return False
|
|
270
270
|
def _debug_signature_issue(self, transaction: Dict, sign_data: str, signature: str, public_key: str):
|
|
271
271
|
"""Debug why signature verification is failing"""
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
272
|
+
safe_print("\n" + "="*60)
|
|
273
|
+
safe_print("DEBUGGING SIGNATURE ISSUE")
|
|
274
|
+
safe_print("="*60)
|
|
275
275
|
|
|
276
276
|
# 1. Check if we can sign and verify a simple test
|
|
277
|
-
|
|
277
|
+
safe_print("\n1. Testing SM2 with simple message...")
|
|
278
278
|
test_message = "Simple test message"
|
|
279
279
|
test_private = self.key_manager.generate_private_key()
|
|
280
280
|
test_public = self.key_manager.derive_public_key(test_private)
|
|
281
281
|
test_sig = self.key_manager.sign_data(test_message, test_private)
|
|
282
282
|
test_valid = self.key_manager.verify_signature(test_message, test_sig, test_public)
|
|
283
|
-
|
|
283
|
+
safe_print(f" Simple test verification: {test_valid}")
|
|
284
284
|
|
|
285
285
|
# 2. Try to recreate what was signed during transaction creation
|
|
286
|
-
|
|
286
|
+
safe_print("\n2. Reconstructing original transaction data...")
|
|
287
287
|
# Create the exact transaction data that should have been signed
|
|
288
288
|
reconstructed = {
|
|
289
289
|
"amount": float(transaction["amount"]),
|
|
@@ -298,23 +298,23 @@ class TransactionManager:
|
|
|
298
298
|
|
|
299
299
|
import json
|
|
300
300
|
reconstructed_json = json.dumps(reconstructed, sort_keys=True)
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
301
|
+
safe_print(f" Reconstructed JSON: {reconstructed_json}")
|
|
302
|
+
safe_print(f" Current signing data: {sign_data}")
|
|
303
|
+
safe_print(f" Are they equal? {reconstructed_json == sign_data}")
|
|
304
|
+
safe_print(f" Length difference: {len(reconstructed_json)} vs {len(sign_data)}")
|
|
305
305
|
|
|
306
306
|
# 3. Check for whitespace differences
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
307
|
+
safe_print("\n3. Checking for whitespace differences...")
|
|
308
|
+
safe_print(f" Reconstructed has spaces: {' ' in reconstructed_json}")
|
|
309
|
+
safe_print(f" Sign data has spaces: {' ' in sign_data}")
|
|
310
310
|
|
|
311
311
|
# 4. Check float formatting
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
312
|
+
safe_print("\n4. Checking float formatting...")
|
|
313
|
+
safe_print(f" Amount in tx: {transaction['amount']} (type: {type(transaction['amount'])})")
|
|
314
|
+
safe_print(f" Amount in reconstructed: {reconstructed['amount']} (type: {type(reconstructed['amount'])})")
|
|
315
315
|
|
|
316
316
|
# 5. Try different JSON serialization options
|
|
317
|
-
|
|
317
|
+
safe_print("\n5. Trying different JSON formats...")
|
|
318
318
|
formats = [
|
|
319
319
|
("Compact", lambda x: json.dumps(x, sort_keys=True, separators=(',', ':'))),
|
|
320
320
|
("Default", lambda x: json.dumps(x, sort_keys=True)),
|
|
@@ -324,9 +324,9 @@ class TransactionManager:
|
|
|
324
324
|
for name, formatter in formats:
|
|
325
325
|
formatted = formatter(reconstructed)
|
|
326
326
|
is_valid_test = self.key_manager.verify_signature(formatted, signature, public_key)
|
|
327
|
-
|
|
327
|
+
safe_print(f" {name} format: {is_valid_test} (length: {len(formatted)})")
|
|
328
328
|
|
|
329
|
-
|
|
329
|
+
safe_print("="*60 + "\n")
|
|
330
330
|
def assess_transaction_risk(self, transaction: Dict) -> Tuple[str, str]:
|
|
331
331
|
"""Assess transaction risk level"""
|
|
332
332
|
return self.security.assess_risk(transaction)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lunalib
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.6.0
|
|
4
4
|
Summary: Cryptocurrency Ecosystem library (LunaLib)
|
|
5
5
|
Home-page:
|
|
6
6
|
Author: Ling Lin
|
|
@@ -10,10 +10,16 @@ Classifier: License :: OSI Approved :: MIT License
|
|
|
10
10
|
Classifier: Operating System :: OS Independent
|
|
11
11
|
Requires-Python: >=3.7
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
|
+
Requires-Dist: cryptography
|
|
14
|
+
Requires-Dist: requests
|
|
15
|
+
Requires-Dist: numpy
|
|
16
|
+
Requires-Dist: pytest
|
|
17
|
+
Requires-Dist: pandas
|
|
13
18
|
Dynamic: author
|
|
14
19
|
Dynamic: classifier
|
|
15
20
|
Dynamic: description
|
|
16
21
|
Dynamic: description-content-type
|
|
22
|
+
Dynamic: requires-dist
|
|
17
23
|
Dynamic: requires-python
|
|
18
24
|
Dynamic: summary
|
|
19
25
|
|
|
@@ -2,7 +2,7 @@ lunalib/__init__.py,sha256=fEvoHvfcC6ilDGQrhXaVmcdB4yDmuijxz6YZHkjbuBg,527
|
|
|
2
2
|
lunalib/cli.py,sha256=SyuJIhvqld-XL9ks9XFOuyqVb44qyBUbahlqE_RDVkM,524
|
|
3
3
|
lunalib/luna_lib.py,sha256=ue9Bs93xjpg7_GHSUJPKBhf8nF5YcbCIdoMIu-jDgG4,2748
|
|
4
4
|
lunalib/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
-
lunalib/core/blockchain.py,sha256=
|
|
5
|
+
lunalib/core/blockchain.py,sha256=dY_zQXzT8wufrinN8rGlpDTHM_M1yejfKEIm6_s78io,36564
|
|
6
6
|
lunalib/core/crypto.py,sha256=R_f2sj7ASNnMW8Dtf2LIWTw-vCUjXD33zJPqPcPQVB8,10684
|
|
7
7
|
lunalib/core/mempool.py,sha256=itYFGQEuUde0Xh6WXcEz_n8hDsNhxkEAlRQ5g_Qiygg,14845
|
|
8
8
|
lunalib/core/sm2.py,sha256=Eq8Er3XQW5rYJXwaPT5vw5NoVXbSWhyuvjoG1LMo-NQ,23454
|
|
@@ -11,21 +11,21 @@ lunalib/core/wallet_manager.py,sha256=KK58hrr_xF1vZ4qI6x_BJqrs9XXh5m0XbZYnZmi9yo
|
|
|
11
11
|
lunalib/core/wallet_sync_helper.py,sha256=CGfSBXvf8vg4SGsLaxsjGwHVbD9dmfcuMrZ_CO0J5lE,6282
|
|
12
12
|
lunalib/gtx/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
13
|
lunalib/gtx/bill_registry.py,sha256=J1TivYIzmJEVQHNJrZxqOOEbUSlJs7rQIXfSA90ztL4,4333
|
|
14
|
-
lunalib/gtx/digital_bill.py,sha256=
|
|
15
|
-
lunalib/gtx/genesis.py,sha256=
|
|
16
|
-
lunalib/mining/__init__.py,sha256=
|
|
14
|
+
lunalib/gtx/digital_bill.py,sha256=xi2d7RVBGFwDOr8ulMCgvXXebHKl9LeeW9f5H4j_P_A,10977
|
|
15
|
+
lunalib/gtx/genesis.py,sha256=dDiLz-jW0zr5WUifYo9lzsrafQGOuZ9oakv_TX6QdPg,16028
|
|
16
|
+
lunalib/mining/__init__.py,sha256=Y6qgk4b7TCzICfjk55wJsDghea5aQ-SN2aRqRdKTf_8,31
|
|
17
17
|
lunalib/mining/cuda_manager.py,sha256=PUnmVvpu98OTZNdKIIYpVXnY__Ng4pHyZoh8wU-tDCM,5174
|
|
18
18
|
lunalib/mining/difficulty.py,sha256=tzIYmdcm1Xr9-8wyTwwkXJvJoGDyE77o_nu9d81VGvI,3927
|
|
19
|
-
lunalib/mining/miner.py,sha256=
|
|
19
|
+
lunalib/mining/miner.py,sha256=LydkuXgfjpFNXPVnd6zQp8ZJFjaxBvy3Ou-n8mqeYiU,31261
|
|
20
20
|
lunalib/storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
21
|
lunalib/storage/cache.py,sha256=U-riY8OTzxCOpl8yvhpbU3YUysEKgrPlmhO4F4cI9FM,5352
|
|
22
22
|
lunalib/storage/database.py,sha256=2f3Ie6JnuK7L0YGtAdZt5mgj90pokneXhSQKUyvx8Pc,8219
|
|
23
23
|
lunalib/storage/encryption.py,sha256=59g8vFFPAkc_L7t2TXas9Rs4oB3JB1t5ikmDbs4aaqM,4399
|
|
24
24
|
lunalib/transactions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
25
|
-
lunalib/transactions/security.py,sha256=
|
|
26
|
-
lunalib/transactions/transactions.py,sha256=
|
|
25
|
+
lunalib/transactions/security.py,sha256=cQJRasJ37Z8mJo8gt0JJOb0_M9CQ0QScr67y3M_NP4Q,10309
|
|
26
|
+
lunalib/transactions/transactions.py,sha256=3PgyW8gDQwY-gAPGY_T3m7RE_9HzEIOjTf6CWCsOKFY,18151
|
|
27
27
|
lunalib/transactions/validator.py,sha256=FQ-jVjj8VoVTlq65blB_hprAwJOtpc2peYdQk_L2xmg,2730
|
|
28
|
-
lunalib-1.
|
|
29
|
-
lunalib-1.
|
|
30
|
-
lunalib-1.
|
|
31
|
-
lunalib-1.
|
|
28
|
+
lunalib-1.6.0.dist-info/METADATA,sha256=4JfUdL6HER3Sa5gkTRSzLP67SZZ_apBLQ8HgX0mQ05c,774
|
|
29
|
+
lunalib-1.6.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
30
|
+
lunalib-1.6.0.dist-info/top_level.txt,sha256=eLcoOCtOwfvoqUu5g5CNBZB9bdhGXbTwmjuOM7i8ylw,8
|
|
31
|
+
lunalib-1.6.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|