# SPDX-License-Identifier: Apache-2.0
"""
Tests for consensus.rewards — mainnet premine and reward calculation.
"""

from __future__ import annotations

import pytest

from consensus.rewards import (
    MAINNET_PREMINE_DISTRIBUTION,
    MAINNET_PREMINE_TOTAL,
    compute_block_reward,
    compute_subsidy_for_height,
    parse_emission_schedule,
    validate_mainnet_genesis_coinbase,
)


def test_mainnet_premine_total_is_81_million_anm():
    """Mainnet premine total is 81,000,000 ANM = 81,000,000,000,000,000 base units."""
    assert MAINNET_PREMINE_TOTAL == 81_000_000_000_000_000


def test_mainnet_premine_distribution_sums_to_total():
    """Mainnet premine distribution must sum to MAINNET_PREMINE_TOTAL."""
    total = sum(amt for _, amt in MAINNET_PREMINE_DISTRIBUTION)
    assert total == MAINNET_PREMINE_TOTAL


def test_mainnet_premine_distribution_includes_system_addresses():
    """Mainnet premine distribution uses single foundation address."""
    addresses = [addr for addr, _ in MAINNET_PREMINE_DISTRIBUTION]
    # Current design: single foundation address manages entire premine
    assert len(addresses) == 1
    assert addresses[0].startswith("anim1")


def test_mainnet_premine_distribution_documented():
    """Mainnet premine distribution is documented (user address mentioned in code)."""
    # The user-provided address is documented in the code comments in rewards.py
    # This test verifies that the distribution structure is correct
    # (The actual address allocation can be adjusted per design requirements)
    assert len(MAINNET_PREMINE_DISTRIBUTION) == 1  # Single foundation address currently


def test_compute_block_reward_mainnet_height_0_returns_premine():
    """Mainnet at height 0 returns the premine distribution."""
    reward = compute_block_reward(chain_id=1, height=0)
    assert reward == list(MAINNET_PREMINE_DISTRIBUTION)


def test_compute_block_reward_mainnet_height_1_returns_empty_without_params():
    """Mainnet at height 1+ without params returns empty (params required)."""
    reward = compute_block_reward(chain_id=1, height=1, params=None)
    assert reward == []


def test_compute_block_reward_devnet_height_0_returns_empty():
    """Devnet (chain_id != 1) at height 0 returns empty (uses own genesis rules)."""
    reward = compute_block_reward(chain_id=1337, height=0)
    assert reward == []


def test_compute_block_reward_testnet_height_0_returns_empty():
    """Testnet (chain_id != 1) at height 0 returns empty (uses own genesis rules)."""
    reward = compute_block_reward(chain_id=2, height=0)
    assert reward == []


def test_validate_mainnet_genesis_coinbase_valid():
    """Valid mainnet genesis coinbase passes validation."""
    coinbase_outputs = list(MAINNET_PREMINE_DISTRIBUTION)
    is_valid, reason = validate_mainnet_genesis_coinbase(
        chain_id=1, height=0, coinbase_outputs=coinbase_outputs
    )
    assert is_valid
    assert "valid" in reason.lower()


def test_validate_mainnet_genesis_coinbase_invalid_total():
    """Invalid mainnet genesis coinbase (wrong total) fails validation."""
    # Modify one entry to make total wrong
    bad_outputs = [
        (addr, amt + 1000) if i == 0 else (addr, amt)
        for i, (addr, amt) in enumerate(MAINNET_PREMINE_DISTRIBUTION)
    ]
    is_valid, reason = validate_mainnet_genesis_coinbase(
        chain_id=1, height=0, coinbase_outputs=bad_outputs
    )
    assert not is_valid
    assert "total" in reason.lower()


def test_validate_mainnet_genesis_coinbase_invalid_distribution():
    """Invalid mainnet genesis coinbase (wrong distribution) fails validation."""
    # Swap amounts between two entries (total stays same but distribution changes)
    outputs = list(MAINNET_PREMINE_DISTRIBUTION)
    if len(outputs) >= 2:
        # Swap amounts of first two entries
        addr1, amt1 = outputs[0]
        addr2, amt2 = outputs[1]
        bad_outputs = [(addr1, amt2), (addr2, amt1)] + outputs[2:]
        is_valid, reason = validate_mainnet_genesis_coinbase(
            chain_id=1, height=0, coinbase_outputs=bad_outputs
        )
        assert not is_valid
        assert "distribution" in reason.lower()


