def node_announcement(self, side: Side, features: str, rgb_color: Tuple[int, int, int], alias: str, addresses: bytes, timestamp: int) -> Message: # Begin with a fake signature. ann = Message(namespace().get_msgtype('node_announcement'), signature=Sig(bytes(64)), features=features, timestamp=timestamp, node_id=self.node_id(side).format().hex(), rgb_color=bytes(rgb_color).hex(), alias=bytes(alias, encoding='utf-8').zfill(32), addresses=addresses) # BOLT #7: # - MUST set `signature` to the signature of the double-SHA256 of the entire # remaining packet after `signature` (using the key given by `node_id`). buf = io.BytesIO() ann.write(buf) # Note the first two 'type' bytes! h = sha256(sha256(buf.getvalue()[2 + 64:]).digest()).digest() ann.set_field('signature', Sig(self.node_privkeys[side].secret.hex(), h.hex())) return ann
def get_output_message(self, conn: Conn, event: ExpectMsg) -> Optional[bytes]: if self.config.getoption('verbose'): print("[GET_OUTPUT_MESSAGE {}]".format(conn)) # We make the message they were expecting. msg = Message(event.msgtype, **event.resolve_args(self, event.kwargs)) # Fake up the other fields. for m in msg.missing_fields(): ftype = msg.messagetype.find_field(m.name) msg.set_field(m.name, self.fake_field(ftype.fieldtype)) binmsg = io.BytesIO() msg.write(binmsg) return binmsg.getvalue()
def channel_update(self, short_channel_id: str, side: Side, disable: bool, cltv_expiry_delta: int, htlc_minimum_msat: int, fee_base_msat: int, fee_proportional_millionths: int, timestamp: int, htlc_maximum_msat: Optional[int]) -> Message: # BOLT #7: The `channel_flags` bitfield is used to indicate the # direction of the channel: it identifies the node that this update # originated from and signals various options concerning the # channel. The following table specifies the meaning of its individual # bits: # # | Bit Position | Name | Meaning | # | ------------- | ----------- | -------------------------------- | # | 0 | `direction` | Direction this update refers to. | # | 1 | `disable` | Disable the channel. | # BOLT #7: # - if the origin node is `node_id_1` in the message: # - MUST set the `direction` bit of `channel_flags` to 0. # - otherwise: # - MUST set the `direction` bit of `channel_flags` to 1. if self.funding_pubkey(side) == self.funding_pubkeys_for_gossip()[0]: channel_flags = 0 else: channel_flags = 1 if disable: channel_flags |= 2 # BOLT #7: The `message_flags` bitfield is used to indicate the # presence of optional fields in the `channel_update` message: # # | Bit Position | Name | Field | # | ------------- | ------------------------- | -------------------------------- | # | 0 | `option_channel_htlc_max` | `htlc_maximum_msat` | message_flags = 0 if htlc_maximum_msat: message_flags |= 1 # Begin with a fake signature. update = Message(namespace().get_msgtype('channel_update'), short_channel_id=short_channel_id, signature=Sig(bytes(64)), chain_hash=self.chain_hash, timestamp=timestamp, message_flags=message_flags, channel_flags=channel_flags, cltv_expiry_delta=cltv_expiry_delta, htlc_minimum_msat=htlc_minimum_msat, fee_base_msat=fee_base_msat, fee_proportional_millionths=fee_proportional_millionths) if htlc_maximum_msat: update.set_field('htlc_maximum_msat', htlc_maximum_msat) # BOLT #7: # - MUST set `signature` to the signature of the double-SHA256 of the # entire remaining packet after `signature`, using its own `node_id`. buf = io.BytesIO() update.write(buf) # Note the first two 'type' bytes! h = sha256(sha256(buf.getvalue()[2 + 64:]).digest()).digest() update.set_field('signature', Sig(self.node_privkeys[side].secret.hex(), h.hex())) return update