Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ms.mempool locking #9050

Merged
merged 92 commits into from
Nov 4, 2021
Merged
Show file tree
Hide file tree
Changes from 87 commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
f545bed
Prority locking to consensus
mariano54 Oct 31, 2021
01f3688
Remove pstats
mariano54 Oct 31, 2021
1ffe17e
Linting
mariano54 Oct 31, 2021
fe5e528
Do some stuff outside of lock
mariano54 Oct 31, 2021
a27a049
Fix startup
mariano54 Oct 31, 2021
bf4a33d
Add log timings
mariano54 Nov 1, 2021
c44e676
Try some different locking
mariano54 Nov 1, 2021
95f1c5c
Add limit
mariano54 Nov 1, 2021
e5ee15a
catch excp
mariano54 Nov 1, 2021
e23be2f
CLVM inside lock
mariano54 Nov 1, 2021
05da9c3
Try using a semaphore instead
mariano54 Nov 1, 2021
629185d
use events for lock queue
mariano54 Nov 1, 2021
175397f
test
mariano54 Nov 1, 2021
abf2690
Add logging for message types
mariano54 Nov 1, 2021
54c0fcb
type
mariano54 Nov 1, 2021
2748641
remove seed
mariano54 Nov 1, 2021
ce61397
check new peak waiters
mariano54 Nov 1, 2021
5d65024
correct FullNodeAPI self.full_node.new_peak._waiters typo
altendky Nov 1, 2021
9b8a08f
correct logging string typos
altendky Nov 1, 2021
632a9f2
only warn about new_peak Waiters if there is at least 1
altendky Nov 1, 2021
f39553b
remove no-longer-accepted parameter to FullNode.peak_post_processing()
altendky Nov 1, 2021
4b179a4
only warn about respond_transaction Waiters if there is at least 1
altendky Nov 1, 2021
9662e7c
lint
altendky Nov 1, 2021
574c065
Change some constants
mariano54 Nov 1, 2021
f8475f2
Small fix and logging changes
mariano54 Nov 1, 2021
849d185
Put message types outside
mariano54 Nov 2, 2021
223d137
Change some log levels so we can test with info
mariano54 Nov 2, 2021
30c7f1b
More logging
mariano54 Nov 2, 2021
ea2a6d4
Increase rate limits but decrease paralelism
mariano54 Nov 2, 2021
13ff27b
tweaks
mariano54 Nov 2, 2021
20290ba
Log dropped tx
mariano54 Nov 2, 2021
3d2c3a0
Fix pool rpc test
mariano54 Nov 2, 2021
a6e87bc
Test fixes
mariano54 Nov 2, 2021
4ce93f0
Mempool optimization
mariano54 Nov 2, 2021
6bab531
Remove from seen if fails
mariano54 Nov 2, 2021
b94ad72
Increase queue sizes
mariano54 Nov 2, 2021
9e4e329
Message types info
mariano54 Nov 2, 2021
ec6aa45
More test and logging
mariano54 Nov 2, 2021
2ae32c6
Small changes to networking just in case
mariano54 Nov 2, 2021
4ac5bd7
Decrease logging
mariano54 Nov 2, 2021
65888df
Decrease logging even further
mariano54 Nov 2, 2021
0332be3
Decrease logging even further even further
mariano54 Nov 2, 2021
b07ccea
Decrease logging 3
mariano54 Nov 2, 2021
fc159bf
Transaction queue
mariano54 Nov 2, 2021
0d0bdb1
Don't cancel tasks or close connection
mariano54 Nov 2, 2021
01f972b
Cancel tasks on disconnect (for shutdown purposed)
mariano54 Nov 2, 2021
e62bd38
Fix typo
mariano54 Nov 2, 2021
b1b7357
Catch cancelled
mariano54 Nov 2, 2021
d1aedcd
Do multiple at a time
mariano54 Nov 2, 2021
4d90340
More accurate farmer response time
mariano54 Nov 2, 2021
bd9605c
More efficiently create tasks
mariano54 Nov 2, 2021
e7304b0
Increase queue size and priority by fee
mariano54 Nov 2, 2021
0aa1032
Revert priority
mariano54 Nov 2, 2021
9d42e0a
Don't re-request too many times for dropped TX
mariano54 Nov 2, 2021
31bf911
Handle cancelled error so we don't go into a bad state
mariano54 Nov 3, 2021
7ebfb1f
Catch cancelled in syncing tasks
mariano54 Nov 3, 2021
5daf545
Reduce new_peak_sem to improve performance
mariano54 Nov 3, 2021
2fbd6c7
Less bytes conversion
mariano54 Nov 3, 2021
a55ca22
Missing file, and 2 workers for CLVM
mariano54 Nov 3, 2021
0ca7b35
Validate BLS in a new thread
mariano54 Nov 3, 2021
b750477
tests
mariano54 Nov 3, 2021
5d92019
Merge branch 'main' into ms.mempool_locking
altendky Nov 3, 2021
cf8901e
Change semaphore constants
mariano54 Nov 3, 2021
e6c6b92
correct a cancellation triggered exception and assertion
altendky Nov 3, 2021
0eaecfc
Fix send_transaction, dont use BaseException, fix tests
mariano54 Nov 3, 2021
f4489aa
Fix more tests
mariano54 Nov 3, 2021
6c0cb36
only log transaction handler cancellation in debug
altendky Nov 3, 2021
5e28b75
typing in log
altendky Nov 3, 2021
551d52d
move unfinished validation to diff proc
Yostra Nov 3, 2021
caba9f9
it is asyncio.CancelledError
altendky Nov 3, 2021
516b7cf
Add a test for bad signature
mariano54 Nov 3, 2021
6f60f4a
Fix more tests, reduce logging, lint
mariano54 Nov 3, 2021
fabfa6d
One more lint
mariano54 Nov 3, 2021
10ff6b6
blockchain tests, pass bytes directly, single call
Yostra Nov 3, 2021
571df63
Try to fix rl_wallet failures
mariano54 Nov 3, 2021
dd6e486
Fix mempool test
mariano54 Nov 3, 2021
3b561b6
catch everything
Yostra Nov 3, 2021
bee7128
Don't test RL wallet
mariano54 Nov 3, 2021
69e1a8f
Merge branch 'main' into ms.mempool_locking
altendky Nov 4, 2021
3a0d8e0
Fix more tests and return error code
mariano54 Nov 4, 2021
9b9e988
Improve error handling in multiprocess
mariano54 Nov 4, 2021
903357c
Add pre-validation time
mariano54 Nov 4, 2021
6f80227
Add pre-validation time in logs, and revert pytest.ini changes
mariano54 Nov 4, 2021
b4aa321
Add log correctly
mariano54 Nov 4, 2021
a8c1d58
Ms.bls cache experiment (#9115)
mariano54 Nov 4, 2021
7380e99
formalize LockQueue shutdown
altendky Nov 4, 2021
632e480
Comments
mariano54 Nov 4, 2021
3b6a9a0
Fix blockchain test
mariano54 Nov 4, 2021
8f0afdd
Improve cache
mariano54 Nov 4, 2021
686afb7
Remove logs
mariano54 Nov 4, 2021
e8ef4ab
Fix sign_coin_spends
mariano54 Nov 4, 2021
5a9d291
Fix pool wallet
mariano54 Nov 4, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions chia/clvm/spend_sim.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from chia.types.blockchain_format.program import Program, SerializedProgram
from chia.util.ints import uint64, uint32
from chia.util.hash import std_hash
from chia.util.errors import Err
from chia.util.errors import Err, ValidationError
from chia.util.db_wrapper import DBWrapper
from chia.types.coin_record import CoinRecord
from chia.types.spend_bundle import SpendBundle
Expand Down Expand Up @@ -49,6 +49,7 @@ def __init__(self, rci: List[Coin], height: uint32, timestamp: uint64):
self.timestamp = timestamp
self.is_transaction_block = True
self.header_hash = std_hash(bytes(height))
self.prev_transaction_block_hash = std_hash(std_hash(height))


class SpendSim:
Expand Down Expand Up @@ -78,7 +79,7 @@ async def close(self):
await self.connection.close()

async def new_peak(self):
await self.mempool_manager.new_peak(self.block_records[-1])
await self.mempool_manager.new_peak(self.block_records[-1], [])

def new_coin_record(self, coin: Coin, coinbase=False) -> CoinRecord:
return CoinRecord(
Expand Down Expand Up @@ -203,9 +204,12 @@ def __init__(self, service):
self.service = service

async def push_tx(self, spend_bundle: SpendBundle) -> Tuple[MempoolInclusionStatus, Optional[Err]]:
cost_result: NPCResult = await self.service.mempool_manager.pre_validate_spendbundle(
spend_bundle, spend_bundle.name()
)
try:
cost_result: NPCResult = await self.service.mempool_manager.pre_validate_spendbundle(
spend_bundle, None, spend_bundle.name()
)
except ValidationError as e:
return MempoolInclusionStatus.FAILED, e.code
cost, status, error = await self.service.mempool_manager.add_spendbundle(
spend_bundle, cost_result, spend_bundle.name()
)
Expand Down
12 changes: 7 additions & 5 deletions chia/consensus/block_body_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ async def validate_block_body(
npc_result: Optional[NPCResult],
fork_point_with_peak: Optional[uint32],
get_block_generator: Callable,
validate_signature=True,
) -> Tuple[Optional[Err], Optional[NPCResult]]:
"""
This assumes the header block has been completely validated.
Expand Down Expand Up @@ -457,10 +458,11 @@ async def validate_block_body(
# However, we force caching of pairings just for unfinished blocks
# as the cache is likely to be useful when validating the corresponding
# finished blocks later.
force_cache: bool = isinstance(block, UnfinishedBlock)
if not cached_bls.aggregate_verify(
pairs_pks, pairs_msgs, block.transactions_info.aggregated_signature, force_cache
):
return Err.BAD_AGGREGATE_SIGNATURE, None
if validate_signature:
force_cache: bool = isinstance(block, UnfinishedBlock)
if not cached_bls.aggregate_verify(
pairs_pks, pairs_msgs, block.transactions_info.aggregated_signature, force_cache
):
return Err.BAD_AGGREGATE_SIGNATURE, None

return None, npc_result
41 changes: 23 additions & 18 deletions chia/consensus/blockchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@
from chia.consensus.difficulty_adjustment import get_next_sub_slot_iters_and_difficulty
from chia.consensus.find_fork_point import find_fork_point_in_chain
from chia.consensus.full_block_to_block_record import block_to_block_record
from chia.consensus.multiprocess_validation import PreValidationResult, pre_validate_blocks_multiprocessing
from chia.consensus.multiprocess_validation import (
PreValidationResult,
pre_validate_blocks_multiprocessing,
_run_generator,
)
from chia.full_node.block_store import BlockStore
from chia.full_node.coin_store import CoinStore
from chia.full_node.hint_store import HintStore
Expand All @@ -35,7 +39,7 @@
from chia.types.unfinished_block import UnfinishedBlock
from chia.types.unfinished_header_block import UnfinishedHeaderBlock
from chia.types.weight_proof import SubEpochChallengeSegment
from chia.util.errors import Err
from chia.util.errors import Err, ConsensusError
from chia.util.generator_tools import get_block_header, tx_removals_and_additions
from chia.util.ints import uint16, uint32, uint64, uint128
from chia.util.streamable import recurse_jsonify
Expand Down Expand Up @@ -561,7 +565,7 @@ def get_recent_reward_challenges(self) -> List[Tuple[bytes32, uint128]]:
return list(reversed(recent_rc))

async def validate_unfinished_block(
self, block: UnfinishedBlock, skip_overflow_ss_validation=True
self, block: UnfinishedBlock, npc_result: Optional[NPCResult], skip_overflow_ss_validation=True
) -> PreValidationResult:
if (
not self.contains_block(block.prev_header_hash)
Expand Down Expand Up @@ -601,21 +605,6 @@ async def validate_unfinished_block(
else self.block_record(block.prev_header_hash).height
)

npc_result = None
if block.transactions_generator is not None:
assert block.transactions_info is not None
try:
block_generator: Optional[BlockGenerator] = await self.get_block_generator(block)
except ValueError:
return PreValidationResult(uint16(Err.GENERATOR_REF_HAS_NO_GENERATOR.value), None, None)
if block_generator is None:
return PreValidationResult(uint16(Err.GENERATOR_REF_HAS_NO_GENERATOR.value), None, None)
npc_result = get_name_puzzle_conditions(
block_generator,
min(self.constants.MAX_BLOCK_COST_CLVM, block.transactions_info.cost),
cost_per_byte=self.constants.COST_PER_BYTE,
safe_mode=False,
)
error_code, cost_result = await validate_block_body(
self.constants,
self,
Expand All @@ -627,6 +616,7 @@ async def validate_unfinished_block(
npc_result,
None,
self.get_block_generator,
False,
)

if error_code is not None:
Expand Down Expand Up @@ -654,6 +644,21 @@ async def pre_validate_blocks_multiprocessing(
wp_summaries,
)

async def run_generator(self, unfinished_block: bytes, generator: BlockGenerator) -> NPCResult:
task = asyncio.get_running_loop().run_in_executor(
self.pool,
_run_generator,
self.constants_json,
unfinished_block,
bytes(generator),
)
error, npc_result_bytes = await task
if error is not None:
raise ConsensusError(error)
if npc_result_bytes is None:
raise ConsensusError(Err.UNKNOWN)
return NPCResult.from_bytes(npc_result_bytes)

def contains_block(self, header_hash: bytes32) -> bool:
"""
True if we have already added this block to the chain. This may return false for orphan blocks
Expand Down
34 changes: 33 additions & 1 deletion chia/consensus/multiprocess_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@
from chia.types.full_block import FullBlock
from chia.types.generator_types import BlockGenerator
from chia.types.header_block import HeaderBlock
from chia.types.unfinished_block import UnfinishedBlock
from chia.util.block_cache import BlockCache
from chia.util.errors import Err
from chia.util.errors import Err, ValidationError
from chia.util.generator_tools import get_block_header, tx_removals_and_additions
from chia.util.ints import uint16, uint64, uint32
from chia.util.streamable import Streamable, dataclass_from_dict, streamable
Expand Down Expand Up @@ -316,3 +317,34 @@ async def pre_validate_blocks_multiprocessing(
for batch_result in (await asyncio.gather(*futures))
for result in batch_result
]


def _run_generator(
constants_dict: bytes,
unfinished_block_bytes: bytes,
block_generator_bytes: bytes,
) -> Tuple[Optional[Err], Optional[bytes]]:
"""
Runs the CLVM generator from bytes inputs. This is meant to be called under a ProcessPoolExecutor, in order to
validate the heavy parts of a block (clvm program) in a different process.
"""
try:
constants: ConsensusConstants = dataclass_from_dict(ConsensusConstants, constants_dict)
unfinished_block: UnfinishedBlock = UnfinishedBlock.from_bytes(unfinished_block_bytes)
assert unfinished_block.transactions_info is not None
block_generator: BlockGenerator = BlockGenerator.from_bytes(block_generator_bytes)
assert block_generator.program == unfinished_block.transactions_generator
npc_result: NPCResult = get_name_puzzle_conditions(
block_generator,
min(constants.MAX_BLOCK_COST_CLVM, unfinished_block.transactions_info.cost),
cost_per_byte=constants.COST_PER_BYTE,
safe_mode=False,
)
if npc_result.error is not None:
return Err(npc_result.error), None
except ValidationError as e:
return e.code, None
except Exception:
return Err.UNKNOWN, None

return None, bytes(npc_result)
Loading