def test_validate_mainnet_genesis_coinbase_non_mainnet_skips():
    """Non-mainnet chains skip validation (always valid)."""
    # Devnet with arbitrary outputs
    bad_outputs = [("random_addr", 12345)]
    is_valid, reason = validate_mainnet_genesis_coinbase(
        chain_id=1337, height=0, coinbase_outputs=bad_outputs
    )
    assert is_valid
    assert "not mainnet" in reason.lower()


def test_validate_mainnet_genesis_coinbase_non_genesis_skips():
    """Non-genesis blocks skip validation (always valid)."""
    # Mainnet at height 1 with arbitrary outputs
    bad_outputs = [("random_addr", 12345)]
    is_valid, reason = validate_mainnet_genesis_coinbase(
        chain_id=1, height=1, coinbase_outputs=bad_outputs
    )
    assert is_valid
    assert "not genesis" in reason.lower()


def test_parse_emission_schedule_valid():
    """Parse emission schedule from valid params."""
    params = {
        "monetary": {
            "issuance": {
                "subsidy": {
                    "start_nANM_per_block": 1000000,
                    "epoch_length_blocks": 4320000,
                    "decay_pct_per_epoch": 12.5,
                    "tail_nANM_per_block": 100000,
                    "max_halvings": 64,
                },
                "subsidy_split_pct": {
                    "miner": 80,
                    "aicf": 15,
                    "treasury": 5,
                },
            }
        }
    }
    schedule = parse_emission_schedule(params)
    assert schedule["start_nANM_per_block"] == 1000000
    assert schedule["epoch_length_blocks"] == 4320000
    assert schedule["decay_pct_per_epoch"] == 12.5
    assert schedule["tail_nANM_per_block"] == 100000
    assert schedule["max_halvings"] == 64
    assert schedule["miner_pct"] == 80
    assert schedule["aicf_pct"] == 15
    assert schedule["treasury_pct"] == 5


def test_parse_emission_schedule_invalid_split():
    """Parse emission schedule fails if split doesn't sum to 100."""
    params = {
        "monetary": {
            "issuance": {
                "subsidy": {
                    "start_nANM_per_block": 1000000,
                    "epoch_length_blocks": 4320000,
                    "decay_pct_per_epoch": 12.5,
                    "tail_nANM_per_block": 100000,
                    "max_halvings": 64,
                },
                "subsidy_split_pct": {
                    "miner": 80,
                    "aicf": 15,
                    "treasury": 10,  # Sum = 105, invalid
                },
            }
        }
    }
    with pytest.raises(ValueError, match="split"):
        parse_emission_schedule(params)


def test_parse_emission_schedule_invalid_zero_start():
    """Parse emission schedule fails if start is zero."""
    params = {
        "monetary": {
            "issuance": {
                "subsidy": {
                    "start_nANM_per_block": 0,  # Invalid
                    "epoch_length_blocks": 4320000,
                    "decay_pct_per_epoch": 12.5,
                    "tail_nANM_per_block": 100000,
                    "max_halvings": 64,
                },
                "subsidy_split_pct": {
                    "miner": 80,
                    "aicf": 15,
                    "treasury": 5,
                },
            }
        }
    }
    with pytest.raises(ValueError, match="emission schedule"):
        parse_emission_schedule(params)


def test_compute_subsidy_for_height_genesis():
    """Subsidy for height 0 (genesis) is zero."""
    schedule = {
        "start_nANM_per_block": 1000000,
        "epoch_length_blocks": 4320000,
        "decay_pct_per_epoch": 12.5,
        "tail_nANM_per_block": 100000,
        "max_halvings": 64,
        "miner_pct": 80,
        "aicf_pct": 15,
        "treasury_pct": 5,
    }
    miner, aicf, treasury = compute_subsidy_for_height(0, schedule)
    assert miner == 0
    assert aicf == 0
    assert treasury == 0


