def SignRemoteHTLCToUs(self, request, context): """BOLT #3 - HTLC Outputs, phase 1 Sign an htlc-success tx on a remote HTLC output offered to us, assuming we know the preimage, at force-close time """ node_id = request.node_id.data node = self.nodes.get(node_id) logger.debug("SignRemoteHTLCToUs node:%s" % node_id.hex()) channel_nonce = request.channel_nonce.data channel = node.channels.get(channel_nonce) remote_per_commit_point = request.remote_per_commit_point.data tx = request.tx amount = tx.input_descs[0].prev_output.value_sat redeemscript = tx.input_descs[0].redeem_script reply = remotesigner_pb2.SignatureReply() htlc_key = Key( import_key=channel.basepoints.keys.htlc_basepoint_secret, is_private=True) htlc_basepoint = htlc_key.public_compressed_byte local_priv_key = derive_priv_key( remote_per_commit_point, htlc_basepoint, channel.basepoints.keys.htlc_basepoint_secret) local_key = Key(import_key=local_priv_key, is_private=True) keys = [local_key] tx = Transaction.import_raw(tx.raw_tx_bytes, self.network) tx.inputs[0].script_type = "p2wsh" tx.inputs[0].witness_type = 'segwit' tx.inputs[0].redeemscript = redeemscript tx.inputs[0].value = amount tx.witness_type = 'segwit' tx.sign(keys=keys, tid=0) logger.debug("remote_per_commit_point %s" % remote_per_commit_point.hex()) logger.debug("channel.basepoints.funding_pk %s" % channel.basepoints.funding_pk.hex()) reply.signature.data = tx.inputs[0].signatures[0].as_der_encoded( ) + b'\x01' return reply
def SignLocalHTLCTx(self, request, context): """BOLT #3 - HTLC Outputs, phase 1 Sign an htlc-success tx spending a local HTLC output, assuming we know the preimage, at force-close time """ node_id = request.node_id.data node = self.nodes.get(node_id) logger.debug("SignLocalHTLCTx node:%s" % node_id.hex()) channel_nonce = request.channel_nonce.data channel = node.channels.get(channel_nonce) n = request.n tx = request.tx amount = tx.input_descs[0].prev_output.value_sat redeemscript = tx.input_descs[0].redeem_script reply = remotesigner_pb2.SignatureReply() htlc_basepoint = channel.basepoints.htlc element = shachain_derive(channel.shaelement, START_INDEX - n) per_commitment_point_prv = coincurve.PrivateKey( secret=bytes(element.secret)) local_per_commit_point = per_commitment_point_prv.public_key.format() local_priv_key = derive_priv_key( local_per_commit_point, htlc_basepoint, channel.basepoints.keys.htlc_basepoint_secret) local_key = Key(import_key=local_priv_key, is_private=True) keys = [local_key] tx = Transaction.import_raw(tx.raw_tx_bytes, self.network) tx.inputs[0].script_type = "p2wsh" tx.inputs[0].witness_type = 'segwit' tx.inputs[0].redeemscript = redeemscript tx.inputs[0].value = amount tx.witness_type = 'segwit' tx.sign(keys=keys, tid=0) reply.signature.data = tx.inputs[0].signatures[0].as_der_encoded( ) + b'\x01' return reply
def SignDelayedPaymentToUs(self, request, context): """BOLT #5 - Unilateral Close Handling, phase 1 Sign a delayed to-local output - either from the commitment tx or from an HTLC, at force-close time """ node_id = request.node_id.data node = self.nodes.get(node_id) logger.debug("SignDelayedPaymentToUs node:%s" % node_id.hex()) channel_nonce = request.channel_nonce.data channel = node.channels.get(channel_nonce) n = request.n tx = request.tx amount = tx.input_descs[0].prev_output.value_sat redeemscript = tx.input_descs[0].redeem_script reply = remotesigner_pb2.SignatureReply() delayed_payment_basepoint = channel.basepoints.delayed_payment element = shachain_derive(channel.shaelement, START_INDEX - n) per_commitment_point_prv = coincurve.PrivateKey( secret=bytes(element.secret)) local_per_commit_point = per_commitment_point_prv.public_key.format() local_priv_key = derive_priv_key( local_per_commit_point, delayed_payment_basepoint, channel.basepoints.keys.delayed_payment_basepoint_secret) local_key = Key(import_key=local_priv_key, is_private=True) keys = [local_key] tx = Transaction.import_raw(tx.raw_tx_bytes, self.network) tx.inputs[0].script_type = "p2wsh" tx.inputs[0].witness_type = 'segwit' tx.inputs[0].redeemscript = redeemscript tx.inputs[0].value = amount tx.witness_type = 'segwit' tx.sign(keys=keys, tid=0) reply.signature.data = tx.inputs[0].signatures[0].as_der_encoded( ) + b'\x01' return reply
def SignPenaltyToUs(self, request, context): """BOLT #5 - Unilateral Close Handling, phase 1 Sign a penalty tx to us - either sweeping the to-local commitment tx output or sweeping an HTLC tx output, after the remote broadcast a revoked commitment transaction. """ node_id = request.node_id.data node = self.nodes.get(node_id) logger.debug("SignPenaltyToUs node:%s" % node_id.hex()) channel_nonce = request.channel_nonce.data channel = node.channels.get(channel_nonce) revocation_secret = request.revocation_secret.data tx = request.tx amount = tx.input_descs[0].prev_output.value_sat redeemscript = tx.input_descs[0].redeem_script index = request.input revocationprivkey = derive_blinded_privkey( revocation_secret, channel.basepoints.keys.revocation_basepoint_secret) local_key = Key(import_key=revocationprivkey, is_private=True) keys = [local_key] tx = Transaction.import_raw(tx.raw_tx_bytes, self.network) tx.inputs[index].script_type = "p2wsh" tx.inputs[index].witness_type = 'segwit' tx.inputs[index].redeemscript = redeemscript tx.inputs[index].value = amount tx.witness_type = 'segwit' tx.sign(keys=keys, tid=index) reply = remotesigner_pb2.SignatureReply() reply.signature.data = tx.inputs[index].signatures[0].as_der_encoded( ) + b'\x01' return reply
def SignRemoteCommitmentTx(self, request, context): """BOLT #3 - Commitment Transaction, phase 1 Sign the remote commitment tx, at commitment time """ node_id = request.node_id.data node = self.nodes.get(node_id) logger.debug("SignRemoteCommitmentTx node:%s" % node_id.hex()) channel_nonce = request.channel_nonce.data channel = node.channels.get(channel_nonce) tx = request.tx amount = tx.input_descs[0].prev_output.value_sat reply = remotesigner_pb2.SignatureReply() local_key = Key(import_key=channel.funding_privkey, is_private=True) remote_pub = channel.remote_basepoints.funding_pubkey remote_pubkey = Key( import_key=channel.remote_basepoints.funding_pubkey) pubs = sorted([remote_pub, local_key.public_compressed_byte]) if remote_pub == pubs[0]: keys = [remote_pubkey, local_key] else: keys = [local_key, remote_pubkey] tx = Transaction.import_raw(tx.raw_tx_bytes, self.network) tx.inputs[0].script_type = "p2wsh" tx.inputs[0].witness_type = 'segwit' tx.inputs[0].sigs_required = 2 tx.inputs[0].value = amount tx.witness_type = 'segwit' tx.sign(keys=keys, tid=0) logger.debug("channel.basepoints.funding_pk %s" % channel.basepoints.funding_pk.hex()) reply.signature.data = tx.inputs[0].signatures[0].as_der_encoded( ) + b'\x01' return reply