mirror of
https://github.com/Chia-Network/chia-blockchain.git
synced 2024-09-11 18:58:59 +03:00
Change rewards coin ids 2 (#1342)
Replay protection by encoding genesis challenge into coinbase parent ids. Co-authored-by: Yostra <straya@chia.net>
This commit is contained in:
parent
8137ea162c
commit
da57397087
@ -14,7 +14,7 @@ jobs:
|
||||
build:
|
||||
name: MacOS Blockchain Tests
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 90
|
||||
timeout-minutes: 120
|
||||
strategy:
|
||||
fail-fast: false
|
||||
max-parallel: 4
|
||||
@ -58,7 +58,7 @@ jobs:
|
||||
with:
|
||||
repository: 'Chia-Network/test-cache'
|
||||
path: '.chia'
|
||||
ref: '0.24.0'
|
||||
ref: '0.26.0'
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Link home directory
|
||||
|
2
.github/workflows/build-test-macos-core.yml
vendored
2
.github/workflows/build-test-macos-core.yml
vendored
@ -58,7 +58,7 @@ jobs:
|
||||
with:
|
||||
repository: 'Chia-Network/test-cache'
|
||||
path: '.chia'
|
||||
ref: '0.24.0'
|
||||
ref: '0.26.0'
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Link home directory
|
||||
|
@ -58,7 +58,7 @@ jobs:
|
||||
with:
|
||||
repository: 'Chia-Network/test-cache'
|
||||
path: '.chia'
|
||||
ref: '0.24.0'
|
||||
ref: '0.26.0'
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Link home directory
|
||||
|
@ -58,7 +58,7 @@ jobs:
|
||||
with:
|
||||
repository: 'Chia-Network/test-cache'
|
||||
path: '.chia'
|
||||
ref: '0.24.0'
|
||||
ref: '0.26.0'
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Link home directory
|
||||
|
@ -65,7 +65,7 @@ jobs:
|
||||
with:
|
||||
repository: 'Chia-Network/test-cache'
|
||||
path: '.chia'
|
||||
ref: '0.24.0'
|
||||
ref: '0.26.0'
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Link home directory
|
||||
|
2
.github/workflows/build-test-ubuntu-core.yml
vendored
2
.github/workflows/build-test-ubuntu-core.yml
vendored
@ -65,7 +65,7 @@ jobs:
|
||||
with:
|
||||
repository: 'Chia-Network/test-cache'
|
||||
path: '.chia'
|
||||
ref: '0.24.0'
|
||||
ref: '0.26.0'
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Link home directory
|
||||
|
@ -65,7 +65,7 @@ jobs:
|
||||
with:
|
||||
repository: 'Chia-Network/test-cache'
|
||||
path: '.chia'
|
||||
ref: '0.24.0'
|
||||
ref: '0.26.0'
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Link home directory
|
||||
|
@ -65,7 +65,7 @@ jobs:
|
||||
with:
|
||||
repository: 'Chia-Network/test-cache'
|
||||
path: '.chia'
|
||||
ref: '0.24.0'
|
||||
ref: '0.26.0'
|
||||
fetch-depth: 1
|
||||
|
||||
- name: Link home directory
|
||||
|
@ -98,17 +98,18 @@ async def validate_block_body(
|
||||
# Add reward claims for all blocks from the prev prev block, until the prev block (including the latter)
|
||||
prev_transaction_block = blocks.block_record(block.foliage_transaction_block.prev_transaction_block_hash)
|
||||
prev_transaction_block_height = prev_transaction_block.height
|
||||
|
||||
assert prev_transaction_block.fees is not None
|
||||
pool_coin = create_pool_coin(
|
||||
prev_transaction_block.height,
|
||||
prev_transaction_block_height,
|
||||
prev_transaction_block.pool_puzzle_hash,
|
||||
calculate_pool_reward(prev_transaction_block.height),
|
||||
constants.GENESIS_CHALLENGE,
|
||||
)
|
||||
farmer_coin = create_farmer_coin(
|
||||
prev_transaction_block.height,
|
||||
prev_transaction_block_height,
|
||||
prev_transaction_block.farmer_puzzle_hash,
|
||||
uint64(calculate_base_farmer_reward(prev_transaction_block.height) + prev_transaction_block.fees),
|
||||
constants.GENESIS_CHALLENGE,
|
||||
)
|
||||
# Adds the previous block
|
||||
expected_reward_coins.add(pool_coin)
|
||||
@ -123,6 +124,7 @@ async def validate_block_body(
|
||||
curr_b.height,
|
||||
curr_b.pool_puzzle_hash,
|
||||
calculate_pool_reward(curr_b.height),
|
||||
constants.GENESIS_CHALLENGE,
|
||||
)
|
||||
)
|
||||
expected_reward_coins.add(
|
||||
@ -130,6 +132,7 @@ async def validate_block_body(
|
||||
curr_b.height,
|
||||
curr_b.farmer_puzzle_hash,
|
||||
calculate_base_farmer_reward(curr_b.height),
|
||||
constants.GENESIS_CHALLENGE,
|
||||
)
|
||||
)
|
||||
curr_b = blocks.block_record(curr_b.prev_hash)
|
||||
|
@ -148,15 +148,14 @@ def create_foliage(
|
||||
|
||||
assert curr.fees is not None
|
||||
pool_coin = create_pool_coin(
|
||||
curr.height,
|
||||
curr.pool_puzzle_hash,
|
||||
calculate_pool_reward(curr.height),
|
||||
curr.height, curr.pool_puzzle_hash, calculate_pool_reward(curr.height), constants.GENESIS_CHALLENGE
|
||||
)
|
||||
|
||||
farmer_coin = create_farmer_coin(
|
||||
curr.height,
|
||||
curr.farmer_puzzle_hash,
|
||||
uint64(calculate_base_farmer_reward(curr.height) + curr.fees),
|
||||
constants.GENESIS_CHALLENGE,
|
||||
)
|
||||
assert curr.header_hash == prev_transaction_block.header_hash
|
||||
reward_claims_incorporated += [pool_coin, farmer_coin]
|
||||
@ -169,11 +168,13 @@ def create_foliage(
|
||||
curr.height,
|
||||
curr.pool_puzzle_hash,
|
||||
calculate_pool_reward(curr.height),
|
||||
constants.GENESIS_CHALLENGE,
|
||||
)
|
||||
farmer_coin = create_farmer_coin(
|
||||
curr.height,
|
||||
curr.farmer_puzzle_hash,
|
||||
calculate_base_farmer_reward(curr.height),
|
||||
constants.GENESIS_CHALLENGE,
|
||||
)
|
||||
reward_claims_incorporated += [pool_coin, farmer_coin]
|
||||
curr = blocks.block_record(curr.prev_hash)
|
||||
|
@ -2,7 +2,6 @@ from blspy import AugSchemeMPL, G1Element, G2Element, PrivateKey
|
||||
|
||||
from src.types.blockchain_format.coin import Coin
|
||||
from src.types.blockchain_format.sized_bytes import bytes32
|
||||
from src.util.hash import std_hash
|
||||
from src.util.ints import uint32, uint64
|
||||
from src.wallet.puzzles.p2_delegated_puzzle_or_hidden_puzzle import puzzle_for_pk
|
||||
|
||||
@ -22,11 +21,19 @@ def sign_coinbase_coin(coin: Coin, private_key: PrivateKey):
|
||||
return signature_for_coinbase(coin, private_key)
|
||||
|
||||
|
||||
def create_pool_coin(block_index: uint32, puzzle_hash: bytes32, reward: uint64):
|
||||
block_index_as_hash = bytes32(block_index.to_bytes(32, "big"))
|
||||
return Coin(block_index_as_hash, puzzle_hash, reward)
|
||||
def pool_parent_id(block_height: uint32, genesis_challenge: bytes32) -> uint32:
|
||||
return bytes32(genesis_challenge[:16] + block_height.to_bytes(16, "big"))
|
||||
|
||||
|
||||
def create_farmer_coin(block_index: uint32, puzzle_hash: bytes32, reward: uint64):
|
||||
block_index_as_hash = std_hash(std_hash(block_index.to_bytes(4, "big")))
|
||||
return Coin(block_index_as_hash, puzzle_hash, reward)
|
||||
def farmer_parent_id(block_height: uint32, genesis_challenge: bytes32) -> uint32:
|
||||
return bytes32(genesis_challenge[16:] + block_height.to_bytes(16, "big"))
|
||||
|
||||
|
||||
def create_pool_coin(block_height: uint32, puzzle_hash: bytes32, reward: uint64, genesis_challenge: bytes32):
|
||||
parent_id = pool_parent_id(block_height, genesis_challenge)
|
||||
return Coin(parent_id, puzzle_hash, reward)
|
||||
|
||||
|
||||
def create_farmer_coin(block_height: uint32, puzzle_hash: bytes32, reward: uint64, genesis_challenge: bytes32):
|
||||
parent_id = farmer_parent_id(block_height, genesis_challenge)
|
||||
return Coin(parent_id, puzzle_hash, reward)
|
||||
|
@ -1,4 +1,3 @@
|
||||
from src.types.blockchain_format.sized_bytes import bytes32
|
||||
from src.util.ints import uint64
|
||||
|
||||
from .constants import ConsensusConstants
|
||||
@ -28,12 +27,13 @@ testnet_kwargs = {
|
||||
"NUMBER_OF_TIMESTAMPS": 11, # Than the average of the last NUMBER_OF_TIMESTAMPS blocks
|
||||
# Used as the initial cc rc challenges, as well as first block back pointers, and first SES back pointer
|
||||
# We override this value based on the chain being run (testnet0, testnet1, mainnet, etc)
|
||||
"GENESIS_CHALLENGE": bytes32([0x00] * 32),
|
||||
# Default used for tests is std_hash(b'')
|
||||
"GENESIS_CHALLENGE": bytes.fromhex("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"),
|
||||
"GENESIS_PRE_FARM_POOL_PUZZLE_HASH": bytes.fromhex(
|
||||
"bc4fd6c394fe90c6097afbfa6ab5927743e2210ecf689dad477be8eb408745d5"
|
||||
"d23da14695a188ae5708dd152263c4db883eb27edeb936178d4d988b8f3ce5fc"
|
||||
),
|
||||
"GENESIS_PRE_FARM_FARMER_PUZZLE_HASH": bytes.fromhex(
|
||||
"4ad98e66a019f11b60a8279514d13105b65588865e2a8e794b5b73d5646174f6"
|
||||
"3d8765d3a597ec1d99663f6c9816d915b9f68613ac94009884c4addaefcce6af"
|
||||
),
|
||||
"MAX_VDF_WITNESS_SIZE": 64,
|
||||
# Target tx count per sec
|
||||
|
@ -727,7 +727,7 @@ class WalletRpcApi:
|
||||
fee_amount = 0
|
||||
last_height_farmed = 0
|
||||
for record in tx_records:
|
||||
height = record.height_farmed()
|
||||
height = record.height_farmed(self.service.constants.GENESIS_CHALLENGE)
|
||||
if height > last_height_farmed:
|
||||
last_height_farmed = height
|
||||
if record.type == TransactionType.COINBASE_REWARD:
|
||||
|
@ -14,8 +14,10 @@ network_overrides: &network_overrides
|
||||
GENESIS_CHALLENGE: null
|
||||
testnet0:
|
||||
MIN_PLOT_SIZE: 18
|
||||
GENESIS_CHALLENGE: "0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||
GENESIS_CHALLENGE: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
NETWORK_TYPE: 1
|
||||
GENESIS_PRE_FARM_POOL_PUZZLE_HASH: "d23da14695a188ae5708dd152263c4db883eb27edeb936178d4d988b8f3ce5fc"
|
||||
GENESIS_PRE_FARM_FARMER_PUZZLE_HASH: "3d8765d3a597ec1d99663f6c9816d915b9f68613ac94009884c4addaefcce6af"
|
||||
testnet5:
|
||||
GENESIS_CHALLENGE: f4c0c9d5b3cd59d6f7c76ecd780e646a2c55064367d0ddbb42b2b6462a4674b2
|
||||
NETWORK_TYPE: 1
|
||||
|
@ -1,11 +1,11 @@
|
||||
from dataclasses import dataclass
|
||||
from typing import List, Optional, Tuple
|
||||
|
||||
from src.consensus.coinbase import pool_parent_id, farmer_parent_id
|
||||
from src.types.blockchain_format.coin import Coin
|
||||
from src.types.blockchain_format.sized_bytes import bytes32
|
||||
from src.types.mempool_inclusion_status import MempoolInclusionStatus
|
||||
from src.types.spend_bundle import SpendBundle
|
||||
from src.util.hash import std_hash
|
||||
from src.util.ints import uint8, uint32, uint64
|
||||
from src.util.streamable import Streamable, streamable
|
||||
from src.wallet.util.transaction_type import TransactionType
|
||||
@ -45,17 +45,17 @@ class TransactionRecord(Streamable):
|
||||
# Note, transactions pending inclusion (pending) return false
|
||||
return False
|
||||
|
||||
def height_farmed(self) -> Optional[uint32]:
|
||||
def height_farmed(self, genesis_challenge) -> Optional[uint32]:
|
||||
if not self.confirmed:
|
||||
return None
|
||||
if self.type == TransactionType.FEE_REWARD or self.type == TransactionType.COINBASE_REWARD:
|
||||
for block_index in range(self.confirmed_at_height, self.confirmed_at_height - 100, -1):
|
||||
if block_index < 0:
|
||||
return None
|
||||
block_index_as_hash = bytes32(block_index.to_bytes(32, "big"))
|
||||
block_index_as_hash_2 = std_hash(std_hash(block_index.to_bytes(4, "big")))
|
||||
if block_index_as_hash == self.additions[0].parent_coin_info:
|
||||
pool_parent = pool_parent_id(uint32(block_index), genesis_challenge)
|
||||
farmer_parent = farmer_parent_id(uint32(block_index), genesis_challenge)
|
||||
if pool_parent == self.additions[0].parent_coin_info:
|
||||
return uint32(block_index)
|
||||
if block_index_as_hash_2 == self.additions[0].parent_coin_info:
|
||||
if farmer_parent == self.additions[0].parent_coin_info:
|
||||
return uint32(block_index)
|
||||
return None
|
||||
|
@ -14,6 +14,7 @@ from cryptography.fernet import Fernet
|
||||
|
||||
from src import __version__
|
||||
from src.consensus.block_record import BlockRecord
|
||||
from src.consensus.coinbase import pool_parent_id, farmer_parent_id
|
||||
from src.consensus.constants import ConsensusConstants
|
||||
from src.consensus.find_fork_point import find_fork_point_in_chain
|
||||
from src.full_node.weight_proof import WeightProofHandler
|
||||
@ -529,14 +530,18 @@ class WalletStateManager:
|
||||
|
||||
if prev is not None:
|
||||
# include last block
|
||||
pool_rewards.add(bytes32(prev.height.to_bytes(32, "big")))
|
||||
farmer_rewards.add(std_hash(std_hash(prev.height)))
|
||||
pool_parent = pool_parent_id(uint32(prev.height), self.constants.GENESIS_CHALLENGE)
|
||||
farmer_parent = farmer_parent_id(uint32(prev.height), self.constants.GENESIS_CHALLENGE)
|
||||
pool_rewards.add(pool_parent)
|
||||
farmer_rewards.add(farmer_parent)
|
||||
prev = await self.blockchain.get_block_record_from_db(prev.prev_hash)
|
||||
|
||||
while prev is not None:
|
||||
# step 2 traverse from previous block to the block before it
|
||||
pool_rewards.add(bytes32(prev.height.to_bytes(32, "big")))
|
||||
farmer_rewards.add(std_hash(std_hash(prev.height)))
|
||||
pool_parent = pool_parent_id(uint32(prev.height), self.constants.GENESIS_CHALLENGE)
|
||||
farmer_parent = farmer_parent_id(uint32(prev.height), self.constants.GENESIS_CHALLENGE)
|
||||
pool_rewards.add(pool_parent)
|
||||
farmer_rewards.add(farmer_parent)
|
||||
if prev.is_transaction_block:
|
||||
break
|
||||
prev = await self.blockchain.get_block_record_from_db(prev.prev_hash)
|
||||
|
@ -36,14 +36,13 @@ def get_future_reward_coins(block: FullBlock) -> Tuple[Coin, Coin]:
|
||||
assert block.transactions_info is not None
|
||||
farmer_amount = uint64(farmer_amount + block.transactions_info.fees)
|
||||
pool_coin: Coin = create_pool_coin(
|
||||
block.height,
|
||||
block.foliage.foliage_block_data.pool_target.puzzle_hash,
|
||||
pool_amount,
|
||||
block.height, block.foliage.foliage_block_data.pool_target.puzzle_hash, pool_amount, constants.GENESIS_CHALLENGE
|
||||
)
|
||||
farmer_coin: Coin = create_farmer_coin(
|
||||
block.height,
|
||||
block.foliage.foliage_block_data.farmer_reward_puzzle_hash,
|
||||
farmer_amount,
|
||||
constants.GENESIS_CHALLENGE,
|
||||
)
|
||||
return pool_coin, farmer_coin
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user