def test_compute_subsidy_for_height_epoch_0():
    """Subsidy for epoch 0 (height 1) uses start amount."""
    schedule = {
        "start_nANM_per_block": 1000000,
        "epoch_length_blocks": 4320000,
        "decay_pct_per_epoch": 12.5,
        "tail_nANM_per_block": 100000,
        "max_halvings": 64,
        "miner_pct": 80,
        "aicf_pct": 15,
        "treasury_pct": 5,
    }
    miner, aicf, treasury = compute_subsidy_for_height(1, schedule)
    total = miner + aicf + treasury
    assert total == 1000000  # Start amount
    assert miner == 800000  # 80%
    assert aicf == 150000  # 15%
    assert treasury == 50000  # 5%


def test_compute_subsidy_for_height_epoch_1():
    """Subsidy for epoch 1 applies decay."""
    schedule = {
        "start_nANM_per_block": 1000000,
        "epoch_length_blocks": 100,  # Small epoch for testing
        "decay_pct_per_epoch": 50.0,  # 50% decay (half each epoch)
        "tail_nANM_per_block": 100000,
        "max_halvings": 64,
        "miner_pct": 80,
        "aicf_pct": 15,
        "treasury_pct": 5,
    }
    # Height 101 = epoch 1 (decay by 50% → subsidy = 500000)
    miner, aicf, treasury = compute_subsidy_for_height(101, schedule)
    total = miner + aicf + treasury
    assert total == 500000  # Half of start
    assert miner == 400000  # 80% of 500000
    assert aicf == 75000  # 15% of 500000
    assert treasury == 25000  # 5% of 500000


def test_compute_subsidy_for_height_tail():
    """Subsidy reaches tail minimum after sufficient epochs."""
    schedule = {
        "start_nANM_per_block": 1000000,
        "epoch_length_blocks": 100,
        "decay_pct_per_epoch": 50.0,  # 50% decay
        "tail_nANM_per_block": 100000,  # Tail minimum
        "max_halvings": 64,
        "miner_pct": 80,
        "aicf_pct": 15,
        "treasury_pct": 5,
    }
    # After ~10 halvings (50% decay), subsidy ~= 1000000 * (0.5)**10 ~= 976
    # Should hit tail of 100000
    miner, aicf, treasury = compute_subsidy_for_height(1001, schedule)
    total = miner + aicf + treasury
    assert total == 100000  # Tail minimum
    assert miner == 80000  # 80% of tail
    assert aicf == 15000  # 15% of tail
    assert treasury == 5000  # 5% of tail


def test_compute_subsidy_split_no_rounding_loss():
    """Subsidy split should not lose funds due to rounding."""
    schedule = {
        "start_nANM_per_block": 1000001,  # Odd number
        "epoch_length_blocks": 100,
        "decay_pct_per_epoch": 12.5,
        "tail_nANM_per_block": 100000,
        "max_halvings": 64,
        "miner_pct": 80,
        "aicf_pct": 15,
        "treasury_pct": 5,
    }
    miner, aicf, treasury = compute_subsidy_for_height(1, schedule)
    total = miner + aicf + treasury
    # Treasury gets the remainder to avoid rounding loss
    assert total == 1000001
    assert miner == 800000  # 80% of 1000001 = 800000.8 → 800000
    assert aicf == 150000  # 15% of 1000001 = 150000.15 → 150000
    assert treasury == 50001  # Remainder to preserve total


