mirror of
https://github.com/logos-blockchain/logos-blockchain-specs.git
synced 2026-01-08 08:03:13 +00:00
wip
This commit is contained in:
parent
5c64a0bd11
commit
113d3bb6d7
0
cryptarchia/sync/__init__.py
Normal file
0
cryptarchia/sync/__init__.py
Normal file
43
cryptarchia/sync/range_sync.py
Normal file
43
cryptarchia/sync/range_sync.py
Normal file
@ -0,0 +1,43 @@
|
||||
from collections import defaultdict
|
||||
from typing import Generator
|
||||
|
||||
from dill.tests.test_diff import A
|
||||
|
||||
from cryptarchia.cryptarchia import BlockHeader, Follower, Id, Slot
|
||||
|
||||
SLOT_TOLERANCE = 2
|
||||
|
||||
|
||||
def range_sync(local: Follower, remotes: list[Follower], start_slot: Slot):
|
||||
while groups := {
|
||||
tip: group
|
||||
for tip, group in group_by_tip(remotes).items()
|
||||
if group[0].tip().slot.absolute_slot - start_slot.absolute_slot > SLOT_TOLERANCE
|
||||
}:
|
||||
for _, group in groups.items():
|
||||
remote = group[0]
|
||||
for block in request_blocks_by_range(remote, start_slot, remote.tip().slot):
|
||||
local.on_block(block)
|
||||
start_slot = Slot(local.tip().slot.absolute_slot + 1)
|
||||
|
||||
|
||||
def group_by_tip(remotes: list[Follower]) -> dict[Id, list[Follower]]:
|
||||
groups: dict[Id, list[Follower]] = defaultdict(list)
|
||||
for remote in remotes:
|
||||
groups[remote.tip_id()].append(remote)
|
||||
return groups
|
||||
|
||||
|
||||
def request_blocks_by_range(
|
||||
remote: Follower, from_slot: Slot, to_slot: Slot
|
||||
) -> Generator[BlockHeader, None, None]:
|
||||
# TODO: Optimize this by keeping blocks by slot in the Follower
|
||||
blocks_by_slot: dict[int, list[BlockHeader]] = defaultdict(list)
|
||||
for ledger_state in remote.ledger_state.values():
|
||||
if from_slot <= ledger_state.block.slot <= to_slot:
|
||||
blocks_by_slot[ledger_state.block.slot.absolute_slot].append(
|
||||
ledger_state.block
|
||||
)
|
||||
for slot in range(from_slot.absolute_slot, to_slot.absolute_slot + 1):
|
||||
for block in blocks_by_slot[slot]:
|
||||
yield block
|
||||
26
cryptarchia/sync/test_range_sync.py
Normal file
26
cryptarchia/sync/test_range_sync.py
Normal file
@ -0,0 +1,26 @@
|
||||
from unittest import TestCase
|
||||
|
||||
from cryptarchia.cryptarchia import Coin, Follower
|
||||
from cryptarchia.sync.range_sync import range_sync
|
||||
from cryptarchia.test_common import mk_block, mk_config, mk_genesis_state
|
||||
|
||||
|
||||
class TestRangeSync(TestCase):
|
||||
def test_no_fork(self):
|
||||
# b0 - b1 - b2
|
||||
coin = Coin(sk=0, value=10)
|
||||
config = mk_config([coin])
|
||||
genesis = mk_genesis_state([coin])
|
||||
follower = Follower(genesis, config)
|
||||
b0, coin = mk_block(genesis.block, 1, coin), coin.evolve()
|
||||
b1, coin = mk_block(b0, 2, coin), coin.evolve()
|
||||
b2, coin = mk_block(b1, 3, coin), coin.evolve()
|
||||
for b in [b0, b1, b2]:
|
||||
follower.on_block(b)
|
||||
assert follower.tip() == b2
|
||||
assert follower.forks == []
|
||||
|
||||
new_follower = Follower(genesis, config)
|
||||
range_sync(new_follower, [follower], genesis.block.slot)
|
||||
assert new_follower.tip() == b2
|
||||
assert new_follower.forks == []
|
||||
Loading…
x
Reference in New Issue
Block a user