teos.watcher¶
-
exception
AppointmentAlreadyTriggered
(msg, **kwargs)[source]¶ Bases:
common.exceptions.BasicException
Raised when an appointment is sent to the Watcher but that same data has already been sent to the
Responder
.
-
exception
AppointmentLimitReached
(msg, **kwargs)[source]¶ Bases:
common.exceptions.BasicException
Raised when the tower maximum appointment count has been reached.
-
exception
AppointmentNotFound
(msg, **kwargs)[source]¶ Bases:
common.exceptions.BasicException
Raised when an appointment is not found on the tower.
-
class
LocatorCache
(blocks_in_cache)[source]¶ Bases:
object
The
LocatorCache
keeps the data about the lastcache_size
blocks around so appointments can be checked against it. The data is indexed by locator and it’s mainly built during the normalWatcher
operation so no extra steps are normally needed.- Parameters
blocks_in_cache (
int
) – the numbers of blocks to keep in the cache.
-
logger
¶ The logger for this component.
- Type
Logger
-
cache
¶ A dictionary of
locator:dispute_txid
pairs that received appointments are checked against.- Type
dict
-
blocks
¶ An ordered dictionary of the last
blocks_in_cache
blocks (block_hash:locators
). Used to keep track of what data belongs to what block, so data can be pruned accordingly. Also needed to rebuild the cache in case of reorgs.- Type
OrderedDict
-
cache_size
¶ The size of the cache in blocks.
- Type
int
-
fix
(last_known_block, block_processor)[source]¶ Fixes the cache after a reorg has been detected by feeding the most recent
cache_size
blocks to it.- Parameters
last_known_block (
str
) – the last known block hash after the reorg.block_processor (
BlockProcessor
) – a block processor instance.
-
get_txid
(locator)[source]¶ Gets a txid from the locator cache.
- Parameters
locator (
str
) – the locator to lookup in the cache.- Returns
The txid linked to the given locator if found. None otherwise.
- Return type
str
orNone
-
init
(last_known_block, block_processor)[source]¶ Sets the initial state of the locator cache.
- Parameters
last_known_block (
str
) – the last known block by theWatcher
.block_processor (
BlockProcessor
) – a block processor instance.
-
update
(block_hash, locator_txid_map)[source]¶ Updates the cache with data from a new block. Removes the oldest block if the cache is full after the addition.
- Parameters
block_hash (
str
) – the hash of the new block.locator_txid_map (
dict
) – the dictionary of locators (locator:txid) derived from a list of transaction ids.
-
class
Watcher
(db_manager, gatekeeper, block_processor, responder, sk, max_appointments, blocks_in_cache)[source]¶ Bases:
object
The
Watcher
is in charge of watching for channel breaches for the appointments accepted by the tower.The
Watcher
keeps track of the accepted appointments inappointments
and, for new received blocks, checks if any breach has happened by comparing the txids with the appointment locators. If a breach is seen, theencrypted_blob
of the corresponding appointment is decrypted and the data is passed to theResponder
.If an appointment reaches its end with no breach, the data is simply deleted.
The
Watcher
receives information about new received blocks via theblock_queue
that is populated by theChainMonitor
.- Parameters
db_manager (
AppointmentsDBM
) – an instance of the appointment database manager to interact with the database.block_processor (
BlockProcessor
) – a block processor instance to get block from bitcoind.responder (
Responder
) – a responder instance.sk (
PrivateKey
) – a private key used to sign accepted appointments.max_appointments (
int
) – the maximum amount of appointments accepted by theWatcher
at the same time.blocks_in_cache (
int
) – the number of blocks to keep in cache so recently triggered appointments can be covered.
-
appointments
¶ A dictionary containing a summary of the appointments (
ExtendedAppointment
instances) accepted by the tower (locator
anduser_id
). It’s populated troughadd_appointment
.- Type
dict
-
locator_uuid_map
¶ A
locator:uuid
map used to allow theWatcher
to deal with several appointments with the samelocator
.- Type
dict
-
block_queue
¶ A queue used by the
Watcher
to receive block hashes frombitcoind
. It is populated by theChainMonitor
.- Type
Queue
-
db_manager
¶ An instance of the appointment database manager to interact with the database.
- Type
-
gatekeeper
¶ A gatekeeper instance in charge to control the user access and subscription expiry.
- Type
-
block_processor
¶ A block processor instance to get block from bitcoind.
- Type
-
signing_key
¶ A private key used to sign accepted appointments.
- Type
PrivateKey
-
max_appointments
¶ The maximum amount of appointments accepted by the
Watcher
at the same time.- Type
int
-
locator_cache
¶ A cache of locators for the last
blocks_in_cache
blocks.- Type
- Raises
InvalidKey – if teos sk cannot be loaded.
-
add_appointment
(appointment, user_signature)[source]¶ Adds a new appointment to the
appointments
dictionary ifmax_appointments
has not been reached.add_appointment
is the entry point of theWatcher
. Upon receiving a new appointment it will start monitoring the blockchain (do_watch
) untilappointments
is empty.Once a breach is seen on the blockchain, the
Watcher
will decrypt the correspondingencrypted_blob
and pass the information to theResponder
.The tower may store multiple appointments with the same
locator
to avoid DoS attacks based on data rewriting. locators` should be derived from thedispute_txid
, but that task is performed by the user, and the tower has no way of verifying whether or not they have been properly derived. Therefore, appointments are identified byuuid
and stored inappointments
andlocator_uuid_map
.- Parameters
appointment (
Appointment
) – the appointment to be added to theWatcher
.user_signature (
str
) – the user’s appointment signature (hex-encoded).
- Returns
The tower response as a dict, containing:
locator
,signature
,available_slots
andsubscription_expiry
.- Return type
dict
- Raises
AppointmentLimitReached – If the tower cannot hold more appointments (cap reached).
AuthenticationFailure – If the user cannot be authenticated.
NotEnoughSlots – If the user does not have enough available slots, so the appointment is rejected.
-
awake
()[source]¶ Starts a new thread to monitor the blockchain for channel breaches. The thread will run until the
ChainMonitor
adds the"END"
message to the queue.- Returns
The thread object that was just created and is already running.
- Return type
Thread
-
check_breach
(uuid, appointment, dispute_txid)[source]¶ Checks if a breach is valid. Valid breaches should decrypt to a valid transaction.
- Parameters
uuid (
str
) – the uuid of the appointment that was triggered by the breach.appointment (
ExtendedAppointment
) – the appointment data.dispute_txid (
str
) – the id of the transaction that triggered the breach.
- Returns
A tuple containing the penalty txid and the raw penalty tx.
- Return type
tuple
- Raises
EncryptionError – if the encrypted blob from the provided appointment cannot be decrypted with the key derived from the breach transaction id.
InvalidTransactionFormat – if the decrypted data does not have a valid transaction format.
-
do_watch
()[source]¶ Monitors the blockchain for channel breaches.
This is the main method of the
Watcher
and the one in charge to pass appointments to theResponder
upon detecting a breach.
-
filter_breaches
(breaches)[source]¶ Filters the valid from the invalid channel breaches.
The
Watcher
cannot know if anencrypted_blob
contains a valid transaction until a breach is seen. Blobs that contain arbitrary data are dropped and not sent to theResponder
.- Parameters
breaches (
dict
) – a dictionary containing channel breaches (locator:txid
).- Returns
A dictionary and a list. The former contains the valid breaches, while the latter contain the invalid ones.
The valid breaches dictionary has the following structure:
{locator, dispute_txid, penalty_txid, penalty_rawtx}
- Return type
tuple
-
get_all_responder_trackers
()[source]¶ Returns a dictionary with all the trackers stored in the db for the responder.
-
get_all_watcher_appointments
()[source]¶ Returns a dictionary with all the appointment stored in the db for the watcher.
-
get_appointment
(locator, user_signature)[source]¶ Gets information about an appointment.
The appointment can either be in the watcher, the responder, or not found.
- Parameters
locator (
str
) – a 16-byte hex-encoded value used by the tower to detect channel breaches.user_signature (
str
) – the signature of the request by the user.
- Returns
A tuple containing the appointment data and the status (either
"being_watched"
or"dispute_responded"
).- Return type
tuple
- Raises
AppointmentNotFound – if the appointment is not found in the tower.
-
get_breaches
(locator_txid_map)[source]¶ Gets a dictionary of channel breaches given a map of
locator:dispute_txid
.- Parameters
locator_txid_map (
dict
) – the dictionary of locators (locator:txid) derived from a list of transaction ids.- Returns
A dictionary (
locator:txid
) with all the breaches found. An empty dictionary if none are found.- Return type
dict
-
get_user_info
(user_id)[source]¶ Returns the data hold by the tower about the user given an
user_id
.- Parameters
user_id (
str
) – the id of the requested user.- Returns
The user data if found.
None
if not found, or theuser_id
is invalid.- Return type
UserInfo <teos.gatekeeper.UserInfo> or :obj:`None
-
property
n_registered_users
¶ Get the number of users currently registered to the tower.
-
property
n_responder_trackers
¶ Get the total number of trackers in the responder.
-
property
n_watcher_appointments
¶ Get the total number of appointments stored in the watcher.
-
register
(user_id)[source]¶ Registers a user.
- Parameters
user_id (
str
) – the public key that identifies the user (33-bytes hex str).- Returns
A tuple containing the available slots, the subscription expiry, and the signature of the registration receipt by the Watcher.
- Return type
tuple
-
property
tower_id
¶ Get the id of this tower, as a hex string.