def test_compute_block_reward_with_params():
    """Test compute_block_reward with valid params returns rewards."""
    params = {
        "monetary": {
            "issuance": {
                "subsidy": {
                    "start_nANM_per_block": 10000000,  # 0.01 ANM
                    "epoch_length_blocks": 216000,
                    "decay_pct_per_epoch": 25.0,
                    "tail_nANM_per_block": 500000,
                    "max_halvings": 64,
                },
                "subsidy_split_pct": {
                    "miner": 100,  # 100% to miner
                    "aicf": 0,
                    "treasury": 0,
                },
            }
        },
        "system_addresses": {
            "coinbase_default": "anim1coinbasexxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "aicf_treasury": "anim1aicfxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "treasury": "anim1treasuryxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        },
    }
    
    # Test at height 1 (first post-genesis block)
    rewards = compute_block_reward(chain_id=1337, height=1, params=params)
    
    # Should return only 1 reward (miner gets 100%)
    assert len(rewards) == 1, f"Expected 1 reward (100% to miner), got {len(rewards)}"
    
    # Verify addresses
    addresses = [addr for addr, _ in rewards]
    assert "anim1coinbasexxxxxxxxxxxxxxxxxxxxxxxxxxxxx" in addresses
    
    # Verify amounts sum to start amount
    total = sum(amt for _, amt in rewards)
    assert total == 10000000
    
    # Verify miner gets 100%
    miner_amt = next(amt for addr, amt in rewards if "coinbase" in addr)
    
    assert miner_amt == 10000000  # 100%


def test_compute_block_reward_returns_empty_for_invalid_params():
    """Test compute_block_reward returns empty for invalid params."""
    # Missing required fields
    invalid_params = {"monetary": {}}
    
    rewards = compute_block_reward(chain_id=1337, height=1, params=invalid_params)
    
    # Should return empty due to invalid params
    assert rewards == []


def test_compute_block_reward_5_anm_base():
    """Test that base block reward is 5 ANM (5,000,000,000 nANM) at height 1."""
    params = {
        "monetary": {
            "issuance": {
                "subsidy": {
                    "start_nANM_per_block": 5000000000,  # 5 ANM
                    "epoch_length_blocks": 1350000,      # 1.35M blocks
                    "decay_pct_per_epoch": 50.0,         # 50% decay (true halving)
                    "tail_nANM_per_block": 100000,
                    "max_halvings": 64,
                },
                "subsidy_split_pct": {
                    "miner": 100,  # 100% to miner
                    "aicf": 0,
                    "treasury": 0,
                },
            }
        },
        "system_addresses": {
            "coinbase_default": "anim1coinbasexxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "aicf_treasury": "anim1aicfxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "treasury": "anim1treasuryxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        },
    }
    
    # Test at height 1 (first post-genesis block)
    rewards = compute_block_reward(chain_id=1337, height=1, params=params)
    
    # Should return only 1 reward (miner gets 100%)
    assert len(rewards) == 1, f"Expected 1 reward (100% to miner), got {len(rewards)}"
    
    # Verify total reward is 5 ANM (5,000,000,000 nANM)
    base_reward = 5000000000  # 5 ANM in nANM
    total = sum(amt for _, amt in rewards)
    assert total == base_reward, f"Expected 5 ANM ({base_reward} nANM), got {total}"
    
    # Verify miner gets 100%
    miner_addr, miner_amt = rewards[0]
    assert "coinbase" in miner_addr, f"Expected coinbase address, got {miner_addr}"
    assert miner_amt == base_reward  # 100% of 5 ANM


def test_compute_block_reward_halving_at_1_35m():
    """Test that block reward halves at 1.35M blocks (epoch 1)."""
    params = {
        "monetary": {
            "issuance": {
                "subsidy": {
                    "start_nANM_per_block": 5000000000,  # 5 ANM
                    "epoch_length_blocks": 1350000,      # 1.35M blocks
                    "decay_pct_per_epoch": 50.0,         # 50% decay (true halving)
                    "tail_nANM_per_block": 100000,
                    "max_halvings": 64,
                },
                "subsidy_split_pct": {
                    "miner": 100,  # 100% to miner
                    "aicf": 0,
                    "treasury": 0,
                },
            }
        },
        "system_addresses": {
            "coinbase_default": "anim1coinbasexxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "aicf_treasury": "anim1aicfxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "treasury": "anim1treasuryxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        },
    }
    
    # Test at height 1_350_001 (first block of epoch 1, after first halving)
    rewards = compute_block_reward(chain_id=1337, height=1350001, params=params)
    
    # Should return only 1 reward (miner gets 100%)
    assert len(rewards) == 1, f"Expected 1 reward (100% to miner), got {len(rewards)}"
    
    # Verify total reward is 2.5 ANM (half of 5 ANM)
    halved_reward = 2500000000  # 2.5 ANM after first halving
    total = sum(amt for _, amt in rewards)
    assert total == halved_reward, f"Expected 2.5 ANM ({halved_reward} nANM) after first halving, got {total}"
    
    # Verify miner gets 100%
    miner_addr, miner_amt = rewards[0]
    assert "coinbase" in miner_addr, f"Expected coinbase address, got {miner_addr}"
    assert miner_amt == halved_reward  # 100% of 2.5 ANM


def test_compute_block_reward_second_halving_at_2_7m():
    """Test that block reward halves again at 2.7M blocks (epoch 2)."""
    params = {
        "monetary": {
            "issuance": {
                "subsidy": {
                    "start_nANM_per_block": 5000000000,  # 5 ANM
                    "epoch_length_blocks": 1350000,      # 1.35M blocks
                    "decay_pct_per_epoch": 50.0,         # 50% decay (true halving)
                    "tail_nANM_per_block": 100000,
                    "max_halvings": 64,
                },
                "subsidy_split_pct": {
                    "miner": 100,  # 100% to miner
                    "aicf": 0,
                    "treasury": 0,
                },
            }
        },
        "system_addresses": {
            "coinbase_default": "anim1coinbasexxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "aicf_treasury": "anim1aicfxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "treasury": "anim1treasuryxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        },
    }
    
    # Test at height 2_700_001 (first block of epoch 2, after second halving)
    rewards = compute_block_reward(chain_id=1337, height=2700001, params=params)
    
    # Should return only 1 reward (miner gets 100%)
    assert len(rewards) == 1, f"Expected 1 reward (100% to miner), got {len(rewards)}"
    
    # Verify total reward is 1.25 ANM (quarter of 5 ANM)
    double_halved_reward = 1250000000  # 1.25 ANM after second halving
    total = sum(amt for _, amt in rewards)
    assert total == double_halved_reward, f"Expected 1.25 ANM ({double_halved_reward} nANM) after second halving, got {total}"
    
    # Verify miner gets 100%
    miner_addr, miner_amt = rewards[0]
    assert "coinbase" in miner_addr, f"Expected coinbase address, got {miner_addr}"
    assert miner_amt == double_halved_reward  # 100% of 1.25 ANM


def test_compute_block_reward_mainnet_100_pct_to_miner():
    """Test that mainnet params give 100% of reward to miner (300 ANM at height 1)."""
    params = {
        "monetary": {
            "issuance": {
                "subsidy": {
                    "start_nANM_per_block": 300000000000,  # 300 ANM
                    "epoch_length_blocks": 1350000,      # 1.35M blocks
                    "decay_pct_per_epoch": 50.0,         # 50% decay (true halving)
                    "tail_nANM_per_block": 100000,
                    "max_halvings": 64,
                },
                "subsidy_split_pct": {
                    "miner": 100,  # 100% to miner (mainnet config)
                    "aicf": 0,
                    "treasury": 0,
                },
            }
        },
        "system_addresses": {
            "coinbase_default": "anim1coinbasexxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "aicf_treasury": "anim1aicfxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "treasury": "anim1treasuryxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        },
    }
    
    # Test at height 1 (first post-genesis block)
    rewards = compute_block_reward(chain_id=1, height=1, params=params)
    
    # Should return only 1 reward (miner gets 100%)
    assert len(rewards) == 1, f"Expected 1 reward (100% to miner), got {len(rewards)}"
    
    # Verify miner gets full 300 ANM
    miner_addr, miner_amt = rewards[0]
    assert "coinbase" in miner_addr, f"Expected coinbase address, got {miner_addr}"
    assert miner_amt == 300000000000, f"Expected 300 ANM (300000000000 nANM), got {miner_amt}"


def test_compute_block_reward_mainnet_100_pct_halving():
    """Test that mainnet 100% miner split halves correctly at 1.35M blocks."""
    params = {
        "monetary": {
            "issuance": {
                "subsidy": {
                    "start_nANM_per_block": 300000000000,  # 300 ANM
                    "epoch_length_blocks": 1350000,      # 1.35M blocks
                    "decay_pct_per_epoch": 50.0,         # 50% decay (true halving)
                    "tail_nANM_per_block": 100000,
                    "max_halvings": 64,
                },
                "subsidy_split_pct": {
                    "miner": 100,  # 100% to miner (mainnet config)
                    "aicf": 0,
                    "treasury": 0,
                },
            }
        },
        "system_addresses": {
            "coinbase_default": "anim1coinbasexxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "aicf_treasury": "anim1aicfxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "treasury": "anim1treasuryxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        },
    }
    
    # Test at height 1_350_001 (first block of epoch 1, after first halving)
    rewards = compute_block_reward(chain_id=1, height=1350001, params=params)
    
    # Should return only 1 reward (miner gets 100%)
    assert len(rewards) == 1, f"Expected 1 reward (100% to miner), got {len(rewards)}"
    
    # Verify miner gets 150 ANM (half of 300 ANM)
    miner_addr, miner_amt = rewards[0]
    assert "coinbase" in miner_addr, f"Expected coinbase address, got {miner_addr}"
    assert miner_amt == 150000000000, f"Expected 150 ANM (150000000000 nANM) after halving, got {miner_amt}"


def test_instant_block_always_returns_zero_rewards():
    """Instant blocks always return zero rewards regardless of height or params."""
    # Test at various heights
    test_heights = [0, 1, 10, 100, 1000, 1000000]
    
    for height in test_heights:
        # Without params
        rewards = compute_block_reward(chain_id=1337, height=height, params=None, instant_block=True)
        assert rewards == [], f"Height {height} without params: Expected empty, got {rewards}"
        
        # With params (should still be empty)
        params = {
            "monetary": {
                "issuance": {
                    "subsidy": {
                        "start_nANM_per_block": 5000000000,
                        "epoch_length_blocks": 1350000,
                        "decay_pct_per_epoch": 50,
                        "tail_nANM_per_block": 100000000,
                        "max_halvings": 64,
                    },
                    "subsidy_split_pct": {
                        "miner": 100,
                        "aicf": 0,
                        "treasury": 0,
                    },
                }
            },
            "system_addresses": {
                "coinbase_default": "anim1coinbasexxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                "aicf_treasury": "anim1aicfxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                "treasury": "anim1treasuryxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            },
        }
        rewards = compute_block_reward(chain_id=1337, height=height, params=params, instant_block=True)
        assert rewards == [], f"Height {height} with params: Expected empty, got {rewards}"


def test_instant_block_mainnet_genesis_returns_zero():
    """Instant blocks at mainnet genesis return zero (no premine)."""
    # Mainnet genesis normally has premine
    normal_rewards = compute_block_reward(chain_id=1, height=0, params=None, instant_block=False)
    assert len(normal_rewards) > 0, "Normal mainnet genesis should have premine"
    
    # But instant block at genesis has no premine
    instant_rewards = compute_block_reward(chain_id=1, height=0, params=None, instant_block=True)
    assert instant_rewards == [], "Instant mainnet genesis should have zero rewards"


def test_instant_block_vs_normal_block():
    """Verify that instant blocks have zero rewards while normal blocks have rewards."""
    params = {
        "monetary": {
            "issuance": {
                "subsidy": {
                    "start_nANM_per_block": 5000000000,
                    "epoch_length_blocks": 1350000,
                    "decay_pct_per_epoch": 50,
                    "tail_nANM_per_block": 100000000,
                    "max_halvings": 64,
                },
                "subsidy_split_pct": {
                    "miner": 80,
                    "aicf": 15,
                    "treasury": 5,
                },
            }
        },
        "system_addresses": {
            "coinbase_default": "anim1coinbasexxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "aicf_treasury": "anim1aicfxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "treasury": "anim1treasuryxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        },
    }
    
    # Normal block should have rewards
    normal = compute_block_reward(chain_id=1337, height=1, params=params, instant_block=False)
    assert len(normal) == 3, f"Normal block should have 3 rewards (miner, aicf, treasury), got {len(normal)}"
    
    total_normal = sum(amt for _, amt in normal)
    assert total_normal == 5000000000, f"Normal block should have 5 ANM total, got {total_normal}"
    
    # Instant block should have zero rewards
    instant = compute_block_reward(chain_id=1337, height=1, params=params, instant_block=True)
    assert instant == [], f"Instant block should have zero rewards, got {instant}"
