teos.watcher¶
-
exception
AppointmentAlreadyTriggered(msg, **kwargs)[source]¶ Bases:
common.exceptions.BasicExceptionRaised 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.BasicExceptionRaised when the tower maximum appointment count has been reached.
-
exception
AppointmentNotFound(msg, **kwargs)[source]¶ Bases:
common.exceptions.BasicExceptionRaised when an appointment is not found on the tower.
-
class
LocatorCache(blocks_in_cache)[source]¶ Bases:
objectThe
LocatorCachekeeps the data about the lastcache_sizeblocks around so appointments can be checked against it. The data is indexed by locator and it’s mainly built during the normalWatcheroperation 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_txidpairs that received appointments are checked against.- Type
dict
-
blocks¶ An ordered dictionary of the last
blocks_in_cacheblocks (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_sizeblocks 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
strorNone
-
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:
objectThe
Watcheris in charge of watching for channel breaches for the appointments accepted by the tower.The
Watcherkeeps track of the accepted appointments inappointmentsand, for new received blocks, checks if any breach has happened by comparing the txids with the appointment locators. If a breach is seen, theencrypted_blobof 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
Watcherreceives information about new received blocks via theblock_queuethat 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 theWatcherat 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 (
ExtendedAppointmentinstances) accepted by the tower (locatoranduser_id). It’s populated troughadd_appointment.- Type
dict
-
locator_uuid_map¶ A
locator:uuidmap used to allow theWatcherto deal with several appointments with the samelocator.- Type
dict
-
block_queue¶ A queue used by the
Watcherto 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
Watcherat the same time.- Type
int
-
locator_cache¶ A cache of locators for the last
blocks_in_cacheblocks.- Type
- Raises
InvalidKey – if teos sk cannot be loaded.
-
add_appointment(appointment, user_signature)[source]¶ Adds a new appointment to the
appointmentsdictionary ifmax_appointmentshas not been reached.add_appointmentis the entry point of theWatcher. Upon receiving a new appointment it will start monitoring the blockchain (do_watch) untilappointmentsis empty.Once a breach is seen on the blockchain, the
Watcherwill decrypt the correspondingencrypted_bloband pass the information to theResponder.The tower may store multiple appointments with the same
locatorto 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 byuuidand stored inappointmentsandlocator_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_slotsandsubscription_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
ChainMonitoradds 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
Watcherand the one in charge to pass appointments to theResponderupon detecting a breach.
-
filter_breaches(breaches)[source]¶ Filters the valid from the invalid channel breaches.
The
Watchercannot know if anencrypted_blobcontains 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.
Noneif not found, or theuser_idis 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.