예제 #1
0
    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
예제 #2
0
    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
예제 #3
0
    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
예제 #4
0
    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
예제 #5
0
    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