class IOU: # pylint: disable=too-many-instance-attributes sender: Address = field(metadata={"marshmallow_field": ChecksumAddress()}) receiver: Address = field( metadata={"marshmallow_field": ChecksumAddress()}) amount: TokenAmount expiration_block: BlockNumber one_to_n_address: Address = field( metadata={"marshmallow_field": ChecksumAddress()}) chain_id: ChainID signature: Signature = field(metadata={"marshmallow_field": HexedBytes()}) claimed: Optional[bool] = None Schema: ClassVar[Type[marshmallow.Schema]] def packed_data(self) -> bytes: return (self.one_to_n_address + encode_single("uint256", self.chain_id) + encode_single("uint256", MessageTypeId.IOU) + self.sender + self.receiver + encode_single("uint256", self.amount) + encode_single("uint256", self.expiration_block)) def is_signature_valid(self) -> bool: try: recovered_address = recover(self.packed_data(), self.signature) except InvalidSignature: return False return is_same_address(recovered_address, self.sender) @property def session_id(self) -> str: """Session ID as used for OneToN.settled_sessions""" return encode_hex( keccak(self.receiver + self.sender + encode_single("uint256", self.expiration_block)))
class Channel: token_network_address: TokenNetworkAddress = field( metadata={"marshmallow_field": ChecksumAddress(required=True)}) channel_id: ChannelID participant1: Address = field( metadata={"marshmallow_field": ChecksumAddress(required=True)}) participant2: Address = field( metadata={"marshmallow_field": ChecksumAddress(required=True)}) settle_timeout: int fee_schedule1: FeeSchedule = field(default_factory=FeeSchedule) fee_schedule2: FeeSchedule = field(default_factory=FeeSchedule) # Set by PFSCapacityUpdate capacity1: TokenAmount = TokenAmount(0) capacity2: TokenAmount = TokenAmount(0) update_nonce1: Nonce = Nonce(0) update_nonce2: Nonce = Nonce(0) reveal_timeout1: int = DEFAULT_REVEAL_TIMEOUT reveal_timeout2: int = DEFAULT_REVEAL_TIMEOUT Schema: ClassVar[Type[marshmallow.Schema]] @property def views(self) -> Tuple["ChannelView", "ChannelView"]: return ChannelView(channel=self), ChannelView(channel=self, reverse=True)
class ChannelView: """ Unidirectional view of a bidirectional channel. """ channel_id: ChannelID participant1: Address = field( metadata={"marshmallow_field": ChecksumAddress(required=True)}) participant2: Address = field( metadata={"marshmallow_field": ChecksumAddress(required=True)}) settle_timeout: int token_network_address: TokenNetworkAddress = field( metadata={"marshmallow_field": ChecksumAddress(required=True)}) capacity: TokenAmount = None # type: ignore reveal_timeout: int = DEFAULT_REVEAL_TIMEOUT deposit: TokenAmount = TokenAmount(0) update_nonce: Nonce = Nonce(0) fee_schedule_sender: FeeSchedule = field(default_factory=FeeSchedule) fee_schedule_receiver: FeeSchedule = field(default_factory=FeeSchedule) Schema: ClassVar[Type[marshmallow.Schema]] def __post_init__(self) -> None: if self.capacity is None: self.capacity = self.deposit def update_deposit(self, total_deposit: TokenAmount) -> None: if total_deposit > self.deposit: self.capacity = TokenAmount(self.capacity + total_deposit - self.deposit) self.deposit = TokenAmount(total_deposit) def update_capacity(self, capacity: TokenAmount, nonce: Nonce = Nonce(0), reveal_timeout: int = None) -> None: self.update_nonce = nonce self.capacity = capacity if reveal_timeout is not None: self.reveal_timeout = reveal_timeout def fee_sender(self, amount: PaymentAmount) -> FeeAmount: """Return the mediation fee for this channel when transferring the given amount""" return self.fee_schedule_sender.fee(amount, Balance(self.capacity)) def fee_receiver(self, amount: PaymentAmount) -> FeeAmount: """Return the mediation fee for this channel when receiving the given amount""" return self.fee_schedule_receiver.fee(amount, Balance(self.capacity)) def set_fee_schedule(self, party: str, fee_schedule: FeeSchedule) -> None: assert party in ["sender", "receiver"] attr_name = "fee_schedule_" + party if getattr(self, attr_name).timestamp >= fee_schedule.timestamp: raise InvalidPFSFeeUpdate( "Timestamp must increase between fee updates") setattr(self, attr_name, fee_schedule) def __repr__(self) -> str: return "<ChannelView from={} to={} capacity={}>".format( self.participant1, self.participant2, self.capacity)
class PathRequest: """A HTTP request to PathsResource""" # pylint: disable=too-many-instance-attributes from_: Address = field( metadata=dict(marshmallow_field=ChecksumAddress(required=True, data_key="from")) ) to: Address = field(metadata=dict(marshmallow_field=ChecksumAddress(required=True))) value: PaymentAmount = field(metadata=dict(validate=marshmallow.validate.Range(min=1))) max_paths: int = field( default=DEFAULT_MAX_PATHS, metadata=dict(validate=marshmallow.validate.Range(min=1, max=MAX_PATHS_PER_REQUEST)), ) iou: Optional[IOU] = None diversity_penalty: Optional[float] = None fee_penalty: Optional[float] = None Schema: ClassVar[Type[marshmallow.Schema]]
class IOURequest: """A HTTP request to IOUResource""" sender: Address = field(metadata={"marshmallow_field": ChecksumAddress(required=True)}) receiver: Address = field(metadata={"marshmallow_field": ChecksumAddress(required=True)}) timestamp: datetime = field(metadata={"marshmallow_field": fields.NaiveDateTime()}) timestamp_str: str = field(metadata=dict(data_key="timestamp", load_only=True)) signature: Signature = field(metadata={"marshmallow_field": HexedBytes()}) Schema: ClassVar[Type[marshmallow.Schema]] def is_signature_valid(self) -> bool: packed_data = self.sender + self.receiver + Web3.toBytes(text=self.timestamp_str) try: recovered_address = recover(packed_data, self.signature) except InvalidSignature: return False return is_same_address(recovered_address, self.sender)