Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def prepare_mediation_fee_config(
cli_token_to_flat_fee: Tuple[Tuple[TokenAddress, FeeAmount], ...],
cli_token_to_proportional_fee: Tuple[Tuple[TokenAddress, ProportionalFeeAmount], ...],
cli_token_to_proportional_imbalance_fee: Tuple[
Tuple[TokenAddress, ProportionalFeeAmount], ...
],
) -> MediationFeeConfig:
""" Converts the mediation fee CLI args to proper per-channel
mediation fees. """
tn_to_flat_fee: Dict[TokenAddress, FeeAmount] = {}
# Add the defaults for flat fees for DAI/WETH
tn_to_flat_fee[WETH_TOKEN_ADDRESS] = FeeAmount(DEFAULT_WETH_FLAT_FEE // 2)
tn_to_flat_fee[DAI_TOKEN_ADDRESS] = FeeAmount(DEFAULT_DAI_FLAT_FEE // 2)
# Store the flat fee settings for the given token addresses
# The given flat fee is for the whole mediation, but that includes two channels.
# Therefore divide by 2 here.
for address, fee in cli_token_to_flat_fee:
tn_to_flat_fee[address] = FeeAmount(fee // 2)
tn_to_proportional_fee: Dict[TokenAddress, ProportionalFeeAmount] = {
address: ppm_fee_per_channel(prop_fee)
for address, prop_fee in cli_token_to_proportional_fee
}
tn_to_proportional_imbalance_fee: Dict[TokenAddress, ProportionalFeeAmount] = {
address: prop_fee for address, prop_fee in cli_token_to_proportional_imbalance_fee
}
the channel_description fixture. Tests all PFS methods w.r.t. to that topology
"""
clients = get_accounts(7)
token_network_address = TokenNetworkAddress(to_canonical_address(token_network.address))
with patch("pathfinding_service.service.MatrixListener", new=Mock):
pfs = PathfindingService(
web3=web3,
contracts={
CONTRACT_TOKEN_NETWORK_REGISTRY: token_network_registry_contract,
CONTRACT_USER_DEPOSIT: user_deposit_contract,
},
required_confirmations=BlockTimeout(1),
db_filename=":memory:",
poll_interval=0.1,
sync_start_block=BlockNumber(0),
private_key=PrivateKey(
decode_hex("3a1076bf45ab87712ad64ccb3b10217737f7faacbf2872e88fdd9a537d8fe266")
),
)
# greenlet needs to be started and context switched to
pfs.start()
pfs.updated.wait(timeout=5)
# there should be one token network registered
assert len(pfs.token_networks) == 1
token_network_model = pfs.token_networks[token_network_address]
graph = token_network_model.G
channel_identifiers = []
for (
canonical_identifier=CanonicalIdentifier(
chain_identifier=ChainID(61),
channel_identifier=channel_id,
token_network_address=TokenNetworkAddress(token_network_model.address),
),
updating_participant=address2,
other_participant=address1,
updating_nonce=Nonce(2),
other_nonce=Nonce(1),
updating_capacity=deposit2,
other_capacity=deposit1,
reveal_timeout=BlockTimeout(2),
signature=EMPTY_SIGNATURE,
),
updating_capacity_partner=TokenAmount(deposit1),
other_capacity_partner=TokenAmount(deposit2),
)
canonical_identifier=CanonicalIdentifier(
chain_identifier=ChainID(61),
channel_identifier=ChannelID(channel_id),
token_network_address=TokenNetworkAddress(token_network.address),
),
updating_participant=addresses[p1_index],
other_participant=addresses[p2_index],
updating_nonce=Nonce(1),
other_nonce=Nonce(1),
updating_capacity=p1_capacity,
other_capacity=p2_capacity,
reveal_timeout=p1_reveal_timeout,
signature=EMPTY_SIGNATURE,
),
updating_capacity_partner=TokenAmount(0),
other_capacity_partner=TokenAmount(0),
)
token_network.handle_channel_balance_update_message(
PFSCapacityUpdate(
canonical_identifier=CanonicalIdentifier(
chain_identifier=ChainID(61),
channel_identifier=ChannelID(channel_id),
token_network_address=TokenNetworkAddress(token_network.address),
),
updating_participant=addresses[p2_index],
other_participant=addresses[p1_index],
updating_nonce=Nonce(2),
other_nonce=Nonce(1),
updating_capacity=p2_capacity,
other_capacity=p1_capacity,
reveal_timeout=p2_reveal_timeout,
signature=EMPTY_SIGNATURE,
def test_update_fee(order, pathfinding_service_mock, token_network_model):
pathfinding_service_mock.database.insert(
"token_network", dict(address=token_network_model.address)
)
if order == "normal":
setup_channel(pathfinding_service_mock, token_network_model)
fee_schedule = FeeScheduleState(
flat=FeeAmount(1),
proportional=ProportionalFeeAmount(int(0.1e9)),
imbalance_penalty=[(TokenAmount(0), FeeAmount(0)), (TokenAmount(10), FeeAmount(10))],
)
fee_update = PFSFeeUpdate(
canonical_identifier=CanonicalIdentifier(
chain_identifier=ChainID(61),
token_network_address=token_network_model.address,
channel_identifier=ChannelID(1),
),
updating_participant=PARTICIPANT1,
fee_schedule=fee_schedule,
timestamp=datetime.utcnow(),
signature=EMPTY_SIGNATURE,
)
fee_update.sign(LocalSigner(PARTICIPANT1_PRIVKEY))
pathfinding_service_mock.handle_message(fee_update)
if order == "fee_update_before_channel_open":
def request_monitoring_message(token_network, get_accounts, get_private_key) -> RequestMonitoring:
c1, c2 = get_accounts(2)
balance_proof_c2 = HashedBalanceProof(
channel_identifier=ChannelID(1),
token_network_address=TokenNetworkAddress(to_canonical_address(token_network.address)),
chain_id=ChainID(61),
nonce=Nonce(2),
additional_hash="0x%064x" % 0,
transferred_amount=TokenAmount(1),
locked_amount=TokenAmount(0),
locksroot=encode_hex(LOCKSROOT_OF_NO_LOCKS),
priv_key=get_private_key(c2),
)
return balance_proof_c2.get_request_monitoring(
privkey=get_private_key(c1),
reward_amount=TokenAmount(1),
monitoring_service_contract_address=MonitoringServiceAddress(bytes([11] * 20)),
)
# The opposite fee schedule should give opposite results, without fee capping
tn.set_fee(2, 3, cap_fees=False)
tn.set_fee(2, 1, imbalance_penalty=[(TA(0), FA(100)), (TA(1000), FA(0))], cap_fees=False)
assert tn.estimate_fee(1, 3) == -10 + 1
assert tn.estimate_fee(3, 1) is None # no balance in channel
# Or zero with fee capping
tn.set_fee(2, 3, cap_fees=True)
tn.set_fee(2, 1, imbalance_penalty=[(TA(0), FA(100)), (TA(1000), FA(0))], cap_fees=True)
assert tn.estimate_fee(1, 3) == 0
assert tn.estimate_fee(3, 1) is None # no balance in channel
# Outgoing channel
# Without fee capping
tn.set_fee(2, 1, cap_fees=False)
tn.set_fee(2, 3, imbalance_penalty=[(TA(0), FA(0)), (TA(1000), FA(100))], cap_fees=False)
assert tn.estimate_fee(1, 3) == -10
assert tn.estimate_fee(3, 1) is None # no balance in channel
# With fee capping
tn.set_fee(2, 1, cap_fees=True)
tn.set_fee(2, 3, imbalance_penalty=[(TA(0), FA(0)), (TA(1000), FA(100))], cap_fees=True)
assert tn.estimate_fee(1, 3) == 0
assert tn.estimate_fee(3, 1) is None # no balance in channel
# The opposite fee schedule should give opposite results
tn.set_fee(2, 3, imbalance_penalty=[(TA(0), FA(100)), (TA(1000), FA(0))])
assert tn.estimate_fee(1, 3) == 10
assert tn.estimate_fee(3, 1) is None # no balance in channel
# Combined fees cancel out
# Works without fee capping
tn.set_fee(2, 1, imbalance_penalty=[(TA(0), FA(0)), (TA(1000), FA(20))], cap_fees=False)
def test_save_and_load_token_networks(pathfinding_service_mock_empty):
pfs = pathfinding_service_mock_empty
token_address = TokenAddress(bytes([1] * 20))
token_network_address = TokenNetworkAddress(bytes([2] * 20))
channel_id = ChannelID(1)
p1 = Address(bytes([3] * 20))
p2 = Address(bytes([4] * 20))
events = [
ReceiveTokenNetworkCreatedEvent(
token_address=token_address,
token_network_address=token_network_address,
block_number=BlockNumber(1),
),
ReceiveChannelOpenedEvent(
token_network_address=token_network_address,
channel_identifier=channel_id,
participant1=p1,
participant2=p2,
settle_timeout=BlockTimeout(2 ** 65), # larger than max_uint64 to check hex storage
block_number=BlockNumber(2),
),
]
# it fails it the no deposit is in the UDC
iou = make_iou(privkey, pfs.address)
with pytest.raises(exceptions.DepositTooLow):
test_payment(iou)
# adding deposit does not help immediately
deposit_to_udc(sender, 10)
with pytest.raises(exceptions.DepositTooLow):
test_payment(iou)
# must succeed after deposit is confirmed
web3.testing.mine(pathfinding_service_web3_mock.required_confirmations)
test_payment(iou)
# wrong recipient
iou = make_iou(privkey, Address(bytes([6] * 20)))
with pytest.raises(exceptions.WrongIOURecipient):
test_payment(iou)
# wrong chain_id
iou = make_iou(privkey, pfs.address, chain_id=2)
with pytest.raises(exceptions.UnsupportedChainID):
test_payment(iou)
# wrong one_to_n_address
iou = make_iou(privkey, pfs.address, one_to_n_address=bytes([1] * 20))
with pytest.raises(exceptions.WrongOneToNAddress):
test_payment(iou)
# payment too low
iou = make_iou(privkey, pfs.address)
with pytest.raises(exceptions.InsufficientServicePayment):
def test_token_network_created(pathfinding_service_mock):
token_address = TokenAddress(bytes([1] * 20))
token_network_address = TokenNetworkAddress(bytes(bytes([2] * 20)))
network_event = ReceiveTokenNetworkCreatedEvent(
token_address=token_address,
token_network_address=token_network_address,
block_number=BlockNumber(1),
)
assert not pathfinding_service_mock.follows_token_network(token_network_address)
assert len(pathfinding_service_mock.token_networks) == 1
pathfinding_service_mock.handle_event(network_event)
assert pathfinding_service_mock.follows_token_network(token_network_address)
assert len(pathfinding_service_mock.token_networks) == 2
# Test idempotency
pathfinding_service_mock.handle_event(network_event)
assert pathfinding_service_mock.follows_token_network(token_network_address)
assert len(pathfinding_service_mock.token_networks) == 2