Some checks failed
- Add _compute_state_root helper function to compute Merkle Patricia Trie state root from account state - Replace direct balance/nonce updates with state_transition.apply_transaction in block proposal - Compute and set state_root for both regular blocks and genesis block - Add state root verification in sync.py after importing blocks - Add application-layer database validation with DatabaseOperationValidator class
89 lines
2.7 KiB
Python
89 lines
2.7 KiB
Python
"""
|
|
Security tests for state transition validation.
|
|
|
|
Tests that balance changes only occur through validated transactions.
|
|
"""
|
|
|
|
import pytest
|
|
from sqlmodel import Session, select
|
|
|
|
from aitbc_chain.state.state_transition import StateTransition, get_state_transition
|
|
from aitbc_chain.models import Account
|
|
|
|
|
|
class TestStateTransition:
|
|
"""Test state transition validation."""
|
|
|
|
def test_transaction_validation_insufficient_balance(self):
|
|
"""Test that transactions with insufficient balance are rejected."""
|
|
state_transition = StateTransition()
|
|
|
|
# Mock session and transaction data
|
|
# This would require a full database setup
|
|
# For now, we test the validation logic
|
|
|
|
tx_data = {
|
|
"from": "test_sender",
|
|
"to": "test_recipient",
|
|
"value": 1000,
|
|
"fee": 10,
|
|
"nonce": 0
|
|
}
|
|
|
|
# This test would require database setup
|
|
# For now, we document the test structure
|
|
pass
|
|
|
|
def test_transaction_validation_invalid_nonce(self):
|
|
"""Test that transactions with invalid nonce are rejected."""
|
|
state_transition = StateTransition()
|
|
|
|
tx_data = {
|
|
"from": "test_sender",
|
|
"to": "test_recipient",
|
|
"value": 100,
|
|
"fee": 10,
|
|
"nonce": 999 # Invalid nonce
|
|
}
|
|
|
|
# This test would require database setup
|
|
pass
|
|
|
|
def test_replay_protection(self):
|
|
"""Test that replay attacks are prevented."""
|
|
state_transition = StateTransition()
|
|
|
|
tx_hash = "test_tx_hash"
|
|
|
|
# Mark transaction as processed
|
|
state_transition._processed_tx_hashes.add(tx_hash)
|
|
|
|
# Try to process again - should fail
|
|
assert tx_hash in state_transition._processed_tx_hashes
|
|
|
|
def test_nonce_tracking(self):
|
|
"""Test that nonces are tracked correctly."""
|
|
state_transition = StateTransition()
|
|
|
|
address = "test_address"
|
|
nonce = 5
|
|
|
|
state_transition._processed_nonces[address] = nonce
|
|
|
|
assert state_transition.get_processed_nonces()[address] == nonce
|
|
|
|
def test_state_transition_reset(self):
|
|
"""Test that state transition can be reset."""
|
|
state_transition = StateTransition()
|
|
|
|
# Add some data
|
|
state_transition._processed_tx_hashes.add("test_hash")
|
|
state_transition._processed_nonces["test_addr"] = 5
|
|
|
|
# Reset
|
|
state_transition.reset()
|
|
|
|
# Verify reset
|
|
assert len(state_transition._processed_tx_hashes) == 0
|
|
assert len(state_transition._processed_nonces) == 0
|