Merge pull request #6450 from guggero/taproot-psbt
taproot: add PSBT signing support for Taproot, fix remote signing Taproot support
This commit is contained in:
16 files changed
+1380
-452
No files matched your search
@@ -25,6 +25,10 @@ addresses](https://github.com/lightningnetwork/lnd/pull/6263). Using
|
||||
then watch it on chain. Taproot script spends are also supported through the
|
||||
`signrpc.SignOutputRaw` RPC (`/v2/signer/signraw` in REST).
|
||||
|
||||
The `walletrpc.SignPsbt` RPC now also supports [Taproot PSBT
|
||||
signing](https://github.com/lightningnetwork/lnd/pull/6450) to fully support
|
||||
remote signing with Taproot outputs.
|
||||
|
||||
## MuSig2
|
||||
|
||||
The [`signrpc.Signer` RPC service now supports EXPERIMENTAL MuSig2
|
||||
|
||||
@@ -6,7 +6,7 @@ require (
|
||||
github.com/btcsuite/btcd v0.22.0-beta.0.20220413172512-bf64c8bdbbbf
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.2.0
|
||||
github.com/btcsuite/btcd/btcutil v1.1.1
|
||||
github.com/btcsuite/btcd/btcutil/psbt v1.1.3
|
||||
github.com/btcsuite/btcd/btcutil/psbt v1.1.4
|
||||
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1
|
||||
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f
|
||||
github.com/btcsuite/btcwallet v0.15.0
|
||||
@@ -16,7 +16,6 @@ require (
|
||||
github.com/btcsuite/btcwallet/wtxmgr v1.5.0
|
||||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1
|
||||
github.com/dvyukov/go-fuzz v0.0.0-20210602112143-b1f3d6f4ef4e
|
||||
github.com/go-errors/errors v1.0.1
|
||||
github.com/golang/protobuf v1.5.2
|
||||
@@ -76,6 +75,7 @@ require (
|
||||
github.com/coreos/go-systemd/v22 v22.3.2 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
||||
github.com/decred/dcrd/crypto/blake256 v1.0.0 // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
|
||||
github.com/decred/dcrd/lru v1.0.0 // indirect
|
||||
github.com/dsnet/compress v0.0.1 // indirect
|
||||
github.com/dustin/go-humanize v1.0.0 // indirect
|
||||
|
||||
@@ -87,8 +87,8 @@ github.com/btcsuite/btcd/btcutil v1.1.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUB
|
||||
github.com/btcsuite/btcd/btcutil v1.1.1 h1:hDcDaXiP0uEzR8Biqo2weECKqEw0uHDZ9ixIWevVQqY=
|
||||
github.com/btcsuite/btcd/btcutil v1.1.1/go.mod h1:nbKlBMNm9FGsdvKvu0essceubPiAcI57pYBNnsLAa34=
|
||||
github.com/btcsuite/btcd/btcutil/psbt v1.1.1/go.mod h1:KsGzRAzAdEimzgERpK9Xm+RhuCMvc4j2ctK0BEQ8JV0=
|
||||
github.com/btcsuite/btcd/btcutil/psbt v1.1.3 h1:fMVX0CHlVkI3VSkwMZTArfdVUkfzLuJA+ElQTfqekOU=
|
||||
github.com/btcsuite/btcd/btcutil/psbt v1.1.3/go.mod h1:GMJ40RHh0brZmhAKjltvYjakbVg9wQqfH+hZF96jIRE=
|
||||
github.com/btcsuite/btcd/btcutil/psbt v1.1.4 h1:Edx4AfBn+YPam2KP5AobDitulGp4r1Oibm8oruzkMdI=
|
||||
github.com/btcsuite/btcd/btcutil/psbt v1.1.4/go.mod h1:9AyU6EQVJ9Iw9zPyNT1lcdHd6cnEZdno5wLu5FY74os=
|
||||
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
|
||||
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U=
|
||||
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"github.com/btcsuite/btcd/btcutil"
|
||||
"github.com/btcsuite/btcd/txscript"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
secp "github.com/decred/dcrd/dcrec/secp256k1/v4"
|
||||
"golang.org/x/crypto/ripemd160"
|
||||
)
|
||||
|
||||
@@ -1399,7 +1398,7 @@ func TweakPubKeyWithTweak(pubKey *btcec.PublicKey,
|
||||
tweakJacobian btcec.JacobianPoint
|
||||
resultJacobian btcec.JacobianPoint
|
||||
)
|
||||
tweakKey := secp.PrivKeyFromBytes(tweakBytes)
|
||||
tweakKey, _ := btcec.PrivKeyFromBytes(tweakBytes)
|
||||
btcec.ScalarBaseMultNonConst(&tweakKey.Key, &tweakJacobian)
|
||||
|
||||
pubKey.AsJacobian(&pubKeyJacobian)
|
||||
@@ -1549,5 +1548,6 @@ func DeriveRevocationPrivKey(revokeBasePriv *btcec.PrivateKey,
|
||||
// the key-ring and also to used as a tweak to derive new public+private keys
|
||||
// for the state.
|
||||
func ComputeCommitmentPoint(commitSecret []byte) *btcec.PublicKey {
|
||||
return secp.PrivKeyFromBytes(commitSecret).PubKey()
|
||||
_, pubKey := btcec.PrivKeyFromBytes(commitSecret)
|
||||
return pubKey
|
||||
}
|
||||
+79
-4
@@ -3,6 +3,7 @@ package input
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
@@ -55,16 +56,29 @@ type SignDescriptor struct {
|
||||
// DoubleTweak, not both.
|
||||
DoubleTweak *btcec.PrivateKey
|
||||
|
||||
// TapTweak is a 32-byte value that will be used to derive a taproot
|
||||
// output public key (or the corresponding private key) from an
|
||||
// internal key and this tweak. The transformation applied is:
|
||||
// * outputKey = internalKey +
|
||||
// tagged_hash("tapTweak", internalKey || tapTweak)
|
||||
//
|
||||
// When attempting to sign an output derived via BIP 86, then this
|
||||
// field should be an empty byte array.
|
||||
//
|
||||
// When attempting to sign for the key spend path of an output key that
|
||||
// commits to an actual script tree, the script root should be used.
|
||||
TapTweak []byte
|
||||
|
||||
// WitnessScript is the full script required to properly redeem the
|
||||
// output. This field should be set to the full script if a p2wsh
|
||||
// output is being signed. For p2wkh it should be set to the hashed
|
||||
// script (PkScript).
|
||||
WitnessScript []byte
|
||||
|
||||
// TaprootKeySpend indicates that instead of a witness script being
|
||||
// spent by the signature that results from this signing request, a
|
||||
// taproot key spend is performed instead.
|
||||
TaprootKeySpend bool
|
||||
// SignMethod specifies how the input should be signed. Depending on the
|
||||
// selected method, either the TapTweak, WitnessScript or both need to
|
||||
// be specified.
|
||||
SignMethod SignMethod
|
||||
|
||||
// Output is the target output which should be signed. The PkScript and
|
||||
// Value fields within the output should be properly populated,
|
||||
@@ -89,6 +103,67 @@ type SignDescriptor struct {
|
||||
InputIndex int
|
||||
}
|
||||
|
||||
// SignMethod defines the different ways a signer can sign, given a specific
|
||||
// input.
|
||||
type SignMethod uint8
|
||||
|
||||
const (
|
||||
// WitnessV0SignMethod denotes that a SegWit v0 (p2wkh, np2wkh, p2wsh)
|
||||
// input script should be signed.
|
||||
WitnessV0SignMethod SignMethod = 0
|
||||
|
||||
// TaprootKeySpendBIP0086SignMethod denotes that a SegWit v1 (p2tr)
|
||||
// input should be signed by using the BIP0086 method (commit to
|
||||
// internal key only).
|
||||
TaprootKeySpendBIP0086SignMethod SignMethod = 1
|
||||
|
||||
// TaprootKeySpendSignMethod denotes that a SegWit v1 (p2tr)
|
||||
// input should be signed by using a given taproot hash to commit to in
|
||||
// addition to the internal key.
|
||||
TaprootKeySpendSignMethod SignMethod = 2
|
||||
|
||||
// TaprootScriptSpendSignMethod denotes that a SegWit v1 (p2tr) input
|
||||
// should be spent using the script path and that a specific leaf script
|
||||
// should be signed for.
|
||||
TaprootScriptSpendSignMethod SignMethod = 3
|
||||
)
|
||||
|
||||
// String returns a human-readable representation of the signing method.
|
||||
func (s SignMethod) String() string {
|
||||
switch s {
|
||||
case WitnessV0SignMethod:
|
||||
return "witness_v0"
|
||||
case TaprootKeySpendBIP0086SignMethod:
|
||||
return "taproot_key_spend_bip86"
|
||||
case TaprootKeySpendSignMethod:
|
||||
return "taproot_key_spend"
|
||||
case TaprootScriptSpendSignMethod:
|
||||
return "taproot_script_spend"
|
||||
default:
|
||||
return fmt.Sprintf("unknown<%d>", s)
|
||||
}
|
||||
}
|
||||
|
||||
// PkScriptCompatible returns true if the given public key script is compatible
|
||||
// with the sign method.
|
||||
func (s SignMethod) PkScriptCompatible(pkScript []byte) bool {
|
||||
switch s {
|
||||
// SegWit v0 can be p2wkh, np2wkh, p2wsh.
|
||||
case WitnessV0SignMethod:
|
||||
return txscript.IsPayToWitnessPubKeyHash(pkScript) ||
|
||||
txscript.IsPayToWitnessScriptHash(pkScript) ||
|
||||
txscript.IsPayToScriptHash(pkScript)
|
||||
|
||||
case TaprootKeySpendBIP0086SignMethod, TaprootKeySpendSignMethod,
|
||||
TaprootScriptSpendSignMethod:
|
||||
|
||||
return txscript.IsPayToTaproot(pkScript)
|
||||
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// WriteSignDescriptor serializes a SignDescriptor struct into the passed
|
||||
// io.Writer stream.
|
||||
//
|
||||
|
||||
+13
-3
@@ -7,7 +7,17 @@ import (
|
||||
"github.com/btcsuite/btcd/txscript"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/btcsuite/btcwallet/waddrmgr"
|
||||
secp "github.com/decred/dcrd/dcrec/secp256k1/v4"
|
||||
)
|
||||
|
||||
const (
|
||||
// PubKeyFormatCompressedOdd is the identifier prefix byte for a public
|
||||
// key whose Y coordinate is odd when serialized in the compressed
|
||||
// format per section 2.3.4 of
|
||||
// [SEC1](https://secg.org/sec1-v2.pdf#subsubsection.2.3.4).
|
||||
// This is copied from the github.com/decred/dcrd/dcrec/secp256k1/v4 to
|
||||
// avoid needing to directly reference (and by accident pull in
|
||||
// incompatible crypto primitives) the package.
|
||||
PubKeyFormatCompressedOdd byte = 0x03
|
||||
)
|
||||
|
||||
// NewTxSigHashesV0Only returns a new txscript.TxSigHashes instance that will
|
||||
@@ -56,7 +66,7 @@ func TapscriptFullTree(internalKey *btcec.PublicKey,
|
||||
tapKey := txscript.ComputeTaprootOutputKey(internalKey, rootHash[:])
|
||||
|
||||
var outputKeyYIsOdd bool
|
||||
if tapKey.SerializeCompressed()[0] == secp.PubKeyFormatCompressedOdd {
|
||||
if tapKey.SerializeCompressed()[0] == PubKeyFormatCompressedOdd {
|
||||
outputKeyYIsOdd = true
|
||||
}
|
||||
|
||||
@@ -85,7 +95,7 @@ func TapscriptPartialReveal(internalKey *btcec.PublicKey,
|
||||
rootHash := controlBlock.RootHash(revealedLeaf.Script)
|
||||
tapKey := txscript.ComputeTaprootOutputKey(internalKey, rootHash)
|
||||
|
||||
if tapKey.SerializeCompressed()[0] == secp.PubKeyFormatCompressedOdd {
|
||||
if tapKey.SerializeCompressed()[0] == PubKeyFormatCompressedOdd {
|
||||
controlBlock.OutputKeyYIsOdd = true
|
||||
}
|
||||
|
||||
|
||||
+404
-308
@@ -20,6 +20,70 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type SignMethod int32
|
||||
|
||||
const (
|
||||
//
|
||||
//Specifies that a SegWit v0 (p2wkh, np2wkh, p2wsh) input script should be
|
||||
//signed.
|
||||
SignMethod_SIGN_METHOD_WITNESS_V0 SignMethod = 0
|
||||
//
|
||||
//Specifies that a SegWit v1 (p2tr) input should be signed by using the
|
||||
//BIP0086 method (commit to internal key only).
|
||||
SignMethod_SIGN_METHOD_TAPROOT_KEY_SPEND_BIP0086 SignMethod = 1
|
||||
//
|
||||
//Specifies that a SegWit v1 (p2tr) input should be signed by using a given
|
||||
//taproot hash to commit to in addition to the internal key.
|
||||
SignMethod_SIGN_METHOD_TAPROOT_KEY_SPEND SignMethod = 2
|
||||
//
|
||||
//Specifies that a SegWit v1 (p2tr) input should be spent using the script
|
||||
//path and that a specific leaf script should be signed for.
|
||||
SignMethod_SIGN_METHOD_TAPROOT_SCRIPT_SPEND SignMethod = 3
|
||||
)
|
||||
|
||||
// Enum value maps for SignMethod.
|
||||
var (
|
||||
SignMethod_name = map[int32]string{
|
||||
0: "SIGN_METHOD_WITNESS_V0",
|
||||
1: "SIGN_METHOD_TAPROOT_KEY_SPEND_BIP0086",
|
||||
2: "SIGN_METHOD_TAPROOT_KEY_SPEND",
|
||||
3: "SIGN_METHOD_TAPROOT_SCRIPT_SPEND",
|
||||
}
|
||||
SignMethod_value = map[string]int32{
|
||||
"SIGN_METHOD_WITNESS_V0": 0,
|
||||
"SIGN_METHOD_TAPROOT_KEY_SPEND_BIP0086": 1,
|
||||
"SIGN_METHOD_TAPROOT_KEY_SPEND": 2,
|
||||
"SIGN_METHOD_TAPROOT_SCRIPT_SPEND": 3,
|
||||
}
|
||||
)
|
||||
|
||||
func (x SignMethod) Enum() *SignMethod {
|
||||
p := new(SignMethod)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x SignMethod) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (SignMethod) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_signrpc_signer_proto_enumTypes[0].Descriptor()
|
||||
}
|
||||
|
||||
func (SignMethod) Type() protoreflect.EnumType {
|
||||
return &file_signrpc_signer_proto_enumTypes[0]
|
||||
}
|
||||
|
||||
func (x SignMethod) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use SignMethod.Descriptor instead.
|
||||
func (SignMethod) EnumDescriptor() ([]byte, []int) {
|
||||
return file_signrpc_signer_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
type KeyLocator struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -228,11 +292,20 @@ type SignDescriptor struct {
|
||||
//tweakPriv*sha256(tweakPub || pubKey)) mod N
|
||||
DoubleTweak []byte `protobuf:"bytes,3,opt,name=double_tweak,json=doubleTweak,proto3" json:"double_tweak,omitempty"`
|
||||
//
|
||||
//The 32 byte input to the taproot tweak derivation that is used to derive
|
||||
//the output key from an internal key: outputKey = internalKey +
|
||||
//tagged_hash("tapTweak", internalKey || tapTweak).
|
||||
//
|
||||
//When doing a BIP 86 spend, this field can be an empty byte slice.
|
||||
//
|
||||
//When doing a normal key path spend, with the output key committing to an
|
||||
//actual script root, then this field should be: the tapscript root hash.
|
||||
TapTweak []byte `protobuf:"bytes,10,opt,name=tap_tweak,json=tapTweak,proto3" json:"tap_tweak,omitempty"`
|
||||
//
|
||||
//The full script required to properly redeem the output. This field will
|
||||
//only be populated if a p2tr, p2wsh or a p2sh output is being signed. In case
|
||||
//taproot_key_spend is set to true then this value must correspond to the
|
||||
//taproot root hash (in case of a tapscript output) or the tap hashed internal
|
||||
//public key (in case of a BIP-0086 output).
|
||||
//only be populated if a p2tr, p2wsh or a p2sh output is being signed. If a
|
||||
//taproot script path spend is being attempted, then this should be the raw
|
||||
//leaf script.
|
||||
WitnessScript []byte `protobuf:"bytes,4,opt,name=witness_script,json=witnessScript,proto3" json:"witness_script,omitempty"`
|
||||
//
|
||||
//A description of the output being spent. The value and script MUST be
|
||||
@@ -246,11 +319,11 @@ type SignDescriptor struct {
|
||||
//The target input within the transaction that should be signed.
|
||||
InputIndex int32 `protobuf:"varint,8,opt,name=input_index,json=inputIndex,proto3" json:"input_index,omitempty"`
|
||||
//
|
||||
//Indicates that this should produce a signature that can be used for the key
|
||||
//spend path of a taproot input. This requires the witness_script field to be
|
||||
//set to the taproot root hash (in case of a tapscript output) or the tap
|
||||
//hashed internal public key (in case of a BIP-0086 output).
|
||||
TaprootKeySpend bool `protobuf:"varint,9,opt,name=taproot_key_spend,json=taprootKeySpend,proto3" json:"taproot_key_spend,omitempty"`
|
||||
//The sign method specifies how the input should be signed. Depending on the
|
||||
//method, either the tap_tweak, witness_script or both need to be specified.
|
||||
//Defaults to SegWit v0 signing to be backward compatible with older RPC
|
||||
//clients.
|
||||
SignMethod SignMethod `protobuf:"varint,9,opt,name=sign_method,json=signMethod,proto3,enum=signrpc.SignMethod" json:"sign_method,omitempty"`
|
||||
}
|
||||
|
||||
func (x *SignDescriptor) Reset() {
|
||||
@@ -306,6 +379,13 @@ func (x *SignDescriptor) GetDoubleTweak() []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *SignDescriptor) GetTapTweak() []byte {
|
||||
if x != nil {
|
||||
return x.TapTweak
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *SignDescriptor) GetWitnessScript() []byte {
|
||||
if x != nil {
|
||||
return x.WitnessScript
|
||||
@@ -334,11 +414,11 @@ func (x *SignDescriptor) GetInputIndex() int32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *SignDescriptor) GetTaprootKeySpend() bool {
|
||||
func (x *SignDescriptor) GetSignMethod() SignMethod {
|
||||
if x != nil {
|
||||
return x.TaprootKeySpend
|
||||
return x.SignMethod
|
||||
}
|
||||
return false
|
||||
return SignMethod_SIGN_METHOD_WITNESS_V0
|
||||
}
|
||||
|
||||
type SignReq struct {
|
||||
@@ -1849,7 +1929,7 @@ var file_signrpc_signer_proto_rawDesc = []byte{
|
||||
0x54, 0x78, 0x4f, 0x75, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x70,
|
||||
0x6b, 0x5f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08,
|
||||
0x70, 0x6b, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x22, 0xbf, 0x02, 0x0a, 0x0e, 0x53, 0x69, 0x67,
|
||||
0x70, 0x6b, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x22, 0xe6, 0x02, 0x0a, 0x0e, 0x53, 0x69, 0x67,
|
||||
0x6e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x12, 0x31, 0x0a, 0x08, 0x6b,
|
||||
0x65, 0x79, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e,
|
||||
0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4b, 0x65, 0x79, 0x44, 0x65, 0x73, 0x63, 0x72,
|
||||
@@ -1858,236 +1938,248 @@ var file_signrpc_signer_proto_rawDesc = []byte{
|
||||
0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x54, 0x77, 0x65, 0x61,
|
||||
0x6b, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x5f, 0x74, 0x77, 0x65, 0x61,
|
||||
0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x54,
|
||||
0x77, 0x65, 0x61, 0x6b, 0x12, 0x25, 0x0a, 0x0e, 0x77, 0x69, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x5f,
|
||||
0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x77, 0x69,
|
||||
0x74, 0x6e, 0x65, 0x73, 0x73, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x12, 0x26, 0x0a, 0x06, 0x6f,
|
||||
0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x73, 0x69,
|
||||
0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x78, 0x4f, 0x75, 0x74, 0x52, 0x06, 0x6f, 0x75, 0x74,
|
||||
0x70, 0x75, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x69, 0x67, 0x68, 0x61, 0x73, 0x68, 0x18, 0x07,
|
||||
0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x73, 0x69, 0x67, 0x68, 0x61, 0x73, 0x68, 0x12, 0x1f, 0x0a,
|
||||
0x0b, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x08, 0x20, 0x01,
|
||||
0x28, 0x05, 0x52, 0x0a, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x2a,
|
||||
0x0a, 0x11, 0x74, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x70,
|
||||
0x65, 0x6e, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x74, 0x61, 0x70, 0x72, 0x6f,
|
||||
0x6f, 0x74, 0x4b, 0x65, 0x79, 0x53, 0x70, 0x65, 0x6e, 0x64, 0x22, 0x96, 0x01, 0x0a, 0x07, 0x53,
|
||||
0x69, 0x67, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x20, 0x0a, 0x0c, 0x72, 0x61, 0x77, 0x5f, 0x74, 0x78,
|
||||
0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x72, 0x61,
|
||||
0x77, 0x54, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x36, 0x0a, 0x0a, 0x73, 0x69, 0x67, 0x6e,
|
||||
0x5f, 0x64, 0x65, 0x73, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73,
|
||||
0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x44, 0x65, 0x73, 0x63, 0x72,
|
||||
0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x44, 0x65, 0x73, 0x63, 0x73,
|
||||
0x12, 0x31, 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x76, 0x5f, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73,
|
||||
0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63,
|
||||
0x2e, 0x54, 0x78, 0x4f, 0x75, 0x74, 0x52, 0x0b, 0x70, 0x72, 0x65, 0x76, 0x4f, 0x75, 0x74, 0x70,
|
||||
0x75, 0x74, 0x73, 0x22, 0x25, 0x0a, 0x08, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12,
|
||||
0x19, 0x0a, 0x08, 0x72, 0x61, 0x77, 0x5f, 0x73, 0x69, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
|
||||
0x0c, 0x52, 0x07, 0x72, 0x61, 0x77, 0x53, 0x69, 0x67, 0x73, 0x22, 0x46, 0x0a, 0x0b, 0x49, 0x6e,
|
||||
0x70, 0x75, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x77, 0x69, 0x74,
|
||||
0x6e, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x07, 0x77, 0x69, 0x74, 0x6e,
|
||||
0x65, 0x73, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x69, 0x67, 0x5f, 0x73, 0x63, 0x72, 0x69, 0x70,
|
||||
0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x53, 0x63, 0x72, 0x69,
|
||||
0x70, 0x74, 0x22, 0x4c, 0x0a, 0x0f, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70,
|
||||
0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x39, 0x0a, 0x0d, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x73,
|
||||
0x63, 0x72, 0x69, 0x70, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73,
|
||||
0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x63, 0x72, 0x69,
|
||||
0x70, 0x74, 0x52, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x73,
|
||||
0x22, 0x92, 0x01, 0x0a, 0x0e, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
|
||||
0x52, 0x65, 0x71, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
|
||||
0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x2c, 0x0a, 0x07, 0x6b, 0x65, 0x79, 0x5f, 0x6c, 0x6f, 0x63,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63,
|
||||
0x2e, 0x4b, 0x65, 0x79, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x06, 0x6b, 0x65, 0x79,
|
||||
0x4c, 0x6f, 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x5f, 0x68, 0x61,
|
||||
0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65,
|
||||
0x48, 0x61, 0x73, 0x68, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x5f,
|
||||
0x73, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x61,
|
||||
0x63, 0x74, 0x53, 0x69, 0x67, 0x22, 0x2f, 0x0a, 0x0f, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73,
|
||||
0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e,
|
||||
0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67,
|
||||
0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x5a, 0x0a, 0x10, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79,
|
||||
0x77, 0x65, 0x61, 0x6b, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x61, 0x70, 0x5f, 0x74, 0x77, 0x65, 0x61,
|
||||
0x6b, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x74, 0x61, 0x70, 0x54, 0x77, 0x65, 0x61,
|
||||
0x6b, 0x12, 0x25, 0x0a, 0x0e, 0x77, 0x69, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x63, 0x72,
|
||||
0x69, 0x70, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x77, 0x69, 0x74, 0x6e, 0x65,
|
||||
0x73, 0x73, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x12, 0x26, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70,
|
||||
0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72,
|
||||
0x70, 0x63, 0x2e, 0x54, 0x78, 0x4f, 0x75, 0x74, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74,
|
||||
0x12, 0x18, 0x0a, 0x07, 0x73, 0x69, 0x67, 0x68, 0x61, 0x73, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28,
|
||||
0x0d, 0x52, 0x07, 0x73, 0x69, 0x67, 0x68, 0x61, 0x73, 0x68, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e,
|
||||
0x70, 0x75, 0x74, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52,
|
||||
0x0a, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x34, 0x0a, 0x0b, 0x73,
|
||||
0x69, 0x67, 0x6e, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e,
|
||||
0x32, 0x13, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4d,
|
||||
0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x74, 0x68, 0x6f,
|
||||
0x64, 0x22, 0x96, 0x01, 0x0a, 0x07, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x20, 0x0a,
|
||||
0x0c, 0x72, 0x61, 0x77, 0x5f, 0x74, 0x78, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x0c, 0x52, 0x0a, 0x72, 0x61, 0x77, 0x54, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12,
|
||||
0x36, 0x0a, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x73, 0x18, 0x02, 0x20,
|
||||
0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x69,
|
||||
0x67, 0x6e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x09, 0x73, 0x69,
|
||||
0x67, 0x6e, 0x44, 0x65, 0x73, 0x63, 0x73, 0x12, 0x31, 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x76, 0x5f,
|
||||
0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e,
|
||||
0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x78, 0x4f, 0x75, 0x74, 0x52, 0x0b, 0x70,
|
||||
0x72, 0x65, 0x76, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x73, 0x22, 0x25, 0x0a, 0x08, 0x53, 0x69,
|
||||
0x67, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x61, 0x77, 0x5f, 0x73, 0x69,
|
||||
0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x07, 0x72, 0x61, 0x77, 0x53, 0x69, 0x67,
|
||||
0x73, 0x22, 0x46, 0x0a, 0x0b, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74,
|
||||
0x12, 0x18, 0x0a, 0x07, 0x77, 0x69, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
|
||||
0x0c, 0x52, 0x07, 0x77, 0x69, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x69,
|
||||
0x67, 0x5f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09,
|
||||
0x73, 0x69, 0x67, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x22, 0x4c, 0x0a, 0x0f, 0x49, 0x6e, 0x70,
|
||||
0x75, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x39, 0x0a, 0x0d,
|
||||
0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x73, 0x18, 0x01, 0x20,
|
||||
0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e,
|
||||
0x70, 0x75, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x52, 0x0c, 0x69, 0x6e, 0x70, 0x75, 0x74,
|
||||
0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x73, 0x22, 0x92, 0x01, 0x0a, 0x0e, 0x53, 0x69, 0x67, 0x6e,
|
||||
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73,
|
||||
0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x1c, 0x0a, 0x09,
|
||||
0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52,
|
||||
0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75,
|
||||
0x62, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6b,
|
||||
0x65, 0x79, 0x22, 0x29, 0x0a, 0x11, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73,
|
||||
0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x69, 0x64,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x22, 0xa2, 0x01,
|
||||
0x0a, 0x10, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x5f,
|
||||
0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x65, 0x70,
|
||||
0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a,
|
||||
0x07, 0x6b, 0x65, 0x79, 0x5f, 0x6c, 0x6f, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13,
|
||||
0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4b, 0x65, 0x79, 0x4c, 0x6f, 0x63, 0x61,
|
||||
0x74, 0x6f, 0x72, 0x42, 0x02, 0x18, 0x01, 0x52, 0x06, 0x6b, 0x65, 0x79, 0x4c, 0x6f, 0x63, 0x12,
|
||||
0x31, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x16, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4b, 0x65, 0x79, 0x44,
|
||||
0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x44, 0x65,
|
||||
0x73, 0x63, 0x22, 0x32, 0x0a, 0x11, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x68, 0x61, 0x72, 0x65,
|
||||
0x64, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x68, 0x61,
|
||||
0x72, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x22, 0x3d, 0x0a, 0x09, 0x54, 0x77, 0x65, 0x61, 0x6b, 0x44,
|
||||
0x65, 0x73, 0x63, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x77, 0x65, 0x61, 0x6b, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x0c, 0x52, 0x05, 0x74, 0x77, 0x65, 0x61, 0x6b, 0x12, 0x1a, 0x0a, 0x09, 0x69, 0x73, 0x5f,
|
||||
0x78, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73,
|
||||
0x58, 0x4f, 0x6e, 0x6c, 0x79, 0x22, 0x59, 0x0a, 0x10, 0x54, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74,
|
||||
0x54, 0x77, 0x65, 0x61, 0x6b, 0x44, 0x65, 0x73, 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x63, 0x72,
|
||||
0x69, 0x70, 0x74, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a,
|
||||
0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x6b, 0x65,
|
||||
0x79, 0x5f, 0x73, 0x70, 0x65, 0x6e, 0x64, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x08, 0x52, 0x0c, 0x6b, 0x65, 0x79, 0x53, 0x70, 0x65, 0x6e, 0x64, 0x4f, 0x6e, 0x6c, 0x79,
|
||||
0x22, 0xb4, 0x01, 0x0a, 0x18, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6f, 0x6d, 0x62, 0x69,
|
||||
0x6e, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2c, 0x0a,
|
||||
0x12, 0x61, 0x6c, 0x6c, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x5f, 0x70, 0x75, 0x62, 0x6b,
|
||||
0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x10, 0x61, 0x6c, 0x6c, 0x53, 0x69,
|
||||
0x67, 0x6e, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x73, 0x12, 0x2a, 0x0a, 0x06, 0x74,
|
||||
0x77, 0x65, 0x61, 0x6b, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x69,
|
||||
0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x77, 0x65, 0x61, 0x6b, 0x44, 0x65, 0x73, 0x63, 0x52,
|
||||
0x06, 0x74, 0x77, 0x65, 0x61, 0x6b, 0x73, 0x12, 0x3e, 0x0a, 0x0d, 0x74, 0x61, 0x70, 0x72, 0x6f,
|
||||
0x6f, 0x74, 0x5f, 0x74, 0x77, 0x65, 0x61, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19,
|
||||
0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74,
|
||||
0x54, 0x77, 0x65, 0x61, 0x6b, 0x44, 0x65, 0x73, 0x63, 0x52, 0x0c, 0x74, 0x61, 0x70, 0x72, 0x6f,
|
||||
0x6f, 0x74, 0x54, 0x77, 0x65, 0x61, 0x6b, 0x22, 0x70, 0x0a, 0x19, 0x4d, 0x75, 0x53, 0x69, 0x67,
|
||||
0x32, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x64,
|
||||
0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x62,
|
||||
0x69, 0x6e, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x14, 0x74, 0x61, 0x70, 0x72, 0x6f,
|
||||
0x6f, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x6b, 0x65, 0x79, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x12, 0x74, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x49, 0x6e,
|
||||
0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x4b, 0x65, 0x79, 0x22, 0x9b, 0x02, 0x0a, 0x14, 0x4d, 0x75,
|
||||
0x53, 0x69, 0x67, 0x32, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x12, 0x2c, 0x0a, 0x07, 0x6b, 0x65, 0x79, 0x5f, 0x6c, 0x6f, 0x63, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4b, 0x65,
|
||||
0x79, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x06, 0x6b, 0x65, 0x79, 0x4c, 0x6f, 0x63,
|
||||
0x12, 0x2c, 0x0a, 0x12, 0x61, 0x6c, 0x6c, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x5f, 0x70,
|
||||
0x75, 0x62, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x10, 0x61, 0x6c,
|
||||
0x6c, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x73, 0x12, 0x3b,
|
||||
0x0a, 0x1a, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x5f, 0x70,
|
||||
0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03,
|
||||
0x28, 0x0c, 0x52, 0x17, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x50,
|
||||
0x75, 0x62, 0x6c, 0x69, 0x63, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x06, 0x74,
|
||||
0x77, 0x65, 0x61, 0x6b, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x69,
|
||||
0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x77, 0x65, 0x61, 0x6b, 0x44, 0x65, 0x73, 0x63, 0x52,
|
||||
0x06, 0x74, 0x77, 0x65, 0x61, 0x6b, 0x73, 0x12, 0x3e, 0x0a, 0x0d, 0x74, 0x61, 0x70, 0x72, 0x6f,
|
||||
0x6f, 0x74, 0x5f, 0x74, 0x77, 0x65, 0x61, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19,
|
||||
0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74,
|
||||
0x54, 0x77, 0x65, 0x61, 0x6b, 0x44, 0x65, 0x73, 0x63, 0x52, 0x0c, 0x74, 0x61, 0x70, 0x72, 0x6f,
|
||||
0x6f, 0x74, 0x54, 0x77, 0x65, 0x61, 0x6b, 0x22, 0xe3, 0x01, 0x0a, 0x15, 0x4d, 0x75, 0x53, 0x69,
|
||||
0x67, 0x32, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64,
|
||||
0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x64,
|
||||
0x4b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x14, 0x74, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x69,
|
||||
0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x0c, 0x52, 0x12, 0x74, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e,
|
||||
0x61, 0x6c, 0x4b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x13, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70,
|
||||
0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01,
|
||||
0x28, 0x0c, 0x52, 0x11, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4e,
|
||||
0x6f, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x68, 0x61, 0x76, 0x65, 0x5f, 0x61, 0x6c,
|
||||
0x6c, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d,
|
||||
0x68, 0x61, 0x76, 0x65, 0x41, 0x6c, 0x6c, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x22, 0x79, 0x0a,
|
||||
0x1b, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4e,
|
||||
0x6f, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a,
|
||||
0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x2c, 0x0a, 0x07,
|
||||
0x6b, 0x65, 0x79, 0x5f, 0x6c, 0x6f, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e,
|
||||
0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4b, 0x65, 0x79, 0x4c, 0x6f, 0x63, 0x61, 0x74,
|
||||
0x6f, 0x72, 0x52, 0x06, 0x6b, 0x65, 0x79, 0x4c, 0x6f, 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x6f,
|
||||
0x75, 0x62, 0x6c, 0x65, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52,
|
||||
0x0a, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1f, 0x0a, 0x0b, 0x63,
|
||||
0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x5f, 0x73, 0x69, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08,
|
||||
0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x53, 0x69, 0x67, 0x22, 0x2f, 0x0a, 0x0f,
|
||||
0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x12,
|
||||
0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x5a, 0x0a,
|
||||
0x10, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65,
|
||||
0x71, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03,
|
||||
0x6d, 0x73, 0x67, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72,
|
||||
0x65, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x0c, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x22, 0x29, 0x0a, 0x11, 0x56, 0x65, 0x72,
|
||||
0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x12, 0x14,
|
||||
0x0a, 0x05, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x76,
|
||||
0x61, 0x6c, 0x69, 0x64, 0x22, 0xa2, 0x01, 0x0a, 0x10, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4b,
|
||||
0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x29, 0x0a, 0x10, 0x65, 0x70, 0x68,
|
||||
0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x5f, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x0c, 0x52, 0x0f, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x50, 0x75,
|
||||
0x62, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x07, 0x6b, 0x65, 0x79, 0x5f, 0x6c, 0x6f, 0x63, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e,
|
||||
0x4b, 0x65, 0x79, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x42, 0x02, 0x18, 0x01, 0x52, 0x06,
|
||||
0x6b, 0x65, 0x79, 0x4c, 0x6f, 0x63, 0x12, 0x31, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x64, 0x65,
|
||||
0x73, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72,
|
||||
0x70, 0x63, 0x2e, 0x4b, 0x65, 0x79, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72,
|
||||
0x52, 0x07, 0x6b, 0x65, 0x79, 0x44, 0x65, 0x73, 0x63, 0x22, 0x32, 0x0a, 0x11, 0x53, 0x68, 0x61,
|
||||
0x72, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d,
|
||||
0x0a, 0x0a, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x0c, 0x52, 0x09, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x22, 0x3d, 0x0a,
|
||||
0x09, 0x54, 0x77, 0x65, 0x61, 0x6b, 0x44, 0x65, 0x73, 0x63, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x77,
|
||||
0x65, 0x61, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x74, 0x77, 0x65, 0x61, 0x6b,
|
||||
0x12, 0x1a, 0x0a, 0x09, 0x69, 0x73, 0x5f, 0x78, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x58, 0x4f, 0x6e, 0x6c, 0x79, 0x22, 0x59, 0x0a, 0x10,
|
||||
0x54, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x54, 0x77, 0x65, 0x61, 0x6b, 0x44, 0x65, 0x73, 0x63,
|
||||
0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x52, 0x6f, 0x6f,
|
||||
0x74, 0x12, 0x24, 0x0a, 0x0e, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x70, 0x65, 0x6e, 0x64, 0x5f, 0x6f,
|
||||
0x6e, 0x6c, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x6b, 0x65, 0x79, 0x53, 0x70,
|
||||
0x65, 0x6e, 0x64, 0x4f, 0x6e, 0x6c, 0x79, 0x22, 0xb4, 0x01, 0x0a, 0x18, 0x4d, 0x75, 0x53, 0x69,
|
||||
0x67, 0x32, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x61, 0x6c, 0x6c, 0x5f, 0x73, 0x69, 0x67, 0x6e,
|
||||
0x65, 0x72, 0x5f, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c,
|
||||
0x52, 0x10, 0x61, 0x6c, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6b, 0x65,
|
||||
0x79, 0x73, 0x12, 0x2a, 0x0a, 0x06, 0x74, 0x77, 0x65, 0x61, 0x6b, 0x73, 0x18, 0x02, 0x20, 0x03,
|
||||
0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x77, 0x65,
|
||||
0x61, 0x6b, 0x44, 0x65, 0x73, 0x63, 0x52, 0x06, 0x74, 0x77, 0x65, 0x61, 0x6b, 0x73, 0x12, 0x3e,
|
||||
0x0a, 0x0d, 0x74, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x74, 0x77, 0x65, 0x61, 0x6b, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e,
|
||||
0x54, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x54, 0x77, 0x65, 0x61, 0x6b, 0x44, 0x65, 0x73, 0x63,
|
||||
0x52, 0x0c, 0x74, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x54, 0x77, 0x65, 0x61, 0x6b, 0x22, 0x70,
|
||||
0x0a, 0x19, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x4b,
|
||||
0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63,
|
||||
0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x0c, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x30,
|
||||
0x0a, 0x14, 0x74, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e,
|
||||
0x61, 0x6c, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x12, 0x74, 0x61,
|
||||
0x70, 0x72, 0x6f, 0x6f, 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x4b, 0x65, 0x79,
|
||||
0x22, 0x9b, 0x02, 0x0a, 0x14, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x53, 0x65, 0x73, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2c, 0x0a, 0x07, 0x6b, 0x65, 0x79,
|
||||
0x5f, 0x6c, 0x6f, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x69, 0x67,
|
||||
0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4b, 0x65, 0x79, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x52,
|
||||
0x06, 0x6b, 0x65, 0x79, 0x4c, 0x6f, 0x63, 0x12, 0x2c, 0x0a, 0x12, 0x61, 0x6c, 0x6c, 0x5f, 0x73,
|
||||
0x69, 0x67, 0x6e, 0x65, 0x72, 0x5f, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20,
|
||||
0x03, 0x28, 0x0c, 0x52, 0x10, 0x61, 0x6c, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x50, 0x75,
|
||||
0x62, 0x6b, 0x65, 0x79, 0x73, 0x12, 0x3b, 0x0a, 0x1a, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x73,
|
||||
0x69, 0x67, 0x6e, 0x65, 0x72, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6e, 0x6f, 0x6e,
|
||||
0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x17, 0x6f, 0x74, 0x68, 0x65, 0x72,
|
||||
0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4e, 0x6f, 0x6e, 0x63,
|
||||
0x65, 0x73, 0x12, 0x2a, 0x0a, 0x06, 0x74, 0x77, 0x65, 0x61, 0x6b, 0x73, 0x18, 0x04, 0x20, 0x03,
|
||||
0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x54, 0x77, 0x65,
|
||||
0x61, 0x6b, 0x44, 0x65, 0x73, 0x63, 0x52, 0x06, 0x74, 0x77, 0x65, 0x61, 0x6b, 0x73, 0x12, 0x3e,
|
||||
0x0a, 0x0d, 0x74, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x74, 0x77, 0x65, 0x61, 0x6b, 0x18,
|
||||
0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e,
|
||||
0x54, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x54, 0x77, 0x65, 0x61, 0x6b, 0x44, 0x65, 0x73, 0x63,
|
||||
0x52, 0x0c, 0x74, 0x61, 0x70, 0x72, 0x6f, 0x6f, 0x74, 0x54, 0x77, 0x65, 0x61, 0x6b, 0x22, 0xe3,
|
||||
0x01, 0x0a, 0x15, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x65,
|
||||
0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, 0x62, 0x69,
|
||||
0x6e, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63,
|
||||
0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x14, 0x74, 0x61,
|
||||
0x70, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x6b,
|
||||
0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x12, 0x74, 0x61, 0x70, 0x72, 0x6f, 0x6f,
|
||||
0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x4b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x13,
|
||||
0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6e, 0x6f, 0x6e,
|
||||
0x63, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
|
||||
0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0f,
|
||||
0x68, 0x61, 0x76, 0x65, 0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x18,
|
||||
0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x68, 0x61, 0x76, 0x65, 0x41, 0x6c, 0x6c, 0x4e, 0x6f,
|
||||
0x6e, 0x63, 0x65, 0x73, 0x22, 0x79, 0x0a, 0x1b, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x52, 0x65,
|
||||
0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69,
|
||||
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x49, 0x64, 0x12, 0x3b, 0x0a, 0x1a, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x67, 0x6e,
|
||||
0x65, 0x72, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73,
|
||||
0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x17, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x53, 0x69, 0x67,
|
||||
0x6e, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x22,
|
||||
0x46, 0x0a, 0x1c, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65,
|
||||
0x72, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x26, 0x0a, 0x0f, 0x68, 0x61, 0x76, 0x65, 0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0x6e, 0x6f, 0x6e, 0x63,
|
||||
0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x68, 0x61, 0x76, 0x65, 0x41, 0x6c,
|
||||
0x6c, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x22, 0x73, 0x0a, 0x11, 0x4d, 0x75, 0x53, 0x69, 0x67,
|
||||
0x32, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a,
|
||||
0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
|
||||
0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x3b, 0x0a, 0x1a, 0x6f,
|
||||
0x74, 0x68, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x5f, 0x70, 0x75, 0x62, 0x6c,
|
||||
0x69, 0x63, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52,
|
||||
0x17, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c,
|
||||
0x69, 0x63, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x22, 0x46, 0x0a, 0x1c, 0x4d, 0x75, 0x53, 0x69,
|
||||
0x67, 0x32, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x68, 0x61, 0x76, 0x65,
|
||||
0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x08, 0x52, 0x0d, 0x68, 0x61, 0x76, 0x65, 0x41, 0x6c, 0x6c, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73,
|
||||
0x22, 0x73, 0x0a, 0x11, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65,
|
||||
0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x6d,
|
||||
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x0c, 0x52, 0x0d, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x44, 0x69, 0x67, 0x65,
|
||||
0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6c, 0x65, 0x61, 0x6e, 0x75, 0x70, 0x18, 0x03, 0x20,
|
||||
0x01, 0x28, 0x08, 0x52, 0x07, 0x63, 0x6c, 0x65, 0x61, 0x6e, 0x75, 0x70, 0x22, 0x4c, 0x0a, 0x12,
|
||||
0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x12, 0x36, 0x0a, 0x17, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x72, 0x74,
|
||||
0x69, 0x61, 0x6c, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x0c, 0x52, 0x15, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61,
|
||||
0x6c, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x72, 0x0a, 0x17, 0x4d, 0x75,
|
||||
0x53, 0x69, 0x67, 0x32, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x53, 0x69, 0x67, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f,
|
||||
0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x6d, 0x65,
|
||||
0x73, 0x73, 0x61, 0x67, 0x65, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63,
|
||||
0x6c, 0x65, 0x61, 0x6e, 0x75, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, 0x6c,
|
||||
0x65, 0x61, 0x6e, 0x75, 0x70, 0x22, 0x4c, 0x0a, 0x12, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x53,
|
||||
0x69, 0x67, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x17, 0x6c,
|
||||
0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x73, 0x69, 0x67,
|
||||
0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x15, 0x6c, 0x6f,
|
||||
0x63, 0x61, 0x6c, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74,
|
||||
0x75, 0x72, 0x65, 0x22, 0x72, 0x0a, 0x17, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6f, 0x6d,
|
||||
0x62, 0x69, 0x6e, 0x65, 0x53, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d,
|
||||
0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x0c, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x38, 0x0a,
|
||||
0x18, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x73,
|
||||
0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52,
|
||||
0x16, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x53, 0x69, 0x67,
|
||||
0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x22, 0x73, 0x0a, 0x18, 0x4d, 0x75, 0x53, 0x69, 0x67,
|
||||
0x32, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x53, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x68, 0x61, 0x76, 0x65, 0x5f, 0x61, 0x6c, 0x6c, 0x5f,
|
||||
0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08,
|
||||
0x52, 0x11, 0x68, 0x61, 0x76, 0x65, 0x41, 0x6c, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75,
|
||||
0x72, 0x65, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x5f, 0x73, 0x69, 0x67,
|
||||
0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x66, 0x69,
|
||||
0x6e, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x35, 0x0a, 0x14,
|
||||
0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x75, 0x70, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f,
|
||||
0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x49, 0x64, 0x22, 0x17, 0x0a, 0x15, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6c, 0x65,
|
||||
0x61, 0x6e, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xdb, 0x06, 0x0a,
|
||||
0x06, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x12, 0x34, 0x0a, 0x0d, 0x53, 0x69, 0x67, 0x6e, 0x4f,
|
||||
0x75, 0x74, 0x70, 0x75, 0x74, 0x52, 0x61, 0x77, 0x12, 0x10, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72,
|
||||
0x70, 0x63, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x11, 0x2e, 0x73, 0x69, 0x67,
|
||||
0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x12, 0x40, 0x0a,
|
||||
0x12, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x63, 0x72,
|
||||
0x69, 0x70, 0x74, 0x12, 0x10, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x69,
|
||||
0x67, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x18, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e,
|
||||
0x49, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x52, 0x65, 0x73, 0x70, 0x12,
|
||||
0x40, 0x0a, 0x0b, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x17,
|
||||
0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73,
|
||||
0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x18, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70,
|
||||
0x63, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73,
|
||||
0x70, 0x12, 0x46, 0x0a, 0x0d, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61,
|
||||
0x67, 0x65, 0x12, 0x19, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x56, 0x65, 0x72,
|
||||
0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e,
|
||||
0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4d, 0x65,
|
||||
0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x12, 0x48, 0x0a, 0x0f, 0x44, 0x65, 0x72,
|
||||
0x69, 0x76, 0x65, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x19, 0x2e, 0x73,
|
||||
0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4b, 0x65, 0x79,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70,
|
||||
0x63, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x5a, 0x0a, 0x11, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6f, 0x6d,
|
||||
0x62, 0x69, 0x6e, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x21, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72,
|
||||
0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65,
|
||||
0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x73, 0x69,
|
||||
0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6f, 0x6d, 0x62,
|
||||
0x69, 0x6e, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x54, 0x0a, 0x13, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53,
|
||||
0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63,
|
||||
0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e,
|
||||
0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, 0x14, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x52,
|
||||
0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x24, 0x2e,
|
||||
0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x52, 0x65,
|
||||
0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75,
|
||||
0x6f, 0x6e, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x18, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x70, 0x61,
|
||||
0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73,
|
||||
0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x16, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x50, 0x61, 0x72,
|
||||
0x74, 0x69, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x22, 0x73,
|
||||
0x0a, 0x18, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x53,
|
||||
0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x68, 0x61,
|
||||
0x76, 0x65, 0x5f, 0x61, 0x6c, 0x6c, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65,
|
||||
0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x68, 0x61, 0x76, 0x65, 0x41, 0x6c, 0x6c,
|
||||
0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x66, 0x69,
|
||||
0x6e, 0x61, 0x6c, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x0c, 0x52, 0x0e, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74,
|
||||
0x75, 0x72, 0x65, 0x22, 0x35, 0x0a, 0x14, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6c, 0x65,
|
||||
0x61, 0x6e, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73,
|
||||
0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,
|
||||
0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x17, 0x0a, 0x15, 0x4d, 0x75,
|
||||
0x53, 0x69, 0x67, 0x32, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x2a, 0x9c, 0x01, 0x0a, 0x0a, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x74, 0x68,
|
||||
0x6f, 0x64, 0x12, 0x1a, 0x0a, 0x16, 0x53, 0x49, 0x47, 0x4e, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f,
|
||||
0x44, 0x5f, 0x57, 0x49, 0x54, 0x4e, 0x45, 0x53, 0x53, 0x5f, 0x56, 0x30, 0x10, 0x00, 0x12, 0x29,
|
||||
0x0a, 0x25, 0x53, 0x49, 0x47, 0x4e, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x54, 0x41,
|
||||
0x50, 0x52, 0x4f, 0x4f, 0x54, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x53, 0x50, 0x45, 0x4e, 0x44, 0x5f,
|
||||
0x42, 0x49, 0x50, 0x30, 0x30, 0x38, 0x36, 0x10, 0x01, 0x12, 0x21, 0x0a, 0x1d, 0x53, 0x49, 0x47,
|
||||
0x4e, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x54, 0x41, 0x50, 0x52, 0x4f, 0x4f, 0x54,
|
||||
0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x53, 0x50, 0x45, 0x4e, 0x44, 0x10, 0x02, 0x12, 0x24, 0x0a, 0x20,
|
||||
0x53, 0x49, 0x47, 0x4e, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x54, 0x41, 0x50, 0x52,
|
||||
0x4f, 0x4f, 0x54, 0x5f, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x5f, 0x53, 0x50, 0x45, 0x4e, 0x44,
|
||||
0x10, 0x03, 0x32, 0xdb, 0x06, 0x0a, 0x06, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x12, 0x34, 0x0a,
|
||||
0x0d, 0x53, 0x69, 0x67, 0x6e, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x52, 0x61, 0x77, 0x12, 0x10,
|
||||
0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x71,
|
||||
0x1a, 0x11, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x52,
|
||||
0x65, 0x73, 0x70, 0x12, 0x40, 0x0a, 0x12, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x49, 0x6e,
|
||||
0x70, 0x75, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x12, 0x10, 0x2e, 0x73, 0x69, 0x67, 0x6e,
|
||||
0x72, 0x70, 0x63, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x71, 0x1a, 0x18, 0x2e, 0x73, 0x69,
|
||||
0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70,
|
||||
0x74, 0x52, 0x65, 0x73, 0x70, 0x12, 0x40, 0x0a, 0x0b, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73,
|
||||
0x73, 0x61, 0x67, 0x65, 0x12, 0x17, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53,
|
||||
0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x1a, 0x18, 0x2e,
|
||||
0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x65, 0x73, 0x73,
|
||||
0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x12, 0x46, 0x0a, 0x0d, 0x56, 0x65, 0x72, 0x69, 0x66,
|
||||
0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x19, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72,
|
||||
0x70, 0x63, 0x2e, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
|
||||
0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x56, 0x65,
|
||||
0x72, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x12,
|
||||
0x48, 0x0a, 0x0f, 0x44, 0x65, 0x72, 0x69, 0x76, 0x65, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4b,
|
||||
0x65, 0x79, 0x12, 0x19, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x68, 0x61,
|
||||
0x72, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e,
|
||||
0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x4b, 0x65,
|
||||
0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5a, 0x0a, 0x11, 0x4d, 0x75, 0x53,
|
||||
0x69, 0x67, 0x32, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x21,
|
||||
0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43,
|
||||
0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x22, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69,
|
||||
0x67, 0x32, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x13, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43,
|
||||
0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x2e, 0x73,
|
||||
0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x53, 0x65, 0x73,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x69,
|
||||
0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x53, 0x65, 0x73, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, 0x14, 0x4d,
|
||||
0x75, 0x53, 0x69, 0x67, 0x32, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x6f, 0x6e,
|
||||
0x63, 0x65, 0x73, 0x12, 0x24, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75,
|
||||
0x53, 0x69, 0x67, 0x32, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x6f, 0x6e, 0x63,
|
||||
0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0a, 0x4d, 0x75,
|
||||
0x53, 0x69, 0x67, 0x32, 0x53, 0x69, 0x67, 0x6e, 0x12, 0x1a, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72,
|
||||
0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d,
|
||||
0x75, 0x53, 0x69, 0x67, 0x32, 0x53, 0x69, 0x67, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x12, 0x57, 0x0a, 0x10, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6f, 0x6d, 0x62, 0x69,
|
||||
0x6e, 0x65, 0x53, 0x69, 0x67, 0x12, 0x20, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e,
|
||||
0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x53, 0x69, 0x67,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70,
|
||||
0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x53,
|
||||
0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x0d, 0x4d, 0x75,
|
||||
0x53, 0x69, 0x67, 0x32, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x75, 0x70, 0x12, 0x1d, 0x2e, 0x73, 0x69,
|
||||
0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6c, 0x65, 0x61,
|
||||
0x6e, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x69, 0x67,
|
||||
0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6c, 0x65, 0x61, 0x6e,
|
||||
0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x2f, 0x5a, 0x2d, 0x67, 0x69,
|
||||
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69,
|
||||
0x6e, 0x67, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6e, 0x64, 0x2f, 0x6c, 0x6e,
|
||||
0x72, 0x70, 0x63, 0x2f, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x33,
|
||||
0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x73, 0x69, 0x67, 0x6e,
|
||||
0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74,
|
||||
0x65, 0x72, 0x4e, 0x6f, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x12, 0x45, 0x0a, 0x0a, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x53, 0x69, 0x67, 0x6e, 0x12, 0x1a,
|
||||
0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x53,
|
||||
0x69, 0x67, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x73, 0x69, 0x67,
|
||||
0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x53, 0x69, 0x67, 0x6e, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x57, 0x0a, 0x10, 0x4d, 0x75, 0x53, 0x69, 0x67,
|
||||
0x32, 0x43, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x65, 0x53, 0x69, 0x67, 0x12, 0x20, 0x2e, 0x73, 0x69,
|
||||
0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6f, 0x6d, 0x62,
|
||||
0x69, 0x6e, 0x65, 0x53, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e,
|
||||
0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6f,
|
||||
0x6d, 0x62, 0x69, 0x6e, 0x65, 0x53, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x12, 0x4e, 0x0a, 0x0d, 0x4d, 0x75, 0x53, 0x69, 0x67, 0x32, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x75,
|
||||
0x70, 0x12, 0x1d, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69,
|
||||
0x67, 0x32, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x1e, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x75, 0x53, 0x69, 0x67,
|
||||
0x32, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x42, 0x2f, 0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c,
|
||||
0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f,
|
||||
0x6c, 0x6e, 0x64, 0x2f, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2f, 0x73, 0x69, 0x67, 0x6e, 0x72, 0x70,
|
||||
0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -2102,79 +2194,82 @@ func file_signrpc_signer_proto_rawDescGZIP() []byte {
|
||||
return file_signrpc_signer_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_signrpc_signer_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||
var file_signrpc_signer_proto_msgTypes = make([]protoimpl.MessageInfo, 28)
|
||||
var file_signrpc_signer_proto_goTypes = []interface{}{
|
||||
(*KeyLocator)(nil), // 0: signrpc.KeyLocator
|
||||
(*KeyDescriptor)(nil), // 1: signrpc.KeyDescriptor
|
||||
(*TxOut)(nil), // 2: signrpc.TxOut
|
||||
(*SignDescriptor)(nil), // 3: signrpc.SignDescriptor
|
||||
(*SignReq)(nil), // 4: signrpc.SignReq
|
||||
(*SignResp)(nil), // 5: signrpc.SignResp
|
||||
(*InputScript)(nil), // 6: signrpc.InputScript
|
||||
(*InputScriptResp)(nil), // 7: signrpc.InputScriptResp
|
||||
(*SignMessageReq)(nil), // 8: signrpc.SignMessageReq
|
||||
(*SignMessageResp)(nil), // 9: signrpc.SignMessageResp
|
||||
(*VerifyMessageReq)(nil), // 10: signrpc.VerifyMessageReq
|
||||
(*VerifyMessageResp)(nil), // 11: signrpc.VerifyMessageResp
|
||||
(*SharedKeyRequest)(nil), // 12: signrpc.SharedKeyRequest
|
||||
(*SharedKeyResponse)(nil), // 13: signrpc.SharedKeyResponse
|
||||
(*TweakDesc)(nil), // 14: signrpc.TweakDesc
|
||||
(*TaprootTweakDesc)(nil), // 15: signrpc.TaprootTweakDesc
|
||||
(*MuSig2CombineKeysRequest)(nil), // 16: signrpc.MuSig2CombineKeysRequest
|
||||
(*MuSig2CombineKeysResponse)(nil), // 17: signrpc.MuSig2CombineKeysResponse
|
||||
(*MuSig2SessionRequest)(nil), // 18: signrpc.MuSig2SessionRequest
|
||||
(*MuSig2SessionResponse)(nil), // 19: signrpc.MuSig2SessionResponse
|
||||
(*MuSig2RegisterNoncesRequest)(nil), // 20: signrpc.MuSig2RegisterNoncesRequest
|
||||
(*MuSig2RegisterNoncesResponse)(nil), // 21: signrpc.MuSig2RegisterNoncesResponse
|
||||
(*MuSig2SignRequest)(nil), // 22: signrpc.MuSig2SignRequest
|
||||
(*MuSig2SignResponse)(nil), // 23: signrpc.MuSig2SignResponse
|
||||
(*MuSig2CombineSigRequest)(nil), // 24: signrpc.MuSig2CombineSigRequest
|
||||
(*MuSig2CombineSigResponse)(nil), // 25: signrpc.MuSig2CombineSigResponse
|
||||
(*MuSig2CleanupRequest)(nil), // 26: signrpc.MuSig2CleanupRequest
|
||||
(*MuSig2CleanupResponse)(nil), // 27: signrpc.MuSig2CleanupResponse
|
||||
(SignMethod)(0), // 0: signrpc.SignMethod
|
||||
(*KeyLocator)(nil), // 1: signrpc.KeyLocator
|
||||
(*KeyDescriptor)(nil), // 2: signrpc.KeyDescriptor
|
||||
(*TxOut)(nil), // 3: signrpc.TxOut
|
||||
(*SignDescriptor)(nil), // 4: signrpc.SignDescriptor
|
||||
(*SignReq)(nil), // 5: signrpc.SignReq
|
||||
(*SignResp)(nil), // 6: signrpc.SignResp
|
||||
(*InputScript)(nil), // 7: signrpc.InputScript
|
||||
(*InputScriptResp)(nil), // 8: signrpc.InputScriptResp
|
||||
(*SignMessageReq)(nil), // 9: signrpc.SignMessageReq
|
||||
(*SignMessageResp)(nil), // 10: signrpc.SignMessageResp
|
||||
(*VerifyMessageReq)(nil), // 11: signrpc.VerifyMessageReq
|
||||
(*VerifyMessageResp)(nil), // 12: signrpc.VerifyMessageResp
|
||||
(*SharedKeyRequest)(nil), // 13: signrpc.SharedKeyRequest
|
||||
(*SharedKeyResponse)(nil), // 14: signrpc.SharedKeyResponse
|
||||
(*TweakDesc)(nil), // 15: signrpc.TweakDesc
|
||||
(*TaprootTweakDesc)(nil), // 16: signrpc.TaprootTweakDesc
|
||||
(*MuSig2CombineKeysRequest)(nil), // 17: signrpc.MuSig2CombineKeysRequest
|
||||
(*MuSig2CombineKeysResponse)(nil), // 18: signrpc.MuSig2CombineKeysResponse
|
||||
(*MuSig2SessionRequest)(nil), // 19: signrpc.MuSig2SessionRequest
|
||||
(*MuSig2SessionResponse)(nil), // 20: signrpc.MuSig2SessionResponse
|
||||
(*MuSig2RegisterNoncesRequest)(nil), // 21: signrpc.MuSig2RegisterNoncesRequest
|
||||
(*MuSig2RegisterNoncesResponse)(nil), // 22: signrpc.MuSig2RegisterNoncesResponse
|
||||
(*MuSig2SignRequest)(nil), // 23: signrpc.MuSig2SignRequest
|
||||
(*MuSig2SignResponse)(nil), // 24: signrpc.MuSig2SignResponse
|
||||
(*MuSig2CombineSigRequest)(nil), // 25: signrpc.MuSig2CombineSigRequest
|
||||
(*MuSig2CombineSigResponse)(nil), // 26: signrpc.MuSig2CombineSigResponse
|
||||
(*MuSig2CleanupRequest)(nil), // 27: signrpc.MuSig2CleanupRequest
|
||||
(*MuSig2CleanupResponse)(nil), // 28: signrpc.MuSig2CleanupResponse
|
||||
}
|
||||
var file_signrpc_signer_proto_depIdxs = []int32{
|
||||
0, // 0: signrpc.KeyDescriptor.key_loc:type_name -> signrpc.KeyLocator
|
||||
1, // 1: signrpc.SignDescriptor.key_desc:type_name -> signrpc.KeyDescriptor
|
||||
2, // 2: signrpc.SignDescriptor.output:type_name -> signrpc.TxOut
|
||||
3, // 3: signrpc.SignReq.sign_descs:type_name -> signrpc.SignDescriptor
|
||||
2, // 4: signrpc.SignReq.prev_outputs:type_name -> signrpc.TxOut
|
||||
6, // 5: signrpc.InputScriptResp.input_scripts:type_name -> signrpc.InputScript
|
||||
0, // 6: signrpc.SignMessageReq.key_loc:type_name -> signrpc.KeyLocator
|
||||
0, // 7: signrpc.SharedKeyRequest.key_loc:type_name -> signrpc.KeyLocator
|
||||
1, // 8: signrpc.SharedKeyRequest.key_desc:type_name -> signrpc.KeyDescriptor
|
||||
14, // 9: signrpc.MuSig2CombineKeysRequest.tweaks:type_name -> signrpc.TweakDesc
|
||||
15, // 10: signrpc.MuSig2CombineKeysRequest.taproot_tweak:type_name -> signrpc.TaprootTweakDesc
|
||||
0, // 11: signrpc.MuSig2SessionRequest.key_loc:type_name -> signrpc.KeyLocator
|
||||
14, // 12: signrpc.MuSig2SessionRequest.tweaks:type_name -> signrpc.TweakDesc
|
||||
15, // 13: signrpc.MuSig2SessionRequest.taproot_tweak:type_name -> signrpc.TaprootTweakDesc
|
||||
4, // 14: signrpc.Signer.SignOutputRaw:input_type -> signrpc.SignReq
|
||||
4, // 15: signrpc.Signer.ComputeInputScript:input_type -> signrpc.SignReq
|
||||
8, // 16: signrpc.Signer.SignMessage:input_type -> signrpc.SignMessageReq
|
||||
10, // 17: signrpc.Signer.VerifyMessage:input_type -> signrpc.VerifyMessageReq
|
||||
12, // 18: signrpc.Signer.DeriveSharedKey:input_type -> signrpc.SharedKeyRequest
|
||||
16, // 19: signrpc.Signer.MuSig2CombineKeys:input_type -> signrpc.MuSig2CombineKeysRequest
|
||||
18, // 20: signrpc.Signer.MuSig2CreateSession:input_type -> signrpc.MuSig2SessionRequest
|
||||
20, // 21: signrpc.Signer.MuSig2RegisterNonces:input_type -> signrpc.MuSig2RegisterNoncesRequest
|
||||
22, // 22: signrpc.Signer.MuSig2Sign:input_type -> signrpc.MuSig2SignRequest
|
||||
24, // 23: signrpc.Signer.MuSig2CombineSig:input_type -> signrpc.MuSig2CombineSigRequest
|
||||
26, // 24: signrpc.Signer.MuSig2Cleanup:input_type -> signrpc.MuSig2CleanupRequest
|
||||
5, // 25: signrpc.Signer.SignOutputRaw:output_type -> signrpc.SignResp
|
||||
7, // 26: signrpc.Signer.ComputeInputScript:output_type -> signrpc.InputScriptResp
|
||||
9, // 27: signrpc.Signer.SignMessage:output_type -> signrpc.SignMessageResp
|
||||
11, // 28: signrpc.Signer.VerifyMessage:output_type -> signrpc.VerifyMessageResp
|
||||
13, // 29: signrpc.Signer.DeriveSharedKey:output_type -> signrpc.SharedKeyResponse
|
||||
17, // 30: signrpc.Signer.MuSig2CombineKeys:output_type -> signrpc.MuSig2CombineKeysResponse
|
||||
19, // 31: signrpc.Signer.MuSig2CreateSession:output_type -> signrpc.MuSig2SessionResponse
|
||||
21, // 32: signrpc.Signer.MuSig2RegisterNonces:output_type -> signrpc.MuSig2RegisterNoncesResponse
|
||||
23, // 33: signrpc.Signer.MuSig2Sign:output_type -> signrpc.MuSig2SignResponse
|
||||
25, // 34: signrpc.Signer.MuSig2CombineSig:output_type -> signrpc.MuSig2CombineSigResponse
|
||||
27, // 35: signrpc.Signer.MuSig2Cleanup:output_type -> signrpc.MuSig2CleanupResponse
|
||||
25, // [25:36] is the sub-list for method output_type
|
||||
14, // [14:25] is the sub-list for method input_type
|
||||
14, // [14:14] is the sub-list for extension type_name
|
||||
14, // [14:14] is the sub-list for extension extendee
|
||||
0, // [0:14] is the sub-list for field type_name
|
||||
1, // 0: signrpc.KeyDescriptor.key_loc:type_name -> signrpc.KeyLocator
|
||||
2, // 1: signrpc.SignDescriptor.key_desc:type_name -> signrpc.KeyDescriptor
|
||||
3, // 2: signrpc.SignDescriptor.output:type_name -> signrpc.TxOut
|
||||
0, // 3: signrpc.SignDescriptor.sign_method:type_name -> signrpc.SignMethod
|
||||
4, // 4: signrpc.SignReq.sign_descs:type_name -> signrpc.SignDescriptor
|
||||
3, // 5: signrpc.SignReq.prev_outputs:type_name -> signrpc.TxOut
|
||||
7, // 6: signrpc.InputScriptResp.input_scripts:type_name -> signrpc.InputScript
|
||||
1, // 7: signrpc.SignMessageReq.key_loc:type_name -> signrpc.KeyLocator
|
||||
1, // 8: signrpc.SharedKeyRequest.key_loc:type_name -> signrpc.KeyLocator
|
||||
2, // 9: signrpc.SharedKeyRequest.key_desc:type_name -> signrpc.KeyDescriptor
|
||||
15, // 10: signrpc.MuSig2CombineKeysRequest.tweaks:type_name -> signrpc.TweakDesc
|
||||
16, // 11: signrpc.MuSig2CombineKeysRequest.taproot_tweak:type_name -> signrpc.TaprootTweakDesc
|
||||
1, // 12: signrpc.MuSig2SessionRequest.key_loc:type_name -> signrpc.KeyLocator
|
||||
15, // 13: signrpc.MuSig2SessionRequest.tweaks:type_name -> signrpc.TweakDesc
|
||||
16, // 14: signrpc.MuSig2SessionRequest.taproot_tweak:type_name -> signrpc.TaprootTweakDesc
|
||||
5, // 15: signrpc.Signer.SignOutputRaw:input_type -> signrpc.SignReq
|
||||
5, // 16: signrpc.Signer.ComputeInputScript:input_type -> signrpc.SignReq
|
||||
9, // 17: signrpc.Signer.SignMessage:input_type -> signrpc.SignMessageReq
|
||||
11, // 18: signrpc.Signer.VerifyMessage:input_type -> signrpc.VerifyMessageReq
|
||||
13, // 19: signrpc.Signer.DeriveSharedKey:input_type -> signrpc.SharedKeyRequest
|
||||
17, // 20: signrpc.Signer.MuSig2CombineKeys:input_type -> signrpc.MuSig2CombineKeysRequest
|
||||
19, // 21: signrpc.Signer.MuSig2CreateSession:input_type -> signrpc.MuSig2SessionRequest
|
||||
21, // 22: signrpc.Signer.MuSig2RegisterNonces:input_type -> signrpc.MuSig2RegisterNoncesRequest
|
||||
23, // 23: signrpc.Signer.MuSig2Sign:input_type -> signrpc.MuSig2SignRequest
|
||||
25, // 24: signrpc.Signer.MuSig2CombineSig:input_type -> signrpc.MuSig2CombineSigRequest
|
||||
27, // 25: signrpc.Signer.MuSig2Cleanup:input_type -> signrpc.MuSig2CleanupRequest
|
||||
6, // 26: signrpc.Signer.SignOutputRaw:output_type -> signrpc.SignResp
|
||||
8, // 27: signrpc.Signer.ComputeInputScript:output_type -> signrpc.InputScriptResp
|
||||
10, // 28: signrpc.Signer.SignMessage:output_type -> signrpc.SignMessageResp
|
||||
12, // 29: signrpc.Signer.VerifyMessage:output_type -> signrpc.VerifyMessageResp
|
||||
14, // 30: signrpc.Signer.DeriveSharedKey:output_type -> signrpc.SharedKeyResponse
|
||||
18, // 31: signrpc.Signer.MuSig2CombineKeys:output_type -> signrpc.MuSig2CombineKeysResponse
|
||||
20, // 32: signrpc.Signer.MuSig2CreateSession:output_type -> signrpc.MuSig2SessionResponse
|
||||
22, // 33: signrpc.Signer.MuSig2RegisterNonces:output_type -> signrpc.MuSig2RegisterNoncesResponse
|
||||
24, // 34: signrpc.Signer.MuSig2Sign:output_type -> signrpc.MuSig2SignResponse
|
||||
26, // 35: signrpc.Signer.MuSig2CombineSig:output_type -> signrpc.MuSig2CombineSigResponse
|
||||
28, // 36: signrpc.Signer.MuSig2Cleanup:output_type -> signrpc.MuSig2CleanupResponse
|
||||
26, // [26:37] is the sub-list for method output_type
|
||||
15, // [15:26] is the sub-list for method input_type
|
||||
15, // [15:15] is the sub-list for extension type_name
|
||||
15, // [15:15] is the sub-list for extension extendee
|
||||
0, // [0:15] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_signrpc_signer_proto_init() }
|
||||
@@ -2525,13 +2620,14 @@ func file_signrpc_signer_proto_init() {
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_signrpc_signer_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumEnums: 1,
|
||||
NumMessages: 28,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_signrpc_signer_proto_goTypes,
|
||||
DependencyIndexes: file_signrpc_signer_proto_depIdxs,
|
||||
EnumInfos: file_signrpc_signer_proto_enumTypes,
|
||||
MessageInfos: file_signrpc_signer_proto_msgTypes,
|
||||
}.Build()
|
||||
File_signrpc_signer_proto = out.File
|
||||
|
||||
@@ -175,6 +175,32 @@ message TxOut {
|
||||
bytes pk_script = 2;
|
||||
}
|
||||
|
||||
enum SignMethod {
|
||||
/*
|
||||
Specifies that a SegWit v0 (p2wkh, np2wkh, p2wsh) input script should be
|
||||
signed.
|
||||
*/
|
||||
SIGN_METHOD_WITNESS_V0 = 0;
|
||||
|
||||
/*
|
||||
Specifies that a SegWit v1 (p2tr) input should be signed by using the
|
||||
BIP0086 method (commit to internal key only).
|
||||
*/
|
||||
SIGN_METHOD_TAPROOT_KEY_SPEND_BIP0086 = 1;
|
||||
|
||||
/*
|
||||
Specifies that a SegWit v1 (p2tr) input should be signed by using a given
|
||||
taproot hash to commit to in addition to the internal key.
|
||||
*/
|
||||
SIGN_METHOD_TAPROOT_KEY_SPEND = 2;
|
||||
|
||||
/*
|
||||
Specifies that a SegWit v1 (p2tr) input should be spent using the script
|
||||
path and that a specific leaf script should be signed for.
|
||||
*/
|
||||
SIGN_METHOD_TAPROOT_SCRIPT_SPEND = 3;
|
||||
}
|
||||
|
||||
message SignDescriptor {
|
||||
/*
|
||||
A descriptor that precisely describes *which* key to use for signing. This
|
||||
@@ -209,12 +235,23 @@ message SignDescriptor {
|
||||
*/
|
||||
bytes double_tweak = 3;
|
||||
|
||||
/*
|
||||
The 32 byte input to the taproot tweak derivation that is used to derive
|
||||
the output key from an internal key: outputKey = internalKey +
|
||||
tagged_hash("tapTweak", internalKey || tapTweak).
|
||||
|
||||
When doing a BIP 86 spend, this field can be an empty byte slice.
|
||||
|
||||
When doing a normal key path spend, with the output key committing to an
|
||||
actual script root, then this field should be: the tapscript root hash.
|
||||
*/
|
||||
bytes tap_tweak = 10;
|
||||
|
||||
/*
|
||||
The full script required to properly redeem the output. This field will
|
||||
only be populated if a p2tr, p2wsh or a p2sh output is being signed. In case
|
||||
taproot_key_spend is set to true then this value must correspond to the
|
||||
taproot root hash (in case of a tapscript output) or the tap hashed internal
|
||||
public key (in case of a BIP-0086 output).
|
||||
only be populated if a p2tr, p2wsh or a p2sh output is being signed. If a
|
||||
taproot script path spend is being attempted, then this should be the raw
|
||||
leaf script.
|
||||
*/
|
||||
bytes witness_script = 4;
|
||||
|
||||
@@ -236,12 +273,12 @@ message SignDescriptor {
|
||||
int32 input_index = 8;
|
||||
|
||||
/*
|
||||
Indicates that this should produce a signature that can be used for the key
|
||||
spend path of a taproot input. This requires the witness_script field to be
|
||||
set to the taproot root hash (in case of a tapscript output) or the tap
|
||||
hashed internal public key (in case of a BIP-0086 output).
|
||||
The sign method specifies how the input should be signed. Depending on the
|
||||
method, either the tap_tweak, witness_script or both need to be specified.
|
||||
Defaults to SegWit v0 signing to be backward compatible with older RPC
|
||||
clients.
|
||||
*/
|
||||
bool taproot_key_spend = 9;
|
||||
SignMethod sign_method = 9;
|
||||
}
|
||||
|
||||
message SignReq {
|
||||
|
||||
@@ -731,10 +731,15 @@
|
||||
"format": "byte",
|
||||
"description": "A private key that will be used in combination with its corresponding\nprivate key to derive the private key that is to be used to sign the target\ninput. Within the Lightning protocol, this value is typically the\ncommitment secret from a previously revoked commitment transaction. This\nvalue is in combination with two hash values, and the original private key\nto derive the private key to be used when signing.\n\nk = (privKey*sha256(pubKey || tweakPub) +\ntweakPriv*sha256(tweakPub || pubKey)) mod N"
|
||||
},
|
||||
"tap_tweak": {
|
||||
"type": "string",
|
||||
"format": "byte",
|
||||
"description": "The 32 byte input to the taproot tweak derivation that is used to derive\nthe output key from an internal key: outputKey = internalKey +\ntagged_hash(\"tapTweak\", internalKey || tapTweak).\n\nWhen doing a BIP 86 spend, this field can be an empty byte slice.\n\nWhen doing a normal key path spend, with the output key committing to an\nactual script root, then this field should be: the tapscript root hash."
|
||||
},
|
||||
"witness_script": {
|
||||
"type": "string",
|
||||
"format": "byte",
|
||||
"description": "The full script required to properly redeem the output. This field will\nonly be populated if a p2tr, p2wsh or a p2sh output is being signed. In case\ntaproot_key_spend is set to true then this value must correspond to the\ntaproot root hash (in case of a tapscript output) or the tap hashed internal\npublic key (in case of a BIP-0086 output)."
|
||||
"description": "The full script required to properly redeem the output. This field will\nonly be populated if a p2tr, p2wsh or a p2sh output is being signed. If a\ntaproot script path spend is being attempted, then this should be the raw\nleaf script."
|
||||
},
|
||||
"output": {
|
||||
"$ref": "#/definitions/signrpcTxOut",
|
||||
@@ -750,9 +755,9 @@
|
||||
"format": "int32",
|
||||
"description": "The target input within the transaction that should be signed."
|
||||
},
|
||||
"taproot_key_spend": {
|
||||
"type": "boolean",
|
||||
"description": "Indicates that this should produce a signature that can be used for the key\nspend path of a taproot input. This requires the witness_script field to be\nset to the taproot root hash (in case of a tapscript output) or the tap\nhashed internal public key (in case of a BIP-0086 output)."
|
||||
"sign_method": {
|
||||
"$ref": "#/definitions/signrpcSignMethod",
|
||||
"description": "The sign method specifies how the input should be signed. Depending on the\nmethod, either the tap_tweak, witness_script or both need to be specified.\nDefaults to SegWit v0 signing to be backward compatible with older RPC\nclients."
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -788,6 +793,17 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"signrpcSignMethod": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"SIGN_METHOD_WITNESS_V0",
|
||||
"SIGN_METHOD_TAPROOT_KEY_SPEND_BIP0086",
|
||||
"SIGN_METHOD_TAPROOT_KEY_SPEND",
|
||||
"SIGN_METHOD_TAPROOT_SCRIPT_SPEND"
|
||||
],
|
||||
"default": "SIGN_METHOD_WITNESS_V0",
|
||||
"description": " - SIGN_METHOD_WITNESS_V0: Specifies that a SegWit v0 (p2wkh, np2wkh, p2wsh) input script should be\nsigned.\n - SIGN_METHOD_TAPROOT_KEY_SPEND_BIP0086: Specifies that a SegWit v1 (p2tr) input should be signed by using the\nBIP0086 method (commit to internal key only).\n - SIGN_METHOD_TAPROOT_KEY_SPEND: Specifies that a SegWit v1 (p2tr) input should be signed by using a given\ntaproot hash to commit to in addition to the internal key.\n - SIGN_METHOD_TAPROOT_SCRIPT_SPEND: Specifies that a SegWit v1 (p2tr) input should be spent using the script\npath and that a specific leaf script should be signed for."
|
||||
},
|
||||
"signrpcSignReq": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
@@ -361,16 +361,56 @@ func (s *Server) SignOutputRaw(_ context.Context, in *SignReq) (*SignResp,
|
||||
}
|
||||
}
|
||||
|
||||
// If a witness script isn't passed, then we can't proceed, as
|
||||
// in the p2wsh case, we can't properly generate the sighash.
|
||||
// A P2WKH doesn't need a witness script. But SignOutputRaw
|
||||
// still needs to know the PK script that was used for the
|
||||
// output. We'll send it in the WitnessScript field, the
|
||||
// SignOutputRaw RPC will know what to do with it when creating
|
||||
// the sighash.
|
||||
if len(signDesc.WitnessScript) == 0 && !signDesc.TaprootKeySpend {
|
||||
return nil, fmt.Errorf("witness script MUST be " +
|
||||
"specified for non-taproot-key-spends")
|
||||
// Check what sign method was selected by the user so, we know
|
||||
// exactly what we're expecting and can prevent some of the more
|
||||
// obvious usage errors.
|
||||
signMethod, err := UnmarshalSignMethod(signDesc.SignMethod)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to unmarshal sign "+
|
||||
"method: %v", err)
|
||||
}
|
||||
if !signMethod.PkScriptCompatible(signDesc.Output.PkScript) {
|
||||
return nil, fmt.Errorf("selected sign method %v is "+
|
||||
"not compatible with given pk script %x",
|
||||
signMethod, signDesc.Output.PkScript)
|
||||
}
|
||||
|
||||
// Perform input validation according to the sign method. Not
|
||||
// all methods require the same fields to be provided.
|
||||
switch signMethod {
|
||||
case input.WitnessV0SignMethod:
|
||||
// If a witness script isn't passed, then we can't
|
||||
// proceed, as in the p2wsh case, we can't properly
|
||||
// generate the sighash. A P2WKH doesn't need a witness
|
||||
// script. But SignOutputRaw still needs to know the PK
|
||||
// script that was used for the output. We'll send it in
|
||||
// the WitnessScript field, the SignOutputRaw RPC will
|
||||
// know what to do with it when creating the sighash.
|
||||
if len(signDesc.WitnessScript) == 0 {
|
||||
return nil, fmt.Errorf("witness script MUST " +
|
||||
"be specified for segwit v0 sign " +
|
||||
"method")
|
||||
}
|
||||
|
||||
case input.TaprootKeySpendBIP0086SignMethod:
|
||||
if len(signDesc.TapTweak) > 0 {
|
||||
return nil, fmt.Errorf("tap tweak must be " +
|
||||
"empty for BIP0086 key spend")
|
||||
}
|
||||
|
||||
case input.TaprootKeySpendSignMethod:
|
||||
if len(signDesc.TapTweak) != sha256.Size {
|
||||
return nil, fmt.Errorf("tap tweak must be " +
|
||||
"specified for key spend with root " +
|
||||
"hash")
|
||||
}
|
||||
|
||||
case input.TaprootScriptSpendSignMethod:
|
||||
if len(signDesc.WitnessScript) == 0 {
|
||||
return nil, fmt.Errorf("witness script MUST " +
|
||||
"be specified for taproot script " +
|
||||
"spend method")
|
||||
}
|
||||
}
|
||||
|
||||
// If the users provided a double tweak, then we'll need to
|
||||
@@ -390,10 +430,11 @@ func (s *Server) SignOutputRaw(_ context.Context, in *SignReq) (*SignResp,
|
||||
KeyLocator: keyLoc,
|
||||
PubKey: targetPubKey,
|
||||
},
|
||||
SingleTweak: signDesc.SingleTweak,
|
||||
DoubleTweak: tweakPrivKey,
|
||||
WitnessScript: signDesc.WitnessScript,
|
||||
TaprootKeySpend: signDesc.TaprootKeySpend,
|
||||
SingleTweak: signDesc.SingleTweak,
|
||||
DoubleTweak: tweakPrivKey,
|
||||
TapTweak: signDesc.TapTweak,
|
||||
WitnessScript: signDesc.WitnessScript,
|
||||
SignMethod: signMethod,
|
||||
Output: &wire.TxOut{
|
||||
Value: signDesc.Output.Value,
|
||||
PkScript: signDesc.Output.PkScript,
|
||||
@@ -1097,3 +1138,24 @@ func UnmarshalTweaks(rpcTweaks []*TweakDesc,
|
||||
|
||||
return tweaks, nil
|
||||
}
|
||||
|
||||
// UnmarshalSignMethod parses the RPC sign method into the native counterpart.
|
||||
func UnmarshalSignMethod(rpcSignMethod SignMethod) (input.SignMethod, error) {
|
||||
switch rpcSignMethod {
|
||||
case SignMethod_SIGN_METHOD_WITNESS_V0:
|
||||
return input.WitnessV0SignMethod, nil
|
||||
|
||||
case SignMethod_SIGN_METHOD_TAPROOT_KEY_SPEND_BIP0086:
|
||||
return input.TaprootKeySpendBIP0086SignMethod, nil
|
||||
|
||||
case SignMethod_SIGN_METHOD_TAPROOT_KEY_SPEND:
|
||||
return input.TaprootKeySpendSignMethod, nil
|
||||
|
||||
case SignMethod_SIGN_METHOD_TAPROOT_SCRIPT_SPEND:
|
||||
return input.TaprootScriptSpendSignMethod, nil
|
||||
|
||||
default:
|
||||
return 0, fmt.Errorf("unknown RPC sign method <%d>",
|
||||
rpcSignMethod)
|
||||
}
|
||||
}
|
||||
+259
-20
@@ -6,13 +6,17 @@ import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
|
||||
"github.com/btcsuite/btcd/btcec/v2/schnorr"
|
||||
"github.com/btcsuite/btcd/btcutil"
|
||||
"github.com/btcsuite/btcd/btcutil/hdkeychain"
|
||||
"github.com/btcsuite/btcd/btcutil/psbt"
|
||||
"github.com/btcsuite/btcd/txscript"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/lightningnetwork/lnd/funding"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
"github.com/lightningnetwork/lnd/lnrpc/signrpc"
|
||||
"github.com/lightningnetwork/lnd/lnrpc/walletrpc"
|
||||
@@ -632,19 +636,22 @@ func testPsbtChanFundingSingleStep(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
closeChannelAndAssert(t, net, carol, chanPoint, false)
|
||||
}
|
||||
|
||||
// runSignPsbt tests that the SignPsbt RPC works correctly.
|
||||
// testSignPsbt tests that the SignPsbt RPC works correctly.
|
||||
func testSignPsbt(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
runSignPsbt(t, net, net.Alice)
|
||||
runSignPsbtSegWitV0P2WKH(t, net, net.Alice)
|
||||
runSignPsbtSegWitV1KeySpendBip86(t, net, net.Alice)
|
||||
runSignPsbtSegWitV1KeySpendRootHash(t, net, net.Alice)
|
||||
runSignPsbtSegWitV1ScriptSpend(t, net, net.Alice)
|
||||
}
|
||||
|
||||
// runSignPsbt tests that the SignPsbt RPC works correctly.
|
||||
func runSignPsbt(t *harnessTest, net *lntest.NetworkHarness,
|
||||
// runSignPsbtSegWitV0P2WKH tests that the SignPsbt RPC works correctly for a
|
||||
// SegWit v0 p2wkh input.
|
||||
func runSignPsbtSegWitV0P2WKH(t *harnessTest, net *lntest.NetworkHarness,
|
||||
alice *lntest.HarnessNode) {
|
||||
|
||||
ctxb := context.Background()
|
||||
|
||||
// Everything we do here should be done within a second or two, so we
|
||||
// can just keep a single timeout context around for all calls.
|
||||
ctxb := context.Background()
|
||||
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
|
||||
defer cancel()
|
||||
|
||||
@@ -699,13 +706,224 @@ func runSignPsbt(t *harnessTest, net *lntest.NetworkHarness,
|
||||
pkScript, err := txscript.PayToAddrScript(witnessAddr)
|
||||
require.NoError(t.t, err)
|
||||
|
||||
// Send some funds to the output and then try to get a signature through
|
||||
// the SignPsbt RPC to spend that output again.
|
||||
assertPsbtSpend(
|
||||
ctxt, t, net, alice, pkScript,
|
||||
func(packet *psbt.Packet) {
|
||||
in := &packet.Inputs[0]
|
||||
in.Bip32Derivation = []*psbt.Bip32Derivation{{
|
||||
PubKey: addrPubKey.SerializeCompressed(),
|
||||
Bip32Path: fullDerivationPath,
|
||||
}}
|
||||
in.SighashType = txscript.SigHashAll
|
||||
},
|
||||
func(packet *psbt.Packet) {
|
||||
require.Len(t.t, packet.Inputs, 1)
|
||||
require.Len(t.t, packet.Inputs[0].PartialSigs, 1)
|
||||
|
||||
partialSig := packet.Inputs[0].PartialSigs[0]
|
||||
require.Equal(
|
||||
t.t, partialSig.PubKey,
|
||||
addrPubKey.SerializeCompressed(),
|
||||
)
|
||||
require.Greater(
|
||||
t.t, len(partialSig.Signature), ecdsa.MinSigLen,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// runSignPsbtSegWitV1KeySpendBip86 tests that the SignPsbt RPC works correctly
|
||||
// for a SegWit v1 p2tr key spend BIP-0086 input.
|
||||
func runSignPsbtSegWitV1KeySpendBip86(t *harnessTest, net *lntest.NetworkHarness,
|
||||
alice *lntest.HarnessNode) {
|
||||
|
||||
// Everything we do here should be done within a second or two, so we
|
||||
// can just keep a single timeout context around for all calls.
|
||||
ctxb := context.Background()
|
||||
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
|
||||
defer cancel()
|
||||
|
||||
// Derive a key we can use for signing.
|
||||
keyDesc, internalKey, fullDerivationPath := deriveInternalKey(
|
||||
ctxt, t, alice,
|
||||
)
|
||||
|
||||
// Our taproot key is a BIP0086 key spend only construction that just
|
||||
// commits to the internal key and no root hash.
|
||||
taprootKey := txscript.ComputeTaprootKeyNoScript(internalKey)
|
||||
tapScriptAddr, err := btcutil.NewAddressTaproot(
|
||||
schnorr.SerializePubKey(taprootKey), harnessNetParams,
|
||||
)
|
||||
require.NoError(t.t, err)
|
||||
p2trPkScript, err := txscript.PayToAddrScript(tapScriptAddr)
|
||||
require.NoError(t.t, err)
|
||||
|
||||
// Send some funds to the output and then try to get a signature through
|
||||
// the SignPsbt RPC to spend that output again.
|
||||
assertPsbtSpend(
|
||||
ctxt, t, net, alice, p2trPkScript,
|
||||
func(packet *psbt.Packet) {
|
||||
in := &packet.Inputs[0]
|
||||
in.Bip32Derivation = []*psbt.Bip32Derivation{{
|
||||
PubKey: keyDesc.RawKeyBytes,
|
||||
Bip32Path: fullDerivationPath,
|
||||
}}
|
||||
in.TaprootBip32Derivation = []*psbt.TaprootBip32Derivation{{
|
||||
XOnlyPubKey: keyDesc.RawKeyBytes[1:],
|
||||
Bip32Path: fullDerivationPath,
|
||||
}}
|
||||
in.SighashType = txscript.SigHashDefault
|
||||
},
|
||||
func(packet *psbt.Packet) {
|
||||
require.Len(t.t, packet.Inputs, 1)
|
||||
require.Len(
|
||||
t.t, packet.Inputs[0].TaprootKeySpendSig, 64,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// runSignPsbtSegWitV1KeySpendRootHash tests that the SignPsbt RPC works
|
||||
// correctly for a SegWit v1 p2tr key spend that also commits to a script tree
|
||||
// root hash.
|
||||
func runSignPsbtSegWitV1KeySpendRootHash(t *harnessTest,
|
||||
net *lntest.NetworkHarness, alice *lntest.HarnessNode) {
|
||||
|
||||
// Everything we do here should be done within a second or two, so we
|
||||
// can just keep a single timeout context around for all calls.
|
||||
ctxb := context.Background()
|
||||
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
|
||||
defer cancel()
|
||||
|
||||
// Derive a key we can use for signing.
|
||||
keyDesc, internalKey, fullDerivationPath := deriveInternalKey(
|
||||
ctxt, t, alice,
|
||||
)
|
||||
|
||||
// Let's create a taproot script output now. This is a hash lock with a
|
||||
// simple preimage of "foobar".
|
||||
leaf1 := testScriptHashLock(t.t, []byte("foobar"))
|
||||
|
||||
rootHash := leaf1.TapHash()
|
||||
taprootKey := txscript.ComputeTaprootOutputKey(internalKey, rootHash[:])
|
||||
tapScriptAddr, err := btcutil.NewAddressTaproot(
|
||||
schnorr.SerializePubKey(taprootKey), harnessNetParams,
|
||||
)
|
||||
require.NoError(t.t, err)
|
||||
p2trPkScript, err := txscript.PayToAddrScript(tapScriptAddr)
|
||||
require.NoError(t.t, err)
|
||||
|
||||
// Send some funds to the output and then try to get a signature through
|
||||
// the SignPsbt RPC to spend that output again.
|
||||
assertPsbtSpend(
|
||||
ctxt, t, net, alice, p2trPkScript,
|
||||
func(packet *psbt.Packet) {
|
||||
in := &packet.Inputs[0]
|
||||
in.Bip32Derivation = []*psbt.Bip32Derivation{{
|
||||
PubKey: keyDesc.RawKeyBytes,
|
||||
Bip32Path: fullDerivationPath,
|
||||
}}
|
||||
in.TaprootBip32Derivation = []*psbt.TaprootBip32Derivation{{
|
||||
XOnlyPubKey: keyDesc.RawKeyBytes[1:],
|
||||
Bip32Path: fullDerivationPath,
|
||||
}}
|
||||
in.TaprootMerkleRoot = rootHash[:]
|
||||
in.SighashType = txscript.SigHashDefault
|
||||
},
|
||||
func(packet *psbt.Packet) {
|
||||
require.Len(t.t, packet.Inputs, 1)
|
||||
require.Len(
|
||||
t.t, packet.Inputs[0].TaprootKeySpendSig, 64,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// runSignPsbtSegWitV1ScriptSpend tests that the SignPsbt RPC works correctly
|
||||
// for a SegWit v1 p2tr script spend.
|
||||
func runSignPsbtSegWitV1ScriptSpend(t *harnessTest,
|
||||
net *lntest.NetworkHarness, alice *lntest.HarnessNode) {
|
||||
|
||||
// Everything we do here should be done within a second or two, so we
|
||||
// can just keep a single timeout context around for all calls.
|
||||
ctxb := context.Background()
|
||||
ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
|
||||
defer cancel()
|
||||
|
||||
// Derive a key we can use for signing.
|
||||
keyDesc, internalKey, fullDerivationPath := deriveInternalKey(
|
||||
ctxt, t, alice,
|
||||
)
|
||||
|
||||
// Let's create a taproot script output now. This is a hash lock with a
|
||||
// simple preimage of "foobar".
|
||||
leaf1 := testScriptSchnorrSig(t.t, internalKey)
|
||||
|
||||
rootHash := leaf1.TapHash()
|
||||
taprootKey := txscript.ComputeTaprootOutputKey(internalKey, rootHash[:])
|
||||
tapScriptAddr, err := btcutil.NewAddressTaproot(
|
||||
schnorr.SerializePubKey(taprootKey), harnessNetParams,
|
||||
)
|
||||
require.NoError(t.t, err)
|
||||
p2trPkScript, err := txscript.PayToAddrScript(tapScriptAddr)
|
||||
require.NoError(t.t, err)
|
||||
|
||||
// We need to assemble the control block to be able to spend through the
|
||||
// script path.
|
||||
tapscript := input.TapscriptPartialReveal(internalKey, leaf1, nil)
|
||||
controlBlockBytes, err := tapscript.ControlBlock.ToBytes()
|
||||
require.NoError(t.t, err)
|
||||
|
||||
// Send some funds to the output and then try to get a signature through
|
||||
// the SignPsbt RPC to spend that output again.
|
||||
assertPsbtSpend(
|
||||
ctxt, t, net, alice, p2trPkScript,
|
||||
func(packet *psbt.Packet) {
|
||||
in := &packet.Inputs[0]
|
||||
in.Bip32Derivation = []*psbt.Bip32Derivation{{
|
||||
PubKey: keyDesc.RawKeyBytes,
|
||||
Bip32Path: fullDerivationPath,
|
||||
}}
|
||||
in.TaprootBip32Derivation = []*psbt.TaprootBip32Derivation{{
|
||||
XOnlyPubKey: keyDesc.RawKeyBytes[1:],
|
||||
Bip32Path: fullDerivationPath,
|
||||
LeafHashes: [][]byte{rootHash[:]},
|
||||
}}
|
||||
in.SighashType = txscript.SigHashDefault
|
||||
in.TaprootLeafScript = []*psbt.TaprootTapLeafScript{{
|
||||
ControlBlock: controlBlockBytes,
|
||||
Script: leaf1.Script,
|
||||
LeafVersion: leaf1.LeafVersion,
|
||||
}}
|
||||
},
|
||||
func(packet *psbt.Packet) {
|
||||
require.Len(t.t, packet.Inputs, 1)
|
||||
require.Len(
|
||||
t.t, packet.Inputs[0].TaprootScriptSpendSig, 1,
|
||||
)
|
||||
|
||||
scriptSpendSig := packet.Inputs[0].TaprootScriptSpendSig[0]
|
||||
require.Len(t.t, scriptSpendSig.Signature, 64)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// assertPsbtSpend creates an output with the given pkScript on chain and then
|
||||
// attempts to create a sweep transaction that is signed using the SignPsbt RPC
|
||||
// that spends that output again.
|
||||
func assertPsbtSpend(ctx context.Context, t *harnessTest,
|
||||
net *lntest.NetworkHarness, alice *lntest.HarnessNode, pkScript []byte,
|
||||
decorateUnsigned func(*psbt.Packet), verifySigned func(*psbt.Packet)) {
|
||||
|
||||
// Let's send some coins to that address now.
|
||||
utxo := &wire.TxOut{
|
||||
Value: 600_000,
|
||||
PkScript: pkScript,
|
||||
}
|
||||
resp, err := alice.WalletKitClient.SendOutputs(
|
||||
ctxt, &walletrpc.SendOutputsRequest{
|
||||
ctx, &walletrpc.SendOutputsRequest{
|
||||
Outputs: []*signrpc.TxOut{{
|
||||
Value: utxo.Value,
|
||||
PkScript: utxo.PkScript,
|
||||
@@ -748,13 +966,9 @@ func runSignPsbt(t *harnessTest, net *lntest.NetworkHarness,
|
||||
require.NoError(t.t, err)
|
||||
|
||||
// Now let's add the meta information that we need for signing.
|
||||
packet.Inputs[0].Bip32Derivation = []*psbt.Bip32Derivation{{
|
||||
PubKey: addrPubKey.SerializeCompressed(),
|
||||
Bip32Path: fullDerivationPath,
|
||||
}}
|
||||
packet.Inputs[0].WitnessUtxo = utxo
|
||||
packet.Inputs[0].NonWitnessUtxo = prevTx
|
||||
packet.Inputs[0].SighashType = txscript.SigHashAll
|
||||
decorateUnsigned(packet)
|
||||
|
||||
// That's it, we should be able to sign the PSBT now.
|
||||
var buf bytes.Buffer
|
||||
@@ -762,7 +976,7 @@ func runSignPsbt(t *harnessTest, net *lntest.NetworkHarness,
|
||||
require.NoError(t.t, err)
|
||||
|
||||
signResp, err := alice.WalletKitClient.SignPsbt(
|
||||
ctxt, &walletrpc.SignPsbtRequest{
|
||||
ctx, &walletrpc.SignPsbtRequest{
|
||||
FundedPsbt: buf.Bytes(),
|
||||
},
|
||||
)
|
||||
@@ -774,12 +988,9 @@ func runSignPsbt(t *harnessTest, net *lntest.NetworkHarness,
|
||||
)
|
||||
require.NoError(t.t, err)
|
||||
|
||||
require.Len(t.t, signedPacket.Inputs, 1)
|
||||
require.Len(t.t, signedPacket.Inputs[0].PartialSigs, 1)
|
||||
|
||||
partialSig := signedPacket.Inputs[0].PartialSigs[0]
|
||||
require.Equal(t.t, partialSig.PubKey, addrPubKey.SerializeCompressed())
|
||||
require.Greater(t.t, len(partialSig.Signature), ecdsa.MinSigLen)
|
||||
// Allow the caller to also verify (and potentially move) some of the
|
||||
// returned fields.
|
||||
verifySigned(signedPacket)
|
||||
|
||||
// We should be able to finalize the PSBT and extract the final TX now.
|
||||
err = psbt.MaybeFinalizeAll(signedPacket)
|
||||
@@ -794,7 +1005,7 @@ func runSignPsbt(t *harnessTest, net *lntest.NetworkHarness,
|
||||
|
||||
// Publish the second transaction and then mine both of them.
|
||||
_, err = alice.WalletKitClient.PublishTransaction(
|
||||
ctxt, &walletrpc.Transaction{
|
||||
ctx, &walletrpc.Transaction{
|
||||
TxHex: buf.Bytes(),
|
||||
},
|
||||
)
|
||||
@@ -808,6 +1019,34 @@ func runSignPsbt(t *harnessTest, net *lntest.NetworkHarness,
|
||||
assertTxInBlock(t, block, &secondTxHash)
|
||||
}
|
||||
|
||||
// deriveInternalKey derives a signing key and returns its descriptor, full
|
||||
// derivation path and parsed public key.
|
||||
func deriveInternalKey(ctx context.Context, t *harnessTest,
|
||||
alice *lntest.HarnessNode) (*signrpc.KeyDescriptor, *btcec.PublicKey,
|
||||
[]uint32) {
|
||||
|
||||
// For the next step, we need a public key. Let's use a special family
|
||||
// for this.
|
||||
keyDesc, err := alice.WalletKitClient.DeriveNextKey(
|
||||
ctx, &walletrpc.KeyReq{KeyFamily: testTaprootKeyFamily},
|
||||
)
|
||||
require.NoError(t.t, err)
|
||||
|
||||
// The DeriveNextKey returns a key from the internal 1017 scope.
|
||||
fullDerivationPath := []uint32{
|
||||
hdkeychain.HardenedKeyStart + keychain.BIP0043Purpose,
|
||||
hdkeychain.HardenedKeyStart + harnessNetParams.HDCoinType,
|
||||
hdkeychain.HardenedKeyStart + uint32(keyDesc.KeyLoc.KeyFamily),
|
||||
0,
|
||||
uint32(keyDesc.KeyLoc.KeyIndex),
|
||||
}
|
||||
|
||||
parsedPubKey, err := btcec.ParsePubKey(keyDesc.RawKeyBytes)
|
||||
require.NoError(t.t, err)
|
||||
|
||||
return keyDesc, parsedPubKey, fullDerivationPath
|
||||
}
|
||||
|
||||
// openChannelPsbt attempts to open a channel between srcNode and destNode with
|
||||
// the passed channel funding parameters. If the passed context has a timeout,
|
||||
// then if the timeout is reached before the channel pending notification is
|
||||
|
||||
@@ -106,7 +106,10 @@ func testRemoteSigner(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
name: "psbt",
|
||||
fn: func(tt *harnessTest, wo, carol *lntest.HarnessNode) {
|
||||
runPsbtChanFunding(net, tt, carol, wo)
|
||||
runSignPsbt(tt, net, wo)
|
||||
runSignPsbtSegWitV0P2WKH(tt, net, wo)
|
||||
runSignPsbtSegWitV1KeySpendBip86(tt, net, wo)
|
||||
runSignPsbtSegWitV1KeySpendRootHash(tt, net, wo)
|
||||
runSignPsbtSegWitV1ScriptSpend(tt, net, wo)
|
||||
},
|
||||
}, {
|
||||
name: "sign output raw",
|
||||
@@ -123,18 +126,14 @@ func testRemoteSigner(net *lntest.NetworkHarness, t *harnessTest) {
|
||||
)
|
||||
defer cancel()
|
||||
|
||||
// TODO(guggero): Fix remote taproot signing by adding
|
||||
// the required fields to PSBT.
|
||||
// testTaprootComputeInputScriptKeySpendBip86(
|
||||
// ctxt, tt, wo, net,
|
||||
// )
|
||||
// testTaprootSignOutputRawScriptSpend(ctxt, tt, wo, net)
|
||||
// testTaprootSignOutputRawKeySpendBip86(
|
||||
// ctxt, tt, wo, net,
|
||||
// )
|
||||
// testTaprootSignOutputRawKeySpendRootHash(
|
||||
// ctxt, tt, wo, net,
|
||||
// )
|
||||
testTaprootComputeInputScriptKeySpendBip86(
|
||||
ctxt, tt, wo, net,
|
||||
)
|
||||
testTaprootSignOutputRawScriptSpend(ctxt, tt, wo, net)
|
||||
testTaprootSignOutputRawKeySpendBip86(ctxt, tt, wo, net)
|
||||
testTaprootSignOutputRawKeySpendRootHash(
|
||||
ctxt, tt, wo, net,
|
||||
)
|
||||
testTaprootMuSig2KeySpendRootHash(ctxt, tt, wo, net)
|
||||
testTaprootMuSig2ScriptSpend(ctxt, tt, wo, net)
|
||||
testTaprootMuSig2KeySpendBip86(ctxt, tt, wo, net)
|
||||
|
||||
@@ -26,6 +26,9 @@ import (
|
||||
const (
|
||||
testTaprootKeyFamily = 77
|
||||
testAmount = 800_000
|
||||
signMethodBip86 = signrpc.SignMethod_SIGN_METHOD_TAPROOT_KEY_SPEND_BIP0086
|
||||
signMethodRootHash = signrpc.SignMethod_SIGN_METHOD_TAPROOT_KEY_SPEND
|
||||
signMethodTapscript = signrpc.SignMethod_SIGN_METHOD_TAPROOT_SCRIPT_SPEND
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -193,6 +196,7 @@ func testTaprootSignOutputRawScriptSpend(ctxt context.Context, t *harnessTest,
|
||||
KeyDesc: keyDesc,
|
||||
Sighash: uint32(txscript.SigHashDefault),
|
||||
WitnessScript: leaf2.Script,
|
||||
SignMethod: signMethodTapscript,
|
||||
}},
|
||||
},
|
||||
)
|
||||
@@ -202,6 +206,27 @@ func testTaprootSignOutputRawScriptSpend(ctxt context.Context, t *harnessTest,
|
||||
"input 0 is missing its previous outpoint information",
|
||||
)
|
||||
|
||||
// We also want to make sure we get an error when we don't specify the
|
||||
// correct signing method.
|
||||
_, err = alice.SignerClient.SignOutputRaw(
|
||||
ctxt, &signrpc.SignReq{
|
||||
RawTxBytes: buf.Bytes(),
|
||||
SignDescs: []*signrpc.SignDescriptor{{
|
||||
Output: utxoInfo[0],
|
||||
InputIndex: 0,
|
||||
KeyDesc: keyDesc,
|
||||
Sighash: uint32(txscript.SigHashDefault),
|
||||
WitnessScript: leaf2.Script,
|
||||
}},
|
||||
PrevOutputs: utxoInfo,
|
||||
},
|
||||
)
|
||||
require.Error(t.t, err)
|
||||
require.Contains(
|
||||
t.t, err.Error(), "selected sign method witness_v0 is not "+
|
||||
"compatible with given pk script 5120",
|
||||
)
|
||||
|
||||
// Do the actual signing now.
|
||||
signResp, err := alice.SignerClient.SignOutputRaw(
|
||||
ctxt, &signrpc.SignReq{
|
||||
@@ -212,6 +237,7 @@ func testTaprootSignOutputRawScriptSpend(ctxt context.Context, t *harnessTest,
|
||||
KeyDesc: keyDesc,
|
||||
Sighash: uint32(txscript.SigHashDefault),
|
||||
WitnessScript: leaf2.Script,
|
||||
SignMethod: signMethodTapscript,
|
||||
}},
|
||||
PrevOutputs: utxoInfo,
|
||||
},
|
||||
@@ -307,12 +333,12 @@ func testTaprootSignOutputRawKeySpendBip86(ctxt context.Context,
|
||||
ctxt, &signrpc.SignReq{
|
||||
RawTxBytes: buf.Bytes(),
|
||||
SignDescs: []*signrpc.SignDescriptor{{
|
||||
Output: utxoInfo[0],
|
||||
InputIndex: 0,
|
||||
KeyDesc: keyDesc,
|
||||
SingleTweak: dummyKeyTweak[:],
|
||||
Sighash: uint32(txscript.SigHashDefault),
|
||||
TaprootKeySpend: true,
|
||||
Output: utxoInfo[0],
|
||||
InputIndex: 0,
|
||||
KeyDesc: keyDesc,
|
||||
SingleTweak: dummyKeyTweak[:],
|
||||
Sighash: uint32(txscript.SigHashDefault),
|
||||
SignMethod: signMethodBip86,
|
||||
}},
|
||||
PrevOutputs: utxoInfo,
|
||||
},
|
||||
@@ -405,13 +431,13 @@ func testTaprootSignOutputRawKeySpendRootHash(ctxt context.Context,
|
||||
ctxt, &signrpc.SignReq{
|
||||
RawTxBytes: buf.Bytes(),
|
||||
SignDescs: []*signrpc.SignDescriptor{{
|
||||
Output: utxoInfo[0],
|
||||
InputIndex: 0,
|
||||
KeyDesc: keyDesc,
|
||||
SingleTweak: dummyKeyTweak[:],
|
||||
Sighash: uint32(txscript.SigHashDefault),
|
||||
WitnessScript: rootHash[:],
|
||||
TaprootKeySpend: true,
|
||||
Output: utxoInfo[0],
|
||||
InputIndex: 0,
|
||||
KeyDesc: keyDesc,
|
||||
SingleTweak: dummyKeyTweak[:],
|
||||
Sighash: uint32(txscript.SigHashDefault),
|
||||
TapTweak: rootHash[:],
|
||||
SignMethod: signMethodRootHash,
|
||||
}},
|
||||
PrevOutputs: utxoInfo,
|
||||
},
|
||||
|
||||
+235
-31
@@ -2,12 +2,15 @@ package btcwallet
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
|
||||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
"github.com/btcsuite/btcd/btcec/v2/schnorr"
|
||||
"github.com/btcsuite/btcd/btcutil"
|
||||
"github.com/btcsuite/btcd/btcutil/psbt"
|
||||
"github.com/btcsuite/btcd/txscript"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/btcsuite/btcwallet/waddrmgr"
|
||||
"github.com/btcsuite/btcwallet/wallet"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
@@ -111,7 +114,7 @@ func (b *BtcWallet) SignPsbt(packet *psbt.Packet) error {
|
||||
prevOutputFetcher := wallet.PsbtPrevOutputFetcher(packet)
|
||||
sigHashes := txscript.NewTxSigHashes(tx, prevOutputFetcher)
|
||||
for idx := range tx.TxIn {
|
||||
in := packet.Inputs[idx]
|
||||
in := &packet.Inputs[idx]
|
||||
|
||||
// We can only sign if we have UTXO information available. Since
|
||||
// we don't finalize, we just skip over any input that we know
|
||||
@@ -165,47 +168,248 @@ func (b *BtcWallet) SignPsbt(packet *psbt.Packet) error {
|
||||
// Do we need to tweak anything? Single or double tweaks are
|
||||
// sent as custom/proprietary fields in the PSBT input section.
|
||||
privKey = maybeTweakPrivKeyPsbt(in.Unknowns, privKey)
|
||||
pubKeyBytes := privKey.PubKey().SerializeCompressed()
|
||||
|
||||
// Extract the correct witness and/or legacy scripts now,
|
||||
// depending on the type of input we sign. The txscript package
|
||||
// has the peculiar requirement that the PkScript of a P2PKH
|
||||
// must be given as the witness script in order for it to arrive
|
||||
// at the correct sighash. That's why we call it subScript here
|
||||
// instead of witness script.
|
||||
subScript, scriptSig, err := prepareScripts(in)
|
||||
// What kind of signature is expected from us and do we have all
|
||||
// information we need?
|
||||
signMethod, err := validateSigningMethod(in)
|
||||
if err != nil {
|
||||
// We derived the correct key so we _are_ expected to
|
||||
// sign this. Not being able to sign at this point means
|
||||
// there's something wrong.
|
||||
return fmt.Errorf("error deriving script for input "+
|
||||
"%d: %v", idx, err)
|
||||
return err
|
||||
}
|
||||
|
||||
// We have everything we need for signing the input now.
|
||||
sig, err := txscript.RawTxInWitnessSignature(
|
||||
tx, sigHashes, idx, in.WitnessUtxo.Value, subScript,
|
||||
in.SighashType, privKey,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error signing input %d: %v", idx,
|
||||
err)
|
||||
switch signMethod {
|
||||
// For p2wkh, np2wkh and p2wsh.
|
||||
case input.WitnessV0SignMethod:
|
||||
err = signSegWitV0(in, tx, sigHashes, idx, privKey)
|
||||
|
||||
// For p2tr BIP0086 key spend only.
|
||||
case input.TaprootKeySpendBIP0086SignMethod:
|
||||
rootHash := make([]byte, 0)
|
||||
err = signSegWitV1KeySpend(
|
||||
in, tx, sigHashes, idx, privKey, rootHash,
|
||||
)
|
||||
|
||||
// For p2tr with script commitment key spend path.
|
||||
case input.TaprootKeySpendSignMethod:
|
||||
rootHash := in.TaprootMerkleRoot
|
||||
err = signSegWitV1KeySpend(
|
||||
in, tx, sigHashes, idx, privKey, rootHash,
|
||||
)
|
||||
|
||||
// For p2tr script spend path.
|
||||
case input.TaprootScriptSpendSignMethod:
|
||||
leafScript := in.TaprootLeafScript[0]
|
||||
leaf := txscript.TapLeaf{
|
||||
LeafVersion: leafScript.LeafVersion,
|
||||
Script: leafScript.Script,
|
||||
}
|
||||
err = signSegWitV1ScriptSpend(
|
||||
in, tx, sigHashes, idx, privKey, leaf,
|
||||
)
|
||||
|
||||
default:
|
||||
err = fmt.Errorf("unsupported signing method for "+
|
||||
"PSBT signing: %v", signMethod)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
packet.Inputs[idx].FinalScriptSig = scriptSig
|
||||
packet.Inputs[idx].PartialSigs = append(
|
||||
packet.Inputs[idx].PartialSigs, &psbt.PartialSig{
|
||||
PubKey: pubKeyBytes,
|
||||
Signature: sig,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// prepareScripts returns the appropriate witness and/or legacy scripts,
|
||||
// validateSigningMethod attempts to detect the signing method that is required
|
||||
// to sign for the given PSBT input and makes sure all information is available
|
||||
// to do so.
|
||||
func validateSigningMethod(in *psbt.PInput) (input.SignMethod, error) {
|
||||
script, err := txscript.ParsePkScript(in.WitnessUtxo.PkScript)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("error detecting signing method, "+
|
||||
"couldn't parse pkScript: %v", err)
|
||||
}
|
||||
|
||||
switch script.Class() {
|
||||
case txscript.WitnessV0PubKeyHashTy, txscript.ScriptHashTy,
|
||||
txscript.WitnessV0ScriptHashTy:
|
||||
|
||||
return input.WitnessV0SignMethod, nil
|
||||
|
||||
case txscript.WitnessV1TaprootTy:
|
||||
if len(in.TaprootBip32Derivation) == 0 {
|
||||
return 0, fmt.Errorf("cannot sign for taproot input " +
|
||||
"without taproot BIP0032 derivation info")
|
||||
}
|
||||
|
||||
// Currently, we only support creating one signature per input.
|
||||
//
|
||||
// TODO(guggero): Should we support signing multiple paths at
|
||||
// the same time? What are the performance and security
|
||||
// implications?
|
||||
if len(in.TaprootBip32Derivation) > 1 {
|
||||
return 0, fmt.Errorf("unsupported multiple taproot " +
|
||||
"BIP0032 derivation info found, can only " +
|
||||
"sign for one at a time")
|
||||
}
|
||||
|
||||
derivation := in.TaprootBip32Derivation[0]
|
||||
switch {
|
||||
// No leaf hashes means this is the internal key we're signing
|
||||
// with, so it's a key spend. And no merkle root means this is
|
||||
// a BIP0086 output we're signing for.
|
||||
case len(derivation.LeafHashes) == 0 &&
|
||||
len(in.TaprootMerkleRoot) == 0:
|
||||
|
||||
return input.TaprootKeySpendBIP0086SignMethod, nil
|
||||
|
||||
// A non-empty merkle root means we committed to a taproot hash
|
||||
// that we need to use in the tap tweak.
|
||||
case len(derivation.LeafHashes) == 0:
|
||||
// Getting here means the merkle root isn't empty, but
|
||||
// is it exactly the length we need?
|
||||
if len(in.TaprootMerkleRoot) != sha256.Size {
|
||||
return 0, fmt.Errorf("invalid taproot merkle "+
|
||||
"root length, got %d expected %d",
|
||||
len(in.TaprootMerkleRoot), sha256.Size)
|
||||
}
|
||||
|
||||
return input.TaprootKeySpendSignMethod, nil
|
||||
|
||||
// Currently, we only support signing for one leaf at a time.
|
||||
//
|
||||
// TODO(guggero): Should we support signing multiple paths at
|
||||
// the same time? What are the performance and security
|
||||
// implications?
|
||||
case len(derivation.LeafHashes) == 1:
|
||||
// If we're supposed to be signing for a leaf hash, we
|
||||
// also expect the leaf script that hashes to that hash
|
||||
// in the appropriate field.
|
||||
if len(in.TaprootLeafScript) != 1 {
|
||||
return 0, fmt.Errorf("specified leaf hash in " +
|
||||
"taproot BIP0032 derivation but " +
|
||||
"missing taproot leaf script")
|
||||
}
|
||||
|
||||
leafScript := in.TaprootLeafScript[0]
|
||||
leaf := txscript.TapLeaf{
|
||||
LeafVersion: leafScript.LeafVersion,
|
||||
Script: leafScript.Script,
|
||||
}
|
||||
leafHash := leaf.TapHash()
|
||||
if !bytes.Equal(leafHash[:], derivation.LeafHashes[0]) {
|
||||
return 0, fmt.Errorf("specified leaf hash in" +
|
||||
"taproot BIP0032 derivation but " +
|
||||
"corresponding taproot leaf script " +
|
||||
"was not found")
|
||||
}
|
||||
|
||||
return input.TaprootScriptSpendSignMethod, nil
|
||||
|
||||
default:
|
||||
return 0, fmt.Errorf("unsupported number of leaf " +
|
||||
"hashes in taproot BIP0032 derivation info, " +
|
||||
"can only sign for one at a time")
|
||||
}
|
||||
|
||||
default:
|
||||
return 0, fmt.Errorf("unsupported script class for signing "+
|
||||
"PSBT: %v", script.Class())
|
||||
}
|
||||
}
|
||||
|
||||
// SignSegWitV0 attempts to generate a signature for a SegWit version 0 input
|
||||
// and stores it in the PartialSigs (and FinalScriptSig for np2wkh addresses)
|
||||
// field.
|
||||
func signSegWitV0(in *psbt.PInput, tx *wire.MsgTx,
|
||||
sigHashes *txscript.TxSigHashes, idx int,
|
||||
privKey *btcec.PrivateKey) error {
|
||||
|
||||
pubKeyBytes := privKey.PubKey().SerializeCompressed()
|
||||
|
||||
// Extract the correct witness and/or legacy scripts now, depending on
|
||||
// the type of input we sign. The txscript package has the peculiar
|
||||
// requirement that the PkScript of a P2PKH must be given as the witness
|
||||
// script in order for it to arrive at the correct sighash. That's why
|
||||
// we call it subScript here instead of witness script.
|
||||
subScript, scriptSig, err := prepareScriptsV0(in)
|
||||
if err != nil {
|
||||
// We derived the correct key so we _are_ expected to sign this.
|
||||
// Not being able to sign at this point means there's something
|
||||
// wrong.
|
||||
return fmt.Errorf("error deriving script for input %d: %v", idx,
|
||||
err)
|
||||
}
|
||||
|
||||
// We have everything we need for signing the input now.
|
||||
sig, err := txscript.RawTxInWitnessSignature(
|
||||
tx, sigHashes, idx, in.WitnessUtxo.Value, subScript,
|
||||
in.SighashType, privKey,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error signing input %d: %v", idx, err)
|
||||
}
|
||||
in.FinalScriptSig = scriptSig
|
||||
in.PartialSigs = append(in.PartialSigs, &psbt.PartialSig{
|
||||
PubKey: pubKeyBytes,
|
||||
Signature: sig,
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// signSegWitV1KeySpend attempts to generate a signature for a SegWit version 1
|
||||
// (p2tr) input and stores it in the TaprootKeySpendSig field.
|
||||
func signSegWitV1KeySpend(in *psbt.PInput, tx *wire.MsgTx,
|
||||
sigHashes *txscript.TxSigHashes, idx int, privKey *btcec.PrivateKey,
|
||||
tapscriptRootHash []byte) error {
|
||||
|
||||
rawSig, err := txscript.RawTxInTaprootSignature(
|
||||
tx, sigHashes, idx, in.WitnessUtxo.Value,
|
||||
in.WitnessUtxo.PkScript, tapscriptRootHash, in.SighashType,
|
||||
privKey,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error signing taproot input %d: %v", idx,
|
||||
err)
|
||||
}
|
||||
|
||||
in.TaprootKeySpendSig = rawSig
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// signSegWitV1ScriptSpend attempts to generate a signature for a SegWit version
|
||||
// 1 (p2tr) input and stores it in the TaprootScriptSpendSig field.
|
||||
func signSegWitV1ScriptSpend(in *psbt.PInput, tx *wire.MsgTx,
|
||||
sigHashes *txscript.TxSigHashes, idx int, privKey *btcec.PrivateKey,
|
||||
leaf txscript.TapLeaf) error {
|
||||
|
||||
rawSig, err := txscript.RawTxInTapscriptSignature(
|
||||
tx, sigHashes, idx, in.WitnessUtxo.Value,
|
||||
in.WitnessUtxo.PkScript, leaf, in.SighashType, privKey,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error signing taproot script input %d: %v",
|
||||
idx, err)
|
||||
}
|
||||
|
||||
leafHash := leaf.TapHash()
|
||||
in.TaprootScriptSpendSig = append(
|
||||
in.TaprootScriptSpendSig, &psbt.TaprootScriptSpendSig{
|
||||
XOnlyPubKey: in.TaprootBip32Derivation[0].XOnlyPubKey,
|
||||
LeafHash: leafHash[:],
|
||||
// We snip off the sighash flag from the end (if it was
|
||||
// specified in the first place.)
|
||||
Signature: rawSig[:schnorr.SignatureSize],
|
||||
SigHash: in.SighashType,
|
||||
},
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// prepareScriptsV0 returns the appropriate witness v0 and/or legacy scripts,
|
||||
// depending on the type of input that should be signed.
|
||||
func prepareScripts(in psbt.PInput) ([]byte, []byte, error) {
|
||||
func prepareScriptsV0(in *psbt.PInput) ([]byte, []byte, error) {
|
||||
switch {
|
||||
// It's a NP2WKH input:
|
||||
case len(in.RedeemScript) > 0:
|
||||
|
||||
@@ -372,21 +372,23 @@ func (b *BtcWallet) SignOutputRaw(tx *wire.MsgTx,
|
||||
// slightly different, so we need to account for that to get the
|
||||
// raw signature.
|
||||
var rawSig []byte
|
||||
if signDesc.TaprootKeySpend {
|
||||
switch signDesc.SignMethod {
|
||||
case input.TaprootKeySpendBIP0086SignMethod,
|
||||
input.TaprootKeySpendSignMethod:
|
||||
|
||||
// This function tweaks the private key using the tap
|
||||
// root key supplied as the tweak. So we pass in the
|
||||
// original private key to avoid it being double
|
||||
// tweaked!
|
||||
// root key supplied as the tweak.
|
||||
rawSig, err = txscript.RawTxInTaprootSignature(
|
||||
tx, sigHashes, signDesc.InputIndex,
|
||||
signDesc.Output.Value, signDesc.Output.PkScript,
|
||||
signDesc.WitnessScript, signDesc.HashType,
|
||||
signDesc.TapTweak, signDesc.HashType,
|
||||
privKey,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
|
||||
case input.TaprootScriptSpendSignMethod:
|
||||
leaf := txscript.TapLeaf{
|
||||
LeafVersion: txscript.BaseLeafVersion,
|
||||
Script: witnessScript,
|
||||
|
||||
+178
-20
@@ -544,6 +544,35 @@ func (r *RPCKeyRing) ComputeInputScript(tx *wire.MsgTx,
|
||||
}
|
||||
signDesc.WitnessScript = witnessProgram
|
||||
|
||||
// If this is a p2tr address, then it must be a BIP0086 key spend if we
|
||||
// are coming through this path (instead of SignOutputRaw).
|
||||
switch addr.AddrType() {
|
||||
case waddrmgr.TaprootPubKey:
|
||||
signDesc.SignMethod = input.TaprootKeySpendBIP0086SignMethod
|
||||
signDesc.WitnessScript = nil
|
||||
|
||||
sig, err := r.remoteSign(tx, signDesc, sigScript)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error signing with remote"+
|
||||
"instance: %v", err)
|
||||
}
|
||||
|
||||
rawSig := sig.Serialize()
|
||||
if signDesc.HashType != txscript.SigHashDefault {
|
||||
rawSig = append(rawSig, byte(signDesc.HashType))
|
||||
}
|
||||
|
||||
return &input.Script{
|
||||
Witness: wire.TxWitness{
|
||||
rawSig,
|
||||
},
|
||||
}, nil
|
||||
|
||||
case waddrmgr.TaprootScript:
|
||||
return nil, fmt.Errorf("computing input script for taproot " +
|
||||
"script address not supported")
|
||||
}
|
||||
|
||||
// Let's give the TX to the remote instance now, so it can sign the
|
||||
// input.
|
||||
sig, err := r.remoteSign(tx, signDesc, sigScript)
|
||||
@@ -803,6 +832,19 @@ func (r *RPCKeyRing) remoteSign(tx *wire.MsgTx, signDesc *input.SignDescriptor,
|
||||
&txIn.PreviousOutPoint,
|
||||
)
|
||||
if err != nil {
|
||||
// Maybe we have an UTXO in the previous output fetcher?
|
||||
if signDesc.PrevOutputFetcher != nil {
|
||||
utxo := signDesc.PrevOutputFetcher.FetchPrevOutput(
|
||||
txIn.PreviousOutPoint,
|
||||
)
|
||||
if utxo != nil && utxo.Value != 0 &&
|
||||
len(utxo.PkScript) > 0 {
|
||||
|
||||
packet.Inputs[idx].WitnessUtxo = utxo
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
log.Warnf("No UTXO info found for index %d "+
|
||||
"(prev_outpoint=%v), won't be able to sign "+
|
||||
"for taproot output!", idx,
|
||||
@@ -966,6 +1008,73 @@ func (r *RPCKeyRing) remoteSign(tx *wire.MsgTx, signDesc *input.SignDescriptor,
|
||||
})
|
||||
}
|
||||
|
||||
// Add taproot specific fields.
|
||||
switch signDesc.SignMethod {
|
||||
case input.TaprootKeySpendBIP0086SignMethod,
|
||||
input.TaprootKeySpendSignMethod:
|
||||
|
||||
// The key identifying factor for a key spend is that we don't
|
||||
// provide any leaf hashes to signal we want a signature for the
|
||||
// key spend path (with the internal key).
|
||||
d := in.Bip32Derivation[0]
|
||||
in.TaprootBip32Derivation = []*psbt.TaprootBip32Derivation{{
|
||||
// The x-only public key is just our compressed public
|
||||
// key without the first byte (type/parity).
|
||||
XOnlyPubKey: d.PubKey[1:],
|
||||
LeafHashes: nil,
|
||||
MasterKeyFingerprint: d.MasterKeyFingerprint,
|
||||
Bip32Path: d.Bip32Path,
|
||||
}}
|
||||
|
||||
// If this is a BIP0086 key spend then the tap tweak is empty,
|
||||
// otherwise it's set to the Taproot root hash.
|
||||
in.TaprootMerkleRoot = signDesc.TapTweak
|
||||
|
||||
case input.TaprootScriptSpendSignMethod:
|
||||
// The script spend path is a bit more involved when doing it
|
||||
// through the PSBT method. We need to specify the leaf hash
|
||||
// that the signer should sign for.
|
||||
leaf := txscript.TapLeaf{
|
||||
LeafVersion: txscript.BaseLeafVersion,
|
||||
Script: signDesc.WitnessScript,
|
||||
}
|
||||
leafHash := leaf.TapHash()
|
||||
|
||||
d := in.Bip32Derivation[0]
|
||||
in.TaprootBip32Derivation = []*psbt.TaprootBip32Derivation{{
|
||||
XOnlyPubKey: d.PubKey[1:],
|
||||
LeafHashes: [][]byte{leafHash[:]},
|
||||
MasterKeyFingerprint: d.MasterKeyFingerprint,
|
||||
Bip32Path: d.Bip32Path,
|
||||
}}
|
||||
|
||||
// We also need to supply a control block. But because we don't
|
||||
// know the internal key nor the merkle proofs (both is not
|
||||
// supplied through the SignOutputRaw RPC) and is technically
|
||||
// not really needed by the signer (since we only want a
|
||||
// signature, the full witness stack is assembled by the caller
|
||||
// of this RPC), we can get by with faking certain information
|
||||
// that we don't have.
|
||||
fakeInternalKey, _ := btcec.ParsePubKey(d.PubKey)
|
||||
fakeKeyIsOdd := d.PubKey[0] == input.PubKeyFormatCompressedOdd
|
||||
controlBlock := txscript.ControlBlock{
|
||||
InternalKey: fakeInternalKey,
|
||||
OutputKeyYIsOdd: fakeKeyIsOdd,
|
||||
LeafVersion: leaf.LeafVersion,
|
||||
}
|
||||
blockBytes, err := controlBlock.ToBytes()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error serializing control "+
|
||||
"block: %v", err)
|
||||
}
|
||||
|
||||
in.TaprootLeafScript = []*psbt.TaprootTapLeafScript{{
|
||||
ControlBlock: blockBytes,
|
||||
Script: leaf.Script,
|
||||
LeafVersion: leaf.LeafVersion,
|
||||
}}
|
||||
}
|
||||
|
||||
// Okay, let's sign the input by the remote signer now.
|
||||
ctxt, cancel := context.WithTimeout(context.Background(), r.rpcTimeout)
|
||||
defer cancel()
|
||||
@@ -996,28 +1105,77 @@ func (r *RPCKeyRing) remoteSign(tx *wire.MsgTx, signDesc *input.SignDescriptor,
|
||||
return nil, fmt.Errorf("remote signer returned invalid PSBT")
|
||||
}
|
||||
in = &signedPacket.Inputs[signDesc.InputIndex]
|
||||
if len(in.PartialSigs) != 1 {
|
||||
return nil, fmt.Errorf("remote signer returned invalid "+
|
||||
"partial signature, wanted 1, got %d",
|
||||
len(in.PartialSigs))
|
||||
}
|
||||
sigWithSigHash := in.PartialSigs[0]
|
||||
if sigWithSigHash == nil {
|
||||
return nil, fmt.Errorf("remote signer returned nil signature")
|
||||
}
|
||||
|
||||
// The remote signer always adds the sighash type, so we need to account
|
||||
// for that.
|
||||
if len(sigWithSigHash.Signature) < ecdsa.MinSigLen+1 {
|
||||
return nil, fmt.Errorf("remote signer returned invalid "+
|
||||
"partial signature: signature too short with %d bytes",
|
||||
len(sigWithSigHash.Signature))
|
||||
}
|
||||
return extractSignature(in, signDesc.SignMethod)
|
||||
}
|
||||
|
||||
// Parse the signature, but chop off the last byte which is the sighash
|
||||
// type.
|
||||
sig := sigWithSigHash.Signature[0 : len(sigWithSigHash.Signature)-1]
|
||||
return ecdsa.ParseDERSignature(sig)
|
||||
// extractSignature attempts to extract the signature from the PSBT input,
|
||||
// looking at different fields depending on the signing method that was used.
|
||||
func extractSignature(in *psbt.PInput,
|
||||
signMethod input.SignMethod) (input.Signature, error) {
|
||||
|
||||
switch signMethod {
|
||||
case input.WitnessV0SignMethod:
|
||||
if len(in.PartialSigs) != 1 {
|
||||
return nil, fmt.Errorf("remote signer returned "+
|
||||
"invalid partial signature, wanted 1, got %d",
|
||||
len(in.PartialSigs))
|
||||
}
|
||||
sigWithSigHash := in.PartialSigs[0]
|
||||
if sigWithSigHash == nil {
|
||||
return nil, fmt.Errorf("remote signer returned nil " +
|
||||
"signature")
|
||||
}
|
||||
|
||||
// The remote signer always adds the sighash type, so we need to
|
||||
// account for that.
|
||||
sigLen := len(sigWithSigHash.Signature)
|
||||
if sigLen < ecdsa.MinSigLen+1 {
|
||||
return nil, fmt.Errorf("remote signer returned "+
|
||||
"invalid partial signature: signature too "+
|
||||
"short with %d bytes", sigLen)
|
||||
}
|
||||
|
||||
// Parse the signature, but chop off the last byte which is the
|
||||
// sighash type.
|
||||
sig := sigWithSigHash.Signature[0 : sigLen-1]
|
||||
return ecdsa.ParseDERSignature(sig)
|
||||
|
||||
// The type of key spend doesn't matter, the signature should be in the
|
||||
// same field for both of those signing methods.
|
||||
case input.TaprootKeySpendBIP0086SignMethod,
|
||||
input.TaprootKeySpendSignMethod:
|
||||
|
||||
sigLen := len(in.TaprootKeySpendSig)
|
||||
if sigLen < schnorr.SignatureSize {
|
||||
return nil, fmt.Errorf("remote signer returned "+
|
||||
"invalid key spend signature: signature too "+
|
||||
"short with %d bytes", sigLen)
|
||||
}
|
||||
|
||||
return schnorr.ParseSignature(
|
||||
in.TaprootKeySpendSig[:schnorr.SignatureSize],
|
||||
)
|
||||
|
||||
case input.TaprootScriptSpendSignMethod:
|
||||
if len(in.TaprootScriptSpendSig) != 1 {
|
||||
return nil, fmt.Errorf("remote signer returned "+
|
||||
"invalid taproot script spend signature, "+
|
||||
"wanted 1, got %d",
|
||||
len(in.TaprootScriptSpendSig))
|
||||
}
|
||||
scriptSpendSig := in.TaprootScriptSpendSig[0]
|
||||
if scriptSpendSig == nil {
|
||||
return nil, fmt.Errorf("remote signer returned nil " +
|
||||
"taproot script spend signature")
|
||||
}
|
||||
|
||||
return schnorr.ParseSignature(scriptSpendSig.Signature)
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("can't extract signature, unsupported "+
|
||||
"signing method: %v", signMethod)
|
||||
}
|
||||
}
|
||||
|
||||
// connectRPC tries to establish an RPC connection to the given host:port with
|
||||
|
||||
Reference in new issue
Block a user