lunalib 1.6.7__py3-none-any.whl → 1.7.9__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/.gitignore +3 -0
- lunalib/__pycache__/__init__.cpython-310.pyc +0 -0
- lunalib/core/__pycache__/__init__.cpython-310.pyc +0 -0
- lunalib/core/__pycache__/blockchain.cpython-310.pyc +0 -0
- lunalib/core/__pycache__/crypto.cpython-310.pyc +0 -0
- lunalib/core/__pycache__/mempool.cpython-310.pyc +0 -0
- lunalib/core/__pycache__/wallet.cpython-310.pyc +0 -0
- lunalib/core/blockchain.py +182 -2
- lunalib/core/daemon.py +108 -5
- lunalib/core/mempool.py +1 -0
- lunalib/core/wallet.py +856 -492
- lunalib/core/wallet_db.py +68 -0
- lunalib/gtx/__pycache__/__init__.cpython-310.pyc +0 -0
- lunalib/gtx/__pycache__/bill_registry.cpython-310.pyc +0 -0
- lunalib/gtx/__pycache__/digital_bill.cpython-310.pyc +0 -0
- lunalib/gtx/__pycache__/genesis.cpython-310.pyc +0 -0
- lunalib/mining/__pycache__/__init__.cpython-310.pyc +0 -0
- lunalib/mining/__pycache__/cuda_manager.cpython-310.pyc +0 -0
- lunalib/mining/__pycache__/difficulty.cpython-310.pyc +0 -0
- lunalib/mining/__pycache__/miner.cpython-310.pyc +0 -0
- lunalib/mining/miner.py +33 -14
- lunalib/storage/__pycache__/__init__.cpython-310.pyc +0 -0
- lunalib/storage/__pycache__/cache.cpython-310.pyc +0 -0
- lunalib/storage/__pycache__/database.cpython-310.pyc +0 -0
- lunalib/storage/__pycache__/encryption.cpython-310.pyc +0 -0
- lunalib/tests/__pycache__/conftest.cpython-310-pytest-9.0.1.pyc +0 -0
- lunalib/tests/__pycache__/test_blockchain.cpython-310-pytest-9.0.1.pyc +0 -0
- lunalib/tests/__pycache__/test_crypto.cpython-310-pytest-9.0.1.pyc +0 -0
- lunalib/tests/__pycache__/test_gtx.cpython-310-pytest-9.0.1.pyc +0 -0
- lunalib/tests/__pycache__/test_mining.cpython-310-pytest-9.0.1.pyc +0 -0
- lunalib/tests/__pycache__/test_storage.cpython-310-pytest-9.0.1.pyc +0 -0
- lunalib/tests/__pycache__/test_transactions.cpython-310-pytest-9.0.1.pyc +0 -0
- lunalib/tests/__pycache__/test_wallet.cpython-310-pytest-9.0.1.pyc +0 -0
- lunalib/tests/conftest.py +41 -0
- lunalib/tests/init.py +0 -0
- lunalib/tests/integration/__pycache__/test_integration.cpython-310-pytest-9.0.1.pyc +0 -0
- lunalib/tests/integration/test_integration.py +62 -0
- lunalib/tests/test_blockchain.py +34 -0
- lunalib/tests/test_crypto.py +42 -0
- lunalib/tests/test_gtx.py +135 -0
- lunalib/tests/test_mining.py +244 -0
- lunalib/tests/test_security_suite.py +832 -0
- lunalib/tests/test_storage.py +84 -0
- lunalib/tests/test_transactions.py +103 -0
- lunalib/tests/test_wallet.py +91 -0
- lunalib/transactions/__pycache__/__init__.cpython-310.pyc +0 -0
- lunalib/transactions/__pycache__/security.cpython-310.pyc +0 -0
- lunalib/transactions/__pycache__/transactions.cpython-310.pyc +0 -0
- lunalib/transactions/__pycache__/validator.cpython-310.pyc +0 -0
- {lunalib-1.6.7.dist-info → lunalib-1.7.9.dist-info}/METADATA +2 -1
- lunalib-1.7.9.dist-info/RECORD +77 -0
- lunalib-1.6.7.dist-info/RECORD +0 -33
- {lunalib-1.6.7.dist-info → lunalib-1.7.9.dist-info}/WHEEL +0 -0
- {lunalib-1.6.7.dist-info → lunalib-1.7.9.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
import time
|
|
3
|
+
from unittest.mock import Mock, patch
|
|
4
|
+
from lunalib.mining.miner import GenesisMiner
|
|
5
|
+
from lunalib.mining.difficulty import DifficultySystem
|
|
6
|
+
|
|
7
|
+
class TestMining:
|
|
8
|
+
def test_difficulty_system(self):
|
|
9
|
+
"""Test difficulty calculations with 9-tier system"""
|
|
10
|
+
difficulty = DifficultySystem()
|
|
11
|
+
|
|
12
|
+
# Test bill difficulties - 9 tiers
|
|
13
|
+
assert difficulty.get_bill_difficulty(1) == 1 # Trivial
|
|
14
|
+
assert difficulty.get_bill_difficulty(5) == 2 # Very Easy
|
|
15
|
+
assert difficulty.get_bill_difficulty(50) == 3 # Easy
|
|
16
|
+
assert difficulty.get_bill_difficulty(500) == 4 # Moderate
|
|
17
|
+
assert difficulty.get_bill_difficulty(5000) == 5 # Standard
|
|
18
|
+
assert difficulty.get_bill_difficulty(50000) == 6 # Challenging
|
|
19
|
+
assert difficulty.get_bill_difficulty(500000) == 7 # Hard
|
|
20
|
+
assert difficulty.get_bill_difficulty(5000000) == 8 # Very Hard
|
|
21
|
+
assert difficulty.get_bill_difficulty(50000000) == 9 # Extreme
|
|
22
|
+
|
|
23
|
+
# Test transaction difficulties - 9 tiers
|
|
24
|
+
assert difficulty.get_transaction_difficulty(0.0005) == 1 # Trivial
|
|
25
|
+
assert difficulty.get_transaction_difficulty(0.005) == 2 # Very Easy
|
|
26
|
+
assert difficulty.get_transaction_difficulty(0.05) == 3 # Easy
|
|
27
|
+
assert difficulty.get_transaction_difficulty(0.5) == 4 # Moderate
|
|
28
|
+
assert difficulty.get_transaction_difficulty(5) == 5 # Standard
|
|
29
|
+
assert difficulty.get_transaction_difficulty(50) == 6 # Challenging
|
|
30
|
+
assert difficulty.get_transaction_difficulty(500) == 7 # Hard
|
|
31
|
+
assert difficulty.get_transaction_difficulty(5000) == 8 # Very Hard
|
|
32
|
+
assert difficulty.get_transaction_difficulty(50000) == 9 # Extreme
|
|
33
|
+
|
|
34
|
+
# Test edge cases and boundary values
|
|
35
|
+
assert difficulty.get_bill_difficulty(0) == 1 # Zero amount
|
|
36
|
+
assert difficulty.get_bill_difficulty(-100) == 1 # Negative amount
|
|
37
|
+
assert difficulty.get_bill_difficulty(999999999999) == 9 # Huge number
|
|
38
|
+
|
|
39
|
+
# Test boundary values for each tier
|
|
40
|
+
assert difficulty.get_bill_difficulty(1) == 1 # Tier 1 upper bound
|
|
41
|
+
assert difficulty.get_bill_difficulty(10) == 2 # Tier 2 upper bound
|
|
42
|
+
assert difficulty.get_bill_difficulty(100) == 3 # Tier 3 upper bound
|
|
43
|
+
assert difficulty.get_bill_difficulty(1000) == 4 # Tier 4 upper bound
|
|
44
|
+
assert difficulty.get_bill_difficulty(10000) == 5 # Tier 5 upper bound
|
|
45
|
+
assert difficulty.get_bill_difficulty(100000) == 6 # Tier 6 upper bound
|
|
46
|
+
assert difficulty.get_bill_difficulty(1000000) == 7 # Tier 7 upper bound
|
|
47
|
+
assert difficulty.get_bill_difficulty(10000000) == 8 # Tier 8 upper bound
|
|
48
|
+
|
|
49
|
+
# Test transaction edge cases
|
|
50
|
+
assert difficulty.get_transaction_difficulty(0) == 1 # Zero amount
|
|
51
|
+
assert difficulty.get_transaction_difficulty(-50) == 1 # Negative amount
|
|
52
|
+
assert difficulty.get_transaction_difficulty(999999999) == 9 # Huge amount
|
|
53
|
+
|
|
54
|
+
# Test difficulty names for all tiers
|
|
55
|
+
assert difficulty.get_difficulty_name(1) == "Trivial"
|
|
56
|
+
assert difficulty.get_difficulty_name(2) == "Very Easy"
|
|
57
|
+
assert difficulty.get_difficulty_name(3) == "Easy"
|
|
58
|
+
assert difficulty.get_difficulty_name(4) == "Moderate"
|
|
59
|
+
assert difficulty.get_difficulty_name(5) == "Standard"
|
|
60
|
+
assert difficulty.get_difficulty_name(6) == "Challenging"
|
|
61
|
+
assert difficulty.get_difficulty_name(7) == "Hard"
|
|
62
|
+
assert difficulty.get_difficulty_name(8) == "Very Hard"
|
|
63
|
+
assert difficulty.get_difficulty_name(9) == "Extreme"
|
|
64
|
+
assert difficulty.get_difficulty_name(999) == "Unknown" # Invalid level
|
|
65
|
+
|
|
66
|
+
# Test difficulty colors
|
|
67
|
+
assert difficulty.get_difficulty_color(1) == "🟢"
|
|
68
|
+
assert difficulty.get_difficulty_color(5) == "🟠"
|
|
69
|
+
assert difficulty.get_difficulty_color(9) == "💀"
|
|
70
|
+
|
|
71
|
+
# Test mining rewards with 9-tier system
|
|
72
|
+
reward_fast = difficulty.calculate_mining_reward(1000, 5) # 5 seconds - 50% bonus
|
|
73
|
+
reward_medium = difficulty.calculate_mining_reward(1000, 15) # 15 seconds - 20% bonus
|
|
74
|
+
reward_slow = difficulty.calculate_mining_reward(1000, 60) # 60 seconds - no bonus
|
|
75
|
+
|
|
76
|
+
assert reward_fast > reward_medium > reward_slow
|
|
77
|
+
assert reward_fast == 1500.0 # 1000 * 1.5
|
|
78
|
+
assert reward_medium == 1200.0 # 1000 * 1.2
|
|
79
|
+
assert reward_slow == 1000.0 # 1000 * 1.0
|
|
80
|
+
|
|
81
|
+
# Test expected mining time calculations for different tiers
|
|
82
|
+
time_trivial = difficulty.get_expected_mining_time(1, 1000000)
|
|
83
|
+
time_easy = difficulty.get_expected_mining_time(3, 1000000)
|
|
84
|
+
time_standard = difficulty.get_expected_mining_time(5, 1000000)
|
|
85
|
+
time_hard = difficulty.get_expected_mining_time(7, 1000000)
|
|
86
|
+
time_extreme = difficulty.get_expected_mining_time(9, 1000000)
|
|
87
|
+
|
|
88
|
+
# Higher difficulty should take exponentially longer
|
|
89
|
+
assert time_extreme > time_hard > time_standard > time_easy > time_trivial
|
|
90
|
+
|
|
91
|
+
# Test invalid difficulty levels
|
|
92
|
+
assert difficulty.get_expected_mining_time(0, 1000000) == float('inf')
|
|
93
|
+
assert difficulty.get_expected_mining_time(10, 1000000) == float('inf')
|
|
94
|
+
|
|
95
|
+
def test_mining_reward_calculation(self):
|
|
96
|
+
"""Test mining reward calculations with 9-tier system"""
|
|
97
|
+
difficulty = DifficultySystem()
|
|
98
|
+
|
|
99
|
+
# Test base rewards for different denominations
|
|
100
|
+
reward_small = difficulty.calculate_mining_reward(10, 10) # Small bill, fast mining
|
|
101
|
+
reward_medium = difficulty.calculate_mining_reward(1000, 10) # Medium bill, fast mining
|
|
102
|
+
reward_large = difficulty.calculate_mining_reward(100000, 10) # Large bill, fast mining
|
|
103
|
+
|
|
104
|
+
# Test time-based bonuses across different tiers
|
|
105
|
+
reward_ultra_fast = difficulty.calculate_mining_reward(1000, 2) # 2 seconds - 50% bonus
|
|
106
|
+
reward_fast = difficulty.calculate_mining_reward(1000, 5) # 5 seconds - 50% bonus
|
|
107
|
+
reward_medium_time = difficulty.calculate_mining_reward(1000, 15) # 15 seconds - 20% bonus
|
|
108
|
+
reward_slow = difficulty.calculate_mining_reward(1000, 35) # 35 seconds - no bonus
|
|
109
|
+
reward_very_slow = difficulty.calculate_mining_reward(1000, 70) # 70 seconds - no bonus
|
|
110
|
+
|
|
111
|
+
# Verify bonus tiers work correctly
|
|
112
|
+
assert reward_ultra_fast == reward_fast == 1500.0 # Both get 50% bonus
|
|
113
|
+
assert reward_medium_time == 1200.0 # 20% bonus
|
|
114
|
+
assert reward_slow == reward_very_slow == 1000.0 # No bonus
|
|
115
|
+
|
|
116
|
+
# Verify faster mining always gives better rewards
|
|
117
|
+
assert reward_ultra_fast > reward_medium_time > reward_slow
|
|
118
|
+
|
|
119
|
+
# Test edge cases
|
|
120
|
+
zero_reward = difficulty.calculate_mining_reward(0, 5)
|
|
121
|
+
negative_reward = difficulty.calculate_mining_reward(-100, 5)
|
|
122
|
+
assert zero_reward == 0
|
|
123
|
+
assert negative_reward == 0
|
|
124
|
+
|
|
125
|
+
@patch('lunalib.mining.miner.GenesisMiner._perform_mining')
|
|
126
|
+
def test_bill_mining_success(self, mock_mining, test_miner, test_wallet):
|
|
127
|
+
"""Test successful bill mining across different tiers"""
|
|
128
|
+
wallet, wallet_data = test_wallet
|
|
129
|
+
|
|
130
|
+
# Test mining for different difficulty tiers
|
|
131
|
+
test_cases = [
|
|
132
|
+
(10, 2), # Very Easy tier
|
|
133
|
+
(100, 3), # Easy tier
|
|
134
|
+
(1000, 4), # Moderate tier
|
|
135
|
+
(10000, 5), # Standard tier
|
|
136
|
+
]
|
|
137
|
+
|
|
138
|
+
for denomination, expected_difficulty in test_cases:
|
|
139
|
+
# Mock successful mining
|
|
140
|
+
mock_mining.return_value = {
|
|
141
|
+
"success": True,
|
|
142
|
+
"hash": "0" * expected_difficulty + "abc123",
|
|
143
|
+
"nonce": 12345,
|
|
144
|
+
"mining_time": 2.5
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
result = test_miner.mine_bill(denomination, wallet_data['address'])
|
|
148
|
+
|
|
149
|
+
assert result['success'] is True
|
|
150
|
+
assert result['denomination'] == denomination
|
|
151
|
+
assert result['luna_value'] == denomination # 1:1 ratio
|
|
152
|
+
assert 'bill_serial' in result
|
|
153
|
+
assert 'mining_time' in result
|
|
154
|
+
|
|
155
|
+
@patch('lunalib.mining.miner.GenesisMiner._perform_mining')
|
|
156
|
+
def test_high_difficulty_mining(self, mock_mining, test_miner, test_wallet):
|
|
157
|
+
"""Test mining for high difficulty tiers"""
|
|
158
|
+
wallet, wallet_data = test_wallet
|
|
159
|
+
|
|
160
|
+
# Test high difficulty bills
|
|
161
|
+
high_tier_cases = [
|
|
162
|
+
(100000, 6), # Challenging tier
|
|
163
|
+
(1000000, 7), # Hard tier
|
|
164
|
+
(10000000, 8), # Very Hard tier
|
|
165
|
+
]
|
|
166
|
+
|
|
167
|
+
for denomination, expected_difficulty in high_tier_cases:
|
|
168
|
+
mock_mining.return_value = {
|
|
169
|
+
"success": True,
|
|
170
|
+
"hash": "0" * expected_difficulty + "def456",
|
|
171
|
+
"nonce": 99999,
|
|
172
|
+
"mining_time": 30.0 # Longer mining time for higher difficulty
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
result = test_miner.mine_bill(denomination, wallet_data['address'])
|
|
176
|
+
|
|
177
|
+
assert result['success'] is True
|
|
178
|
+
assert result['denomination'] == denomination
|
|
179
|
+
# High denomination bills might have additional validation
|
|
180
|
+
assert result['luna_value'] >= denomination
|
|
181
|
+
|
|
182
|
+
def test_mining_stop_functionality(self, test_miner):
|
|
183
|
+
"""Test mining stop functionality"""
|
|
184
|
+
# Test starting and stopping mining
|
|
185
|
+
test_miner.mining_active = True
|
|
186
|
+
assert test_miner.mining_active is True
|
|
187
|
+
|
|
188
|
+
test_miner.stop_mining()
|
|
189
|
+
assert test_miner.mining_active is False
|
|
190
|
+
|
|
191
|
+
# Test stopping when already stopped
|
|
192
|
+
test_miner.stop_mining()
|
|
193
|
+
assert test_miner.mining_active is False
|
|
194
|
+
|
|
195
|
+
def test_invalid_denomination(self, test_miner, test_wallet):
|
|
196
|
+
"""Test mining with invalid denominations"""
|
|
197
|
+
wallet, wallet_data = test_wallet
|
|
198
|
+
|
|
199
|
+
invalid_denominations = [
|
|
200
|
+
-100, # Negative
|
|
201
|
+
0, # Zero
|
|
202
|
+
999, # Unusual amount
|
|
203
|
+
-999999, # Large negative
|
|
204
|
+
]
|
|
205
|
+
|
|
206
|
+
for invalid_denom in invalid_denominations:
|
|
207
|
+
result = test_miner.mine_bill(invalid_denom, wallet_data['address'])
|
|
208
|
+
assert result['success'] is False
|
|
209
|
+
assert 'error' in result
|
|
210
|
+
|
|
211
|
+
@patch('lunalib.mining.miner.GenesisMiner._perform_mining')
|
|
212
|
+
def test_mining_failure(self, mock_mining, test_miner, test_wallet):
|
|
213
|
+
"""Test mining failure scenarios"""
|
|
214
|
+
wallet, wallet_data = test_wallet
|
|
215
|
+
|
|
216
|
+
# Mock mining failure
|
|
217
|
+
mock_mining.return_value = {
|
|
218
|
+
"success": False,
|
|
219
|
+
"error": "Mining timeout"
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
result = test_miner.mine_bill(100, wallet_data['address'])
|
|
223
|
+
|
|
224
|
+
assert result['success'] is False
|
|
225
|
+
assert 'error' in result
|
|
226
|
+
|
|
227
|
+
def test_difficulty_progression(self):
|
|
228
|
+
"""Test that difficulty progression makes sense"""
|
|
229
|
+
difficulty = DifficultySystem()
|
|
230
|
+
|
|
231
|
+
# Test that each tier is more difficult than the previous
|
|
232
|
+
for i in range(1, 9):
|
|
233
|
+
time_lower = difficulty.get_expected_mining_time(i, 1000000)
|
|
234
|
+
time_higher = difficulty.get_expected_mining_time(i + 1, 1000000)
|
|
235
|
+
assert time_higher > time_lower, f"Tier {i+1} should be harder than tier {i}"
|
|
236
|
+
|
|
237
|
+
def test_mining_auto_stop(self, test_miner):
|
|
238
|
+
"""Test that mining can be stopped automatically"""
|
|
239
|
+
test_miner.start_auto_mining([100, 200, 300], "test_address")
|
|
240
|
+
assert test_miner.mining_active is True
|
|
241
|
+
|
|
242
|
+
# Stop mining and verify
|
|
243
|
+
test_miner.stop_mining()
|
|
244
|
+
assert test_miner.mining_active is False
|