##############################################################################
#
# Crossbar.io Database
# Copyright (c) Crossbar.io Technologies GmbH. Licensed under MIT.
#
##############################################################################
import pprint
from uuid import UUID
import numpy as np
import flatbuffers
from cfxdb import unpack_uint256, pack_uint256
from cfxdb.gen.xbrmm import ChannelType as ChannelTypeGen, ChannelState as ChannelStateGen, \
Channel as ChannelGen, ChannelBalance as ChannelBalanceGen
from zlmdb import table, MapUuidFlatBuffers, MapBytes20TimestampUuid
ChannelType = ChannelTypeGen.ChannelType
ChannelState = ChannelStateGen.ChannelState
class _ChannelGen(ChannelGen.Channel):
"""
Expand methods on the class code generated by flatc.
FIXME: come up with a PR for flatc to generated this stuff automatically.
"""
@classmethod
def GetRootAsChannel(cls, buf, offset):
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
x = _ChannelGen()
x.Init(buf, n + offset)
return x
def MarketOidAsBytes(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
if o != 0:
_off = self._tab.Vector(o)
_len = self._tab.VectorLen(o)
return memoryview(self._tab.Bytes)[_off:_off + _len]
return None
def MemberOidAsBytes(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
if o != 0:
_off = self._tab.Vector(o)
_len = self._tab.VectorLen(o)
return memoryview(self._tab.Bytes)[_off:_off + _len]
return None
def ChannelOidAsBytes(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
if o != 0:
_off = self._tab.Vector(o)
_len = self._tab.VectorLen(o)
return memoryview(self._tab.Bytes)[_off:_off + _len]
return None
def OpenAtAsBytes(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
if o != 0:
_off = self._tab.Vector(o)
_len = self._tab.VectorLen(o)
return memoryview(self._tab.Bytes)[_off:_off + _len]
return None
def MarketmakerAsBytes(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(18))
if o != 0:
_off = self._tab.Vector(o)
_len = self._tab.VectorLen(o)
return memoryview(self._tab.Bytes)[_off:_off + _len]
return None
def ActorAsBytes(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(20))
if o != 0:
_off = self._tab.Vector(o)
_len = self._tab.VectorLen(o)
return memoryview(self._tab.Bytes)[_off:_off + _len]
return None
def DelegateAsBytes(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
if o != 0:
_off = self._tab.Vector(o)
_len = self._tab.VectorLen(o)
return memoryview(self._tab.Bytes)[_off:_off + _len]
return None
def RecipientAsBytes(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
if o != 0:
_off = self._tab.Vector(o)
_len = self._tab.VectorLen(o)
return memoryview(self._tab.Bytes)[_off:_off + _len]
return None
def AmountAsBytes(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
if o != 0:
_off = self._tab.Vector(o)
_len = self._tab.VectorLen(o)
return memoryview(self._tab.Bytes)[_off:_off + _len]
return None
def ClosingAtAsBytes(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(32))
if o != 0:
_off = self._tab.Vector(o)
_len = self._tab.VectorLen(o)
return memoryview(self._tab.Bytes)[_off:_off + _len]
return None
def ClosedAtAsBytes(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(34))
if o != 0:
_off = self._tab.Vector(o)
_len = self._tab.VectorLen(o)
return memoryview(self._tab.Bytes)[_off:_off + _len]
return None
def CloseMmSigAsBytes(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(36))
if o != 0:
_off = self._tab.Vector(o)
_len = self._tab.VectorLen(o)
return memoryview(self._tab.Bytes)[_off:_off + _len]
return None
def CloseDelSigAsBytes(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(38))
if o != 0:
_off = self._tab.Vector(o)
_len = self._tab.VectorLen(o)
return memoryview(self._tab.Bytes)[_off:_off + _len]
return None
def CloseBalanceAsBytes(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(42))
if o != 0:
_off = self._tab.Vector(o)
_len = self._tab.VectorLen(o)
return memoryview(self._tab.Bytes)[_off:_off + _len]
return None
def ClosedTxAsBytes(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(46))
if o != 0:
_off = self._tab.Vector(o)
_len = self._tab.VectorLen(o)
return memoryview(self._tab.Bytes)[_off:_off + _len]
return None
class Channel(object):
"""
XBR off-chain payment or paying channel.
"""
def __init__(self, from_fbs=None):
self._from_fbs = from_fbs
self._market_oid = None
self._member_oid = None
self._channel_oid = None
self._timestamp = None
self._open_at = None
self._seq = None
self._channel_type = None
self._marketmaker = None
self._actor = None
self._delegate = None
self._recipient = None
self._amount = None
self._timeout = None
self._state = None
self._closing_at = None
self._closed_at = None
self._close_mm_sig = None
self._close_del_sig = None
self._close_channel_seq = None
self._close_balance = None
self._close_is_final = None
self._closed_tx = None
def marshal(self) -> dict:
obj = {
'market_oid': self.market_oid.bytes if self.market_oid else None,
'member_oid': self.member_oid.bytes if self.member_oid else None,
'channel_oid': self.channel_oid.bytes if self.channel_oid else None,
'timestamp': int(self.timestamp) if self.timestamp else None,
'open_at': pack_uint256(self.open_at) if self.open_at else None,
'seq': self.seq,
'channel_type': self.channel_type,
'marketmaker': bytes(self.marketmaker) if self.marketmaker else None,
'actor': bytes(self.actor) if self.actor else None,
'delegate': bytes(self.delegate) if self.delegate else None,
'recipient': bytes(self.recipient) if self.recipient else None,
'amount': pack_uint256(self.amount) if self.amount else 0,
'timeout': self.timeout,
'state': self.state,
'closing_at': pack_uint256(self.closing_at) if self.closing_at else None,
'closed_at': pack_uint256(self.closed_at) if self.closed_at else None,
'close_mm_sig': bytes(self.close_mm_sig) if self.close_mm_sig else None,
'close_del_sig': bytes(self.close_del_sig) if self.close_del_sig else None,
'close_channel_seq': self.close_channel_seq,
'close_balance': pack_uint256(self.close_balance),
'close_is_final': self.close_is_final,
'closed_tx': bytes(self.closed_tx) if self.closed_tx else None,
}
return obj
def __str__(self):
return '\n{}\n'.format(pprint.pformat(self.marshal()))
@property
def market_oid(self) -> UUID:
"""
The unique OID of the market.
"""
if self._market_oid is None and self._from_fbs:
if self._from_fbs.MarketOidLength():
_market_oid = self._from_fbs.MarketOidAsBytes()
self._market_oid = UUID(bytes=bytes(_market_oid))
return self._market_oid
@market_oid.setter
def market_oid(self, value: UUID):
assert value is None or isinstance(value, UUID)
self._market_oid = value
@property
def member_oid(self) -> UUID:
"""
The unique OID of the member.
"""
if self._member_oid is None and self._from_fbs:
if self._from_fbs.MemberOidLength():
_member_oid = self._from_fbs.MemberOidAsBytes()
self._member_oid = UUID(bytes=bytes(_member_oid))
return self._member_oid
@member_oid.setter
def member_oid(self, value: UUID):
assert value is None or isinstance(value, UUID)
self._member_oid = value
@property
def channel_oid(self) -> UUID:
"""
The unique OID of the channel.
"""
if self._channel_oid is None and self._from_fbs:
if self._from_fbs.ChannelOidLength():
_channel_oid = self._from_fbs.ChannelOidAsBytes()
self._channel_oid = UUID(bytes=bytes(_channel_oid))
return self._channel_oid
@channel_oid.setter
def channel_oid(self, value: UUID):
assert value is None or isinstance(value, UUID)
self._channel_oid = value
@property
def timestamp(self) -> np.datetime64:
"""
Database transaction time (epoch time in ns) of insert or last update.
"""
if self._timestamp is None and self._from_fbs:
self._timestamp = np.datetime64(self._from_fbs.Timestamp(), 'ns')
return self._timestamp
@timestamp.setter
def timestamp(self, value: np.datetime64):
assert value is None or isinstance(value, np.datetime64)
self._timestamp = value
@property
def open_at(self) -> int:
"""
Block number (on the blockchain) when the actor (originally) joined the market.
"""
if self._open_at is None and self._from_fbs:
if self._from_fbs.OpenAtLength():
_open_at = self._from_fbs.OpenAtAsBytes()
self._open_at = unpack_uint256(bytes(_open_at))
else:
self._open_at = 0
return self._open_at
@open_at.setter
def open_at(self, value: int):
assert value is None or type(value) == int
self._open_at = value
@property
def seq(self) -> int:
"""
Global channel sequence number.
"""
if self._seq is None and self._from_fbs:
self._seq = self._from_fbs.Seq()
return self._seq or 0
@seq.setter
def seq(self, value: int):
assert value is None or type(value) == int
self._seq = value
@property
def channel_type(self) -> int:
"""
Channel type: payment channel (from XBR consumer to XBR market maker) or paying channel (from XBR market maker to XBR provider).
"""
if self._channel_type is None and self._from_fbs:
self._channel_type = self._from_fbs.ChannelType()
return self._channel_type
@channel_type.setter
def channel_type(self, value: int):
assert type(value) == int
self._channel_type = value
@property
def marketmaker(self) -> bytes:
"""
ID of the payment channel.
"""
if self._marketmaker is None and self._from_fbs:
if self._from_fbs.MarketmakerLength():
self._marketmaker = self._from_fbs.MarketmakerAsBytes()
return self._marketmaker
@marketmaker.setter
def marketmaker(self, value: bytes):
assert value is None or type(value) == bytes
self._marketmaker = value
@property
def actor(self) -> bytes:
"""
Ethereum address of the sender (either XBR Consumer or XBR Market).
"""
if self._actor is None and self._from_fbs:
if self._from_fbs.ActorLength():
self._actor = self._from_fbs.ActorAsBytes()
return self._actor
@actor.setter
def actor(self, value: bytes):
assert value is None or type(value) == bytes
self._actor = value
@property
def delegate(self) -> bytes:
"""
Ethereum address of the sender delegate (either XBR Consumer delegate or XBR Market delegate == market maker)
"""
if self._delegate is None and self._from_fbs:
if self._from_fbs.DelegateLength():
self._delegate = self._from_fbs.DelegateAsBytes()
return self._delegate
@delegate.setter
def delegate(self, value: bytes):
assert value is None or type(value) == bytes
self._delegate = value
@property
def recipient(self) -> bytes:
"""
Ethereum address of the recipient (either XBR Market or XBR Provider)
"""
if self._recipient is None and self._from_fbs:
if self._from_fbs.RecipientLength():
self._recipient = self._from_fbs.RecipientAsBytes()
return self._recipient
@recipient.setter
def recipient(self, value: bytes):
assert value is None or type(value) == bytes
self._recipient = value
@property
def amount(self) -> int:
"""
Amount of XBR tokens initially deposited into the payment channel.
"""
if self._amount is None and self._from_fbs:
if self._from_fbs.AmountLength():
_amount = self._from_fbs.AmountAsBytes()
self._amount = unpack_uint256(bytes(_amount))
else:
self._amount = 0
return self._amount
@amount.setter
def amount(self, value: int):
assert value is None or type(value) == int
self._amount = value
@property
def timeout(self) -> int:
"""
Payment channel (non-cooperative) closed timeout in blocks (on the blockchain).
"""
if self._timeout is None and self._from_fbs:
self._timeout = self._from_fbs.Timeout()
return self._timeout
@timeout.setter
def timeout(self, value: int):
assert type(value) == int
self._timeout = value
@property
def state(self) -> int:
"""
Current state of payment channel.
"""
if self._state is None and self._from_fbs:
self._state = self._from_fbs.State()
return self._state
@state.setter
def state(self, value: int):
assert type(value) == int
self._state = value
@property
def closing_at(self) -> int:
"""
Block number (on the blockchain) when the payment channel will close (at the latest).
"""
if self._closing_at is None and self._from_fbs:
if self._from_fbs.ClosingAtLength():
_closing_at = self._from_fbs.ClosingAtAsBytes()
self._closing_at = unpack_uint256(bytes(_closing_at))
else:
self._closed_at = 0
return self._closing_at
@closing_at.setter
def closing_at(self, value: int):
assert value is None or type(value) == int
self._closing_at = value
@property
def closed_at(self) -> int:
"""
Block number (on the blockchain) when the payment channel was finally closed.
"""
if self._closed_at is None and self._from_fbs:
if self._from_fbs.ClosedAtLength():
_closed_at = self._from_fbs.ClosedAtAsBytes()
self._closed_at = unpack_uint256(bytes(_closed_at))
else:
self._closed_at = 0
return self._closed_at
@closed_at.setter
def closed_at(self, value: int):
assert value is None or type(value) == int
self._closed_at = value
@property
def close_mm_sig(self) -> int:
"""
Closing signature by market maker.
"""
if self._close_mm_sig is None and self._from_fbs:
if self._from_fbs.CloseMmSigLength():
self._close_mm_sig = self._from_fbs.CloseMmSigAsBytes()
return self._close_mm_sig
@close_mm_sig.setter
def close_mm_sig(self, value: int):
assert value is None or type(value) == bytes
self._close_mm_sig = value
@property
def close_del_sig(self) -> bytes:
"""
Closing signature by (seller or buyer) delegate.
"""
if self._close_del_sig is None and self._from_fbs:
if self._from_fbs.CloseDelSigLength():
self._close_del_sig = self._from_fbs.CloseDelSigAsBytes()
return self._close_del_sig
@close_del_sig.setter
def close_del_sig(self, value: bytes):
assert value is None or type(value) == bytes
self._close_del_sig = value
@property
def close_channel_seq(self) -> int:
"""
Last off-chain, closing transaction: channel transaction sequence number.
"""
if self._close_channel_seq is None and self._from_fbs:
self._close_channel_seq = self._from_fbs.CloseChannelSeq()
return self._close_channel_seq
@close_channel_seq.setter
def close_channel_seq(self, value: int):
assert type(value) == int
self._close_channel_seq = value
@property
def close_balance(self) -> int:
"""
Remaining (closing) channel balance (XBR).
"""
if self._close_balance is None and self._from_fbs:
if self._from_fbs.CloseBalanceLength():
_close_balance = self._from_fbs.CloseBalanceAsBytes()
if _close_balance is not None:
self._close_balance = unpack_uint256(bytes(_close_balance))
else:
self._close_balance = 0
else:
self._close_balance = 0
return self._close_balance
@close_balance.setter
def close_balance(self, value: int):
assert value is None or type(value) == int
self._close_balance = value
@property
def close_is_final(self) -> bool:
"""
Flag indication if close is final (happens immediately without a channel timeout).
"""
if self._close_is_final is None and self._from_fbs:
self._close_is_final = (self._from_fbs.CloseIsFinal() is True)
return self._close_is_final
@close_is_final.setter
def close_is_final(self, value: bool):
assert value is None or type(value) == bool
self._close_is_final = value
@property
def closed_tx(self) -> bytes:
"""
When channel was finally closed on-chain, the Ethereum transaction ID.
"""
if self._closed_tx is None and self._from_fbs:
if self._from_fbs.ClosedTxLength():
self._closed_tx = self._from_fbs.ClosedTxAsBytes()
return self._closed_tx
@closed_tx.setter
def closed_tx(self, value: bytes):
assert value is None or type(value) == bytes
self._closed_tx = value
@staticmethod
def cast(buf):
return Channel(_ChannelGen.GetRootAsChannel(buf, 0))
def build(self, builder):
market_oid = self.market_oid
if market_oid:
market_oid = builder.CreateString(market_oid.bytes)
member_oid = self.member_oid
if member_oid:
member_oid = builder.CreateString(member_oid.bytes)
channel_oid = self.channel_oid
if channel_oid:
channel_oid = builder.CreateString(channel_oid.bytes)
open_at = self.open_at
if open_at:
open_at = builder.CreateString(pack_uint256(open_at))
marketmaker = self.marketmaker
if marketmaker:
marketmaker = builder.CreateString(bytes(marketmaker))
actor = self.actor
if actor:
actor = builder.CreateString(bytes(actor))
delegate = self.delegate
if delegate:
delegate = builder.CreateString(bytes(delegate))
recipient = self.recipient
if recipient:
recipient = builder.CreateString(bytes(recipient))
amount = self.amount
if amount:
amount = builder.CreateString(pack_uint256(amount))
closing_at = self.closing_at
if closing_at:
closing_at = builder.CreateString(pack_uint256(closing_at))
closed_at = self.closed_at
if closed_at:
closed_at = builder.CreateString(pack_uint256(closed_at))
close_mm_sig = self.close_mm_sig
if close_mm_sig:
close_mm_sig = builder.CreateString(bytes(close_mm_sig))
close_del_sig = self.close_del_sig
if close_del_sig:
close_del_sig = builder.CreateString(bytes(close_del_sig))
close_balance = self.close_balance
if close_balance:
close_balance = builder.CreateString(pack_uint256(close_balance))
closed_tx = self.closed_tx
if closed_tx:
closed_tx = builder.CreateString(bytes(closed_tx))
ChannelGen.ChannelStart(builder)
if market_oid:
ChannelGen.ChannelAddMarketOid(builder, market_oid)
if member_oid:
ChannelGen.ChannelAddMemberOid(builder, member_oid)
if channel_oid:
ChannelGen.ChannelAddChannelOid(builder, channel_oid)
if self.timestamp:
ChannelGen.ChannelAddTimestamp(builder, int(self.timestamp))
if open_at:
ChannelGen.ChannelAddOpenAt(builder, open_at)
if self.seq:
ChannelGen.ChannelAddSeq(builder, self.seq)
if self.channel_type:
ChannelGen.ChannelAddChannelType(builder, self.channel_type)
if marketmaker:
ChannelGen.ChannelAddMarketmaker(builder, marketmaker)
if actor:
ChannelGen.ChannelAddActor(builder, actor)
if delegate:
ChannelGen.ChannelAddDelegate(builder, delegate)
if recipient:
ChannelGen.ChannelAddRecipient(builder, recipient)
if amount:
ChannelGen.ChannelAddAmount(builder, amount)
ChannelGen.ChannelAddTimeout(builder, self.timeout)
if self.state:
ChannelGen.ChannelAddState(builder, int(self.state))
if closing_at:
ChannelGen.ChannelAddClosingAt(builder, closing_at)
if closed_at:
ChannelGen.ChannelAddClosedAt(builder, closed_at)
if close_mm_sig:
ChannelGen.ChannelAddCloseMmSig(builder, close_mm_sig)
if close_del_sig:
ChannelGen.ChannelAddCloseDelSig(builder, close_del_sig)
if self.close_channel_seq:
ChannelGen.ChannelAddCloseChannelSeq(builder, self.close_channel_seq)
if close_balance:
ChannelGen.ChannelAddCloseBalance(builder, close_balance)
if self.close_is_final:
ChannelGen.ChannelAddCloseIsFinal(builder, self.close_is_final)
if closed_tx:
ChannelGen.ChannelAddClosedTx(builder, closed_tx)
final = ChannelGen.ChannelEnd(builder)
return final
[docs]@table('b3d01946-85ae-49f3-ad96-b78194eb82fe', build=Channel.build, cast=Channel.cast)
class PaymentChannels(MapUuidFlatBuffers):
"""
XBR payment channels by ``channel_oid``.
Map :class:`zlmdb.MapUuidFlatBuffers` from ``channel_oid`` to :class:`cfxdb.xbr.Channel`
"""
[docs]@table('cffd5253-72f8-41a9-8b76-5e6ff3654e67')
class IndexPaymentChannelByDelegate(MapBytes20TimestampUuid):
"""
Index: ``(delegate_adr, created_timestamp) -> channel_oid``
"""
@table('c78e0113-3b40-42b1-a15f-0b478ccf0de4')
class IndexPaymentChannelByActor(MapBytes20TimestampUuid):
"""
Index: ``(actor_adr, created_timestamp) -> channel_oid``
"""
@table('4e7e7c8d-db0d-4dea-8409-ac8f21ce1e10', build=Channel.build, cast=Channel.cast)
class PayingChannels(MapUuidFlatBuffers):
"""
XBR paying channels by ``channel_oid``.
Map :class:`zlmdb.MapUuidFlatBuffers` from ``channel_oid`` to :class:`cfxdb.xbr.Channel`
"""
@table('cee954be-fdb2-43cc-8891-529d6c7a0c3b')
class IndexPayingChannelByDelegate(MapBytes20TimestampUuid):
"""
Index: ``(delegate_adr, created_timestamp) -> channel_oid``
"""
@table('655a9d5f-0bdf-4c2a-8102-208f6da4a566')
class IndexPayingChannelByRecipient(MapBytes20TimestampUuid):
"""
Index: ``(recipient_adr, created_timestamp) -> channel_oid``
"""
class _ChannelBalanceGen(ChannelBalanceGen.ChannelBalance):
"""
Expand methods on the class code generated by flatc.
FIXME: come up with a PR for flatc to generated this stuff automatically.
"""
@classmethod
def GetRootAsChannelBalance(cls, buf, offset):
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
x = _ChannelBalanceGen()
x.Init(buf, n + offset)
return x
def RemainingAsBytes(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
if o != 0:
_off = self._tab.Vector(o)
_len = self._tab.VectorLen(o)
return memoryview(self._tab.Bytes)[_off:_off + _len]
return None
def InflightAsBytes(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
if o != 0:
_off = self._tab.Vector(o)
_len = self._tab.VectorLen(o)
return memoryview(self._tab.Bytes)[_off:_off + _len]
return None
class ChannelBalance(object):
"""
XBR payment channel current (off-chain) balance. The sum of ``Balance.remaining`` and ``Balance.inflight`` equals ``Channel.amount``.
"""
def __init__(self, from_fbs=None):
self._from_fbs = from_fbs
self._remaining = None
self._inflight = None
self._seq = None
@staticmethod
def parse(data: dict):
assert type(data) == dict
obj = ChannelBalance()
if 'remaining' in data:
remaining = data['remaining']
assert type(remaining) == bytes and len(remaining) == 32
obj._remaining = unpack_uint256(remaining)
if 'inflight' in data:
inflight = data['inflight']
assert type(inflight) == bytes and len(inflight) == 32
obj._inflight = unpack_uint256(inflight)
if 'seq' in data:
seq = data['seq']
assert type(seq) == int
obj._seq = unpack_uint256(seq)
return obj
def marshal(self) -> dict:
obj = {
'remaining': pack_uint256(self.remaining) if self.remaining else 0,
'inflight': pack_uint256(self.inflight) if self.inflight else 0,
'seq': self.seq or 0
}
return obj
def __str__(self):
return '\n{}\n'.format(pprint.pformat(self.marshal()))
@property
def remaining(self) -> int:
"""
Amount of XBR tokens currently remaining in the payment channel.
"""
if self._remaining is None and self._from_fbs:
if self._from_fbs.RemainingLength():
_remaining = self._from_fbs.RemainingAsBytes()
self._remaining = unpack_uint256(bytes(_remaining))
else:
self._remaining = 0
return self._remaining
@remaining.setter
def remaining(self, value: int):
assert value is None or type(value) == int
self._remaining = value
@property
def inflight(self) -> int:
"""
Amount of XBR tokens reserved to in-flight purchase transactions.
"""
if self._inflight is None and self._from_fbs:
if self._from_fbs.InflightLength():
_inflight = self._from_fbs.InflightAsBytes()
self._inflight = unpack_uint256(bytes(_inflight))
else:
self._inflight = 0
return self._inflight
@inflight.setter
def inflight(self, value: int):
assert value is None or type(value) == int
self._inflight = value
@property
def seq(self) -> int:
"""
Sequence number of transactions on this balance starting from 0 when the payment channel is created.
"""
if self._seq is None and self._from_fbs:
self._seq = self._from_fbs.Seq()
return self._seq or 0
@seq.setter
def seq(self, value: int):
assert value is None or type(value) == int
self._seq = value
@staticmethod
def cast(buf):
return ChannelBalance(_ChannelBalanceGen.GetRootAsChannelBalance(buf, 0))
def build(self, builder):
remaining = self.remaining
if remaining:
remaining = builder.CreateString(pack_uint256(remaining))
inflight = self.inflight
if inflight:
inflight = builder.CreateString(pack_uint256(inflight))
ChannelBalanceGen.ChannelBalanceStart(builder)
if remaining:
ChannelBalanceGen.ChannelBalanceAddRemaining(builder, remaining)
if inflight:
ChannelBalanceGen.ChannelBalanceAddInflight(builder, inflight)
if self.seq:
ChannelBalanceGen.ChannelBalanceAddSeq(builder, self.seq)
final = ChannelBalanceGen.ChannelBalanceEnd(builder)
return final
[docs]@table('878ac002-a830-488b-bfe9-f06371b8eecb', build=ChannelBalance.build, cast=ChannelBalance.cast)
class PaymentChannelBalances(MapUuidFlatBuffers):
"""
XBR payment channels current balances by ``channel_oid``.
Map :class:`zlmdb.MapBytes20FlatBuffers` from ``channel_oid`` to :class:`cfxdb.xbr.Balance`
"""
@table('c0931d5d-6d5d-4f9c-b2a3-29664a0f4c07', build=ChannelBalance.build, cast=ChannelBalance.cast)
class PayingChannelBalances(MapUuidFlatBuffers):
"""
XBR paying channels current balances by ``channel_oid``.
Map :class:`zlmdb.MapBytes20FlatBuffers` from ``channel_oid`` to :class:`cfxdb.xbr.Balance`
"""