mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-02-23 06:35:07 +01:00
Merge pull request #4213 from carlaKC/txdetails-addlabel
lnrpc: add optional labels to on chain transactions
This commit is contained in:
commit
afc60353a1
34 changed files with 1084 additions and 882 deletions
|
@ -90,7 +90,7 @@ type BreachConfig struct {
|
|||
|
||||
// PublishTransaction facilitates the process of broadcasting a
|
||||
// transaction to the network.
|
||||
PublishTransaction func(*wire.MsgTx) error
|
||||
PublishTransaction func(*wire.MsgTx, string) error
|
||||
|
||||
// ContractBreaches is a channel where the breachArbiter will receive
|
||||
// notifications in the event of a contract breach being observed. A
|
||||
|
@ -566,7 +566,7 @@ justiceTxBroadcast:
|
|||
|
||||
// We'll now attempt to broadcast the transaction which finalized the
|
||||
// channel's retribution against the cheating counter party.
|
||||
err = b.cfg.PublishTransaction(finalTx)
|
||||
err = b.cfg.PublishTransaction(finalTx, "")
|
||||
if err != nil {
|
||||
brarLog.Errorf("Unable to broadcast justice tx: %v", err)
|
||||
|
||||
|
|
|
@ -1371,7 +1371,7 @@ func testBreachSpends(t *testing.T, test breachTest) {
|
|||
|
||||
// Make PublishTransaction always return ErrDoubleSpend to begin with.
|
||||
publErr = lnwallet.ErrDoubleSpend
|
||||
brar.cfg.PublishTransaction = func(tx *wire.MsgTx) error {
|
||||
brar.cfg.PublishTransaction = func(tx *wire.MsgTx, _ string) error {
|
||||
publTx <- tx
|
||||
|
||||
publMtx.Lock()
|
||||
|
@ -1681,7 +1681,7 @@ func createTestArbiter(t *testing.T, contractBreaches chan *ContractBreachEvent,
|
|||
ContractBreaches: contractBreaches,
|
||||
Signer: signer,
|
||||
Notifier: notifier,
|
||||
PublishTransaction: func(_ *wire.MsgTx) error { return nil },
|
||||
PublishTransaction: func(_ *wire.MsgTx, _ string) error { return nil },
|
||||
Store: store,
|
||||
})
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ type chanCloseCfg struct {
|
|||
unregisterChannel func(lnwire.ChannelID)
|
||||
|
||||
// broadcastTx broadcasts the passed transaction to the network.
|
||||
broadcastTx func(*wire.MsgTx) error
|
||||
broadcastTx func(*wire.MsgTx, string) error
|
||||
|
||||
// disableChannel disables a channel, resulting in it not being able to
|
||||
// forward payments.
|
||||
|
@ -544,7 +544,8 @@ func (c *channelCloser) ProcessCloseMsg(msg lnwire.Message) ([]lnwire.Message, b
|
|||
newLogClosure(func() string {
|
||||
return spew.Sdump(closeTx)
|
||||
}))
|
||||
if err := c.cfg.broadcastTx(closeTx); err != nil {
|
||||
err = c.cfg.broadcastTx(closeTx, "")
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
|
|
|
@ -194,6 +194,11 @@ func estimateFees(ctx *cli.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
var txLabelFlag = cli.StringFlag{
|
||||
Name: "label",
|
||||
Usage: "(optional) a label for the transaction",
|
||||
}
|
||||
|
||||
var sendCoinsCommand = cli.Command{
|
||||
Name: "sendcoins",
|
||||
Category: "On-chain",
|
||||
|
@ -236,6 +241,7 @@ var sendCoinsCommand = cli.Command{
|
|||
"sat/byte that should be used when crafting " +
|
||||
"the transaction",
|
||||
},
|
||||
txLabelFlag,
|
||||
},
|
||||
Action: actionDecorator(sendCoins),
|
||||
}
|
||||
|
@ -295,6 +301,7 @@ func sendCoins(ctx *cli.Context) error {
|
|||
TargetConf: int32(ctx.Int64("conf_target")),
|
||||
SatPerByte: ctx.Int64("sat_per_byte"),
|
||||
SendAll: ctx.Bool("sweepall"),
|
||||
Label: ctx.String(txLabelFlag.Name),
|
||||
}
|
||||
txid, err := client.SendCoins(ctxb, req)
|
||||
if err != nil {
|
||||
|
@ -450,6 +457,7 @@ var sendManyCommand = cli.Command{
|
|||
Usage: "(optional) a manual fee expressed in sat/byte that should be " +
|
||||
"used when crafting the transaction",
|
||||
},
|
||||
txLabelFlag,
|
||||
},
|
||||
Action: actionDecorator(sendMany),
|
||||
}
|
||||
|
@ -475,6 +483,7 @@ func sendMany(ctx *cli.Context) error {
|
|||
AddrToAmount: amountToAddr,
|
||||
TargetConf: int32(ctx.Int64("conf_target")),
|
||||
SatPerByte: ctx.Int64("sat_per_byte"),
|
||||
Label: ctx.String(txLabelFlag.Name),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -79,7 +79,7 @@ type ChainArbitratorConfig struct {
|
|||
// PublishTx reliably broadcasts a transaction to the network. Once
|
||||
// this function exits without an error, then they transaction MUST
|
||||
// continually be rebroadcast if needed.
|
||||
PublishTx func(*wire.MsgTx) error
|
||||
PublishTx func(*wire.MsgTx, string) error
|
||||
|
||||
// DeliverResolutionMsg is a function that will append an outgoing
|
||||
// message to the "out box" for a ChannelLink. This is used to cancel
|
||||
|
@ -699,7 +699,7 @@ func (c *ChainArbitrator) rebroadcast(channel *channeldb.OpenChannel,
|
|||
log.Infof("Re-publishing %s close tx(%v) for channel %v",
|
||||
kind, closeTx.TxHash(), chanPoint)
|
||||
|
||||
err = c.cfg.PublishTx(closeTx)
|
||||
err = c.cfg.PublishTx(closeTx, "")
|
||||
if err != nil && err != lnwallet.ErrDoubleSpend {
|
||||
log.Warnf("Unable to broadcast %s close tx(%v): %v",
|
||||
kind, closeTx.TxHash(), err)
|
||||
|
|
|
@ -82,7 +82,7 @@ func TestChainArbitratorRepublishCloses(t *testing.T) {
|
|||
chainArbCfg := ChainArbitratorConfig{
|
||||
ChainIO: &mockChainIO{},
|
||||
Notifier: &mockNotifier{},
|
||||
PublishTx: func(tx *wire.MsgTx) error {
|
||||
PublishTx: func(tx *wire.MsgTx, _ string) error {
|
||||
published[tx.TxHash()]++
|
||||
return nil
|
||||
},
|
||||
|
@ -174,7 +174,7 @@ func TestResolveContract(t *testing.T) {
|
|||
chainArbCfg := ChainArbitratorConfig{
|
||||
ChainIO: &mockChainIO{},
|
||||
Notifier: &mockNotifier{},
|
||||
PublishTx: func(tx *wire.MsgTx) error {
|
||||
PublishTx: func(tx *wire.MsgTx, _ string) error {
|
||||
return nil
|
||||
},
|
||||
Clock: clock.NewDefaultClock(),
|
||||
|
|
|
@ -851,7 +851,7 @@ func (c *ChannelArbitrator) stateStep(
|
|||
|
||||
// At this point, we'll now broadcast the commitment
|
||||
// transaction itself.
|
||||
if err := c.cfg.PublishTx(closeTx); err != nil {
|
||||
if err := c.cfg.PublishTx(closeTx, ""); err != nil {
|
||||
log.Errorf("ChannelArbitrator(%v): unable to broadcast "+
|
||||
"close tx: %v", c.cfg.ChanPoint, err)
|
||||
if err != lnwallet.ErrDoubleSpend {
|
||||
|
|
|
@ -324,7 +324,7 @@ func createTestChannelArbitrator(t *testing.T, log ArbitratorLog,
|
|||
mockSweeper := newMockSweeper()
|
||||
chainArbCfg := ChainArbitratorConfig{
|
||||
ChainIO: chainIO,
|
||||
PublishTx: func(*wire.MsgTx) error {
|
||||
PublishTx: func(*wire.MsgTx, string) error {
|
||||
return nil
|
||||
},
|
||||
DeliverResolutionMsg: func(msgs ...ResolutionMsg) error {
|
||||
|
@ -575,7 +575,7 @@ func TestChannelArbitratorLocalForceClose(t *testing.T) {
|
|||
// We create a channel we can use to pause the ChannelArbitrator at the
|
||||
// point where it broadcasts the close tx, and check its state.
|
||||
stateChan := make(chan ArbitratorState)
|
||||
chanArb.cfg.PublishTx = func(*wire.MsgTx) error {
|
||||
chanArb.cfg.PublishTx = func(*wire.MsgTx, string) error {
|
||||
// When the force close tx is being broadcasted, check that the
|
||||
// state is correct at that point.
|
||||
select {
|
||||
|
@ -998,7 +998,7 @@ func TestChannelArbitratorLocalForceCloseRemoteConfirmed(t *testing.T) {
|
|||
// Create a channel we can use to assert the state when it publishes
|
||||
// the close tx.
|
||||
stateChan := make(chan ArbitratorState)
|
||||
chanArb.cfg.PublishTx = func(*wire.MsgTx) error {
|
||||
chanArb.cfg.PublishTx = func(*wire.MsgTx, string) error {
|
||||
// When the force close tx is being broadcasted, check that the
|
||||
// state is correct at that point.
|
||||
select {
|
||||
|
@ -1106,7 +1106,7 @@ func TestChannelArbitratorLocalForceDoubleSpend(t *testing.T) {
|
|||
|
||||
// Return ErrDoubleSpend when attempting to publish the tx.
|
||||
stateChan := make(chan ArbitratorState)
|
||||
chanArb.cfg.PublishTx = func(*wire.MsgTx) error {
|
||||
chanArb.cfg.PublishTx = func(*wire.MsgTx, string) error {
|
||||
// When the force close tx is being broadcasted, check that the
|
||||
// state is correct at that point.
|
||||
select {
|
||||
|
@ -1339,7 +1339,7 @@ func TestChannelArbitratorForceCloseBreachedChannel(t *testing.T) {
|
|||
// unexpected publication error, causing the state machine to halt.
|
||||
expErr := errors.New("intentional publication error")
|
||||
stateChan := make(chan ArbitratorState)
|
||||
chanArb.cfg.PublishTx = func(*wire.MsgTx) error {
|
||||
chanArb.cfg.PublishTx = func(*wire.MsgTx, string) error {
|
||||
// When the force close tx is being broadcasted, check that the
|
||||
// state is correct at that point.
|
||||
select {
|
||||
|
|
|
@ -155,7 +155,7 @@ func (h *htlcSuccessResolver) Resolve() (ContractResolver, error) {
|
|||
// Regardless of whether an existing transaction was found or newly
|
||||
// constructed, we'll broadcast the sweep transaction to the
|
||||
// network.
|
||||
err := h.PublishTx(h.sweepTx)
|
||||
err := h.PublishTx(h.sweepTx, "")
|
||||
if err != nil {
|
||||
log.Infof("%T(%x): unable to publish tx: %v",
|
||||
h, h.htlc.RHash[:], err)
|
||||
|
@ -199,7 +199,7 @@ func (h *htlcSuccessResolver) Resolve() (ContractResolver, error) {
|
|||
// the claiming process.
|
||||
//
|
||||
// TODO(roasbeef): after changing sighashes send to tx bundler
|
||||
err := h.PublishTx(h.htlcResolution.SignedSuccessTx)
|
||||
err := h.PublishTx(h.htlcResolution.SignedSuccessTx, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -236,7 +236,7 @@ type fundingConfig struct {
|
|||
|
||||
// PublishTransaction facilitates the process of broadcasting a
|
||||
// transaction to the network.
|
||||
PublishTransaction func(*wire.MsgTx) error
|
||||
PublishTransaction func(*wire.MsgTx, string) error
|
||||
|
||||
// FeeEstimator calculates appropriate fee rates based on historical
|
||||
// transaction information.
|
||||
|
@ -553,7 +553,7 @@ func (f *fundingManager) start() error {
|
|||
channel.IsInitiator {
|
||||
|
||||
err := f.cfg.PublishTransaction(
|
||||
channel.FundingTxn,
|
||||
channel.FundingTxn, "",
|
||||
)
|
||||
if err != nil {
|
||||
fndgLog.Errorf("Unable to rebroadcast "+
|
||||
|
@ -1995,7 +1995,7 @@ func (f *fundingManager) handleFundingSigned(fmsg *fundingSignedMsg) {
|
|||
fndgLog.Infof("Broadcasting funding tx for ChannelPoint(%v): %v",
|
||||
completeChan.FundingOutpoint, spew.Sdump(fundingTx))
|
||||
|
||||
err = f.cfg.PublishTransaction(fundingTx)
|
||||
err = f.cfg.PublishTransaction(fundingTx, "")
|
||||
if err != nil {
|
||||
fndgLog.Errorf("Unable to broadcast funding tx for "+
|
||||
"ChannelPoint(%v): %v",
|
||||
|
|
|
@ -412,7 +412,7 @@ func createTestFundingManager(t *testing.T, privKey *btcec.PrivateKey,
|
|||
ReportShortChanID: func(wire.OutPoint) error {
|
||||
return nil
|
||||
},
|
||||
PublishTransaction: func(txn *wire.MsgTx) error {
|
||||
PublishTransaction: func(txn *wire.MsgTx, _ string) error {
|
||||
publTxChan <- txn
|
||||
return nil
|
||||
},
|
||||
|
@ -515,7 +515,7 @@ func recreateAliceFundingManager(t *testing.T, alice *testNode) {
|
|||
},
|
||||
DefaultMinHtlcIn: 5,
|
||||
RequiredRemoteMaxValue: oldCfg.RequiredRemoteMaxValue,
|
||||
PublishTransaction: func(txn *wire.MsgTx) error {
|
||||
PublishTransaction: func(txn *wire.MsgTx, _ string) error {
|
||||
publishChan <- txn
|
||||
return nil
|
||||
},
|
||||
|
|
33
labels/labels.go
Normal file
33
labels/labels.go
Normal file
|
@ -0,0 +1,33 @@
|
|||
// Package labels contains labels used to label transactions broadcast by lnd.
|
||||
// These labels are used across packages, so they are declared in a separate
|
||||
// package to avoid dependency issues.
|
||||
package labels
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/btcsuite/btcwallet/wtxmgr"
|
||||
)
|
||||
|
||||
// External labels a transaction as user initiated via the api. This
|
||||
// label is only used when a custom user provided label is not given.
|
||||
const External = "external"
|
||||
|
||||
// ValidateAPI returns the generic api label if the label provided is empty.
|
||||
// This allows us to label all transactions published by the api, even if
|
||||
// no label is provided. If a label is provided, it is validated against
|
||||
// the known restrictions.
|
||||
func ValidateAPI(label string) (string, error) {
|
||||
if len(label) > wtxmgr.TxLabelLimit {
|
||||
return "", fmt.Errorf("label length: %v exceeds "+
|
||||
"limit of %v", len(label), wtxmgr.TxLabelLimit)
|
||||
}
|
||||
|
||||
// If no label was provided by the user, add the generic user
|
||||
// send label.
|
||||
if len(label) == 0 {
|
||||
return External, nil
|
||||
}
|
||||
|
||||
return label, nil
|
||||
}
|
1497
lnrpc/rpc.pb.go
1497
lnrpc/rpc.pb.go
File diff suppressed because it is too large
Load diff
|
@ -708,6 +708,9 @@ message Transaction {
|
|||
|
||||
// The raw transaction hex.
|
||||
string raw_tx_hex = 9;
|
||||
|
||||
// A label that was optionally set on transaction broadcast.
|
||||
string label = 10;
|
||||
}
|
||||
message GetTransactionsRequest {
|
||||
/*
|
||||
|
@ -1002,6 +1005,9 @@ message SendManyRequest {
|
|||
// A manual fee rate set in sat/byte that should be used when crafting the
|
||||
// transaction.
|
||||
int64 sat_per_byte = 5;
|
||||
|
||||
// An optional label for the transaction, limited to 500 characters.
|
||||
string label = 6;
|
||||
}
|
||||
message SendManyResponse {
|
||||
// The id of the transaction
|
||||
|
@ -1029,6 +1035,9 @@ message SendCoinsRequest {
|
|||
address.
|
||||
*/
|
||||
bool send_all = 6;
|
||||
|
||||
// An optional label for the transaction, limited to 500 characters.
|
||||
string label = 7;
|
||||
}
|
||||
message SendCoinsResponse {
|
||||
// The transaction ID of the transaction
|
||||
|
|
|
@ -4230,6 +4230,10 @@
|
|||
"type": "boolean",
|
||||
"format": "boolean",
|
||||
"description": "If set, then the amount field will be ignored, and lnd will attempt to\nsend all the coins under control of the internal wallet to the specified\naddress."
|
||||
},
|
||||
"label": {
|
||||
"type": "string",
|
||||
"description": "An optional label for the transaction, limited to 500 characters."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -4451,6 +4455,10 @@
|
|||
"raw_tx_hex": {
|
||||
"type": "string",
|
||||
"description": "The raw transaction hex."
|
||||
},
|
||||
"label": {
|
||||
"type": "string",
|
||||
"description": "A label that was optionally set on transaction broadcast."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -36,6 +36,7 @@ func RPCTransactionDetails(txns []*lnwallet.TransactionDetail) *TransactionDetai
|
|||
TotalFees: tx.TotalFees,
|
||||
DestAddresses: destAddresses,
|
||||
RawTxHex: hex.EncodeToString(tx.RawTx),
|
||||
Label: tx.Label,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -261,7 +261,10 @@ func (m *AddrResponse) GetAddr() string {
|
|||
type Transaction struct {
|
||||
//
|
||||
//The raw serialized transaction.
|
||||
TxHex []byte `protobuf:"bytes,1,opt,name=tx_hex,json=txHex,proto3" json:"tx_hex,omitempty"`
|
||||
TxHex []byte `protobuf:"bytes,1,opt,name=tx_hex,json=txHex,proto3" json:"tx_hex,omitempty"`
|
||||
//
|
||||
//An optional label to save with the transaction. Limited to 500 characters.
|
||||
Label string `protobuf:"bytes,2,opt,name=label,proto3" json:"label,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
|
@ -299,6 +302,13 @@ func (m *Transaction) GetTxHex() []byte {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *Transaction) GetLabel() string {
|
||||
if m != nil {
|
||||
return m.Label
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type PublishResponse struct {
|
||||
//
|
||||
//If blank, then no error occurred and the transaction was successfully
|
||||
|
@ -351,10 +361,12 @@ type SendOutputsRequest struct {
|
|||
SatPerKw int64 `protobuf:"varint,1,opt,name=sat_per_kw,json=satPerKw,proto3" json:"sat_per_kw,omitempty"`
|
||||
//
|
||||
//A slice of the outputs that should be created in the transaction produced.
|
||||
Outputs []*signrpc.TxOut `protobuf:"bytes,2,rep,name=outputs,proto3" json:"outputs,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
Outputs []*signrpc.TxOut `protobuf:"bytes,2,rep,name=outputs,proto3" json:"outputs,omitempty"`
|
||||
// An optional label for the transaction, limited to 500 characters.
|
||||
Label string `protobuf:"bytes,3,opt,name=label,proto3" json:"label,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *SendOutputsRequest) Reset() { *m = SendOutputsRequest{} }
|
||||
|
@ -396,6 +408,13 @@ func (m *SendOutputsRequest) GetOutputs() []*signrpc.TxOut {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *SendOutputsRequest) GetLabel() string {
|
||||
if m != nil {
|
||||
return m.Label
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type SendOutputsResponse struct {
|
||||
//
|
||||
//The serialized transaction sent out on the network.
|
||||
|
@ -1002,81 +1021,82 @@ func init() {
|
|||
func init() { proto.RegisterFile("walletrpc/walletkit.proto", fileDescriptor_6cc6942ac78249e5) }
|
||||
|
||||
var fileDescriptor_6cc6942ac78249e5 = []byte{
|
||||
// 1178 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0x6d, 0x6f, 0xe2, 0x46,
|
||||
0x10, 0x3e, 0x42, 0x42, 0x60, 0x78, 0x09, 0x59, 0xf2, 0xe2, 0xe3, 0x72, 0x0d, 0x75, 0xdf, 0xa2,
|
||||
0xf6, 0x8e, 0xa8, 0x39, 0xb5, 0xea, 0xb5, 0x52, 0xd5, 0x04, 0x1c, 0x11, 0x41, 0x70, 0x6a, 0xfb,
|
||||
0x2e, 0xba, 0xaa, 0xd2, 0xca, 0xe0, 0x0d, 0xb1, 0x02, 0xb6, 0x6f, 0xbd, 0x1c, 0xf0, 0xad, 0x5f,
|
||||
0xfa, 0x17, 0x2a, 0xdd, 0xbf, 0xad, 0xbc, 0x7e, 0x61, 0x0d, 0xcd, 0x49, 0xfd, 0x14, 0x76, 0x9e,
|
||||
0x67, 0x9e, 0x9d, 0x9d, 0x19, 0xcf, 0x04, 0x9e, 0xce, 0xcc, 0xf1, 0x98, 0x30, 0xea, 0x0d, 0x4f,
|
||||
0xc3, 0x5f, 0x0f, 0x36, 0x6b, 0x7a, 0xd4, 0x65, 0x2e, 0x2a, 0x24, 0x50, 0xbd, 0x40, 0xbd, 0x61,
|
||||
0x68, 0xad, 0xef, 0xf9, 0xf6, 0xc8, 0x09, 0xe8, 0xc1, 0x5f, 0x42, 0x43, 0xab, 0xfc, 0x3b, 0xe4,
|
||||
0xba, 0x64, 0xa1, 0x91, 0xf7, 0xe8, 0x04, 0xaa, 0x0f, 0x64, 0x81, 0xef, 0x6c, 0x67, 0x44, 0x28,
|
||||
0xf6, 0xa8, 0xed, 0x30, 0x29, 0xd3, 0xc8, 0x9c, 0x6c, 0x69, 0x95, 0x07, 0xb2, 0xb8, 0xe4, 0xe6,
|
||||
0x9b, 0xc0, 0x8a, 0x9e, 0x03, 0x70, 0xa6, 0x39, 0xb1, 0xc7, 0x0b, 0x69, 0x83, 0x73, 0x0a, 0x01,
|
||||
0x87, 0x1b, 0xe4, 0x32, 0x14, 0xcf, 0x2d, 0x8b, 0x6a, 0xe4, 0xfd, 0x94, 0xf8, 0x4c, 0x96, 0xa1,
|
||||
0x14, 0x1e, 0x7d, 0xcf, 0x75, 0x7c, 0x82, 0x10, 0x6c, 0x9a, 0x96, 0x45, 0xb9, 0x76, 0x41, 0xe3,
|
||||
0xbf, 0xe5, 0x2f, 0xa1, 0x68, 0x50, 0xd3, 0xf1, 0xcd, 0x21, 0xb3, 0x5d, 0x07, 0xed, 0x43, 0x8e,
|
||||
0xcd, 0xf1, 0x3d, 0x99, 0x73, 0x52, 0x49, 0xdb, 0x62, 0xf3, 0x0e, 0x99, 0xcb, 0x3f, 0xc2, 0xce,
|
||||
0xcd, 0x74, 0x30, 0xb6, 0xfd, 0xfb, 0x44, 0xec, 0x0b, 0x28, 0x7b, 0xa1, 0x09, 0x13, 0x4a, 0xdd,
|
||||
0x58, 0xb5, 0x14, 0x19, 0x95, 0xc0, 0x26, 0xff, 0x09, 0x48, 0x27, 0x8e, 0xa5, 0x4e, 0x99, 0x37,
|
||||
0x65, 0x7e, 0x14, 0x17, 0x3a, 0x02, 0xf0, 0x4d, 0x86, 0x3d, 0x42, 0xf1, 0xc3, 0x8c, 0xfb, 0x65,
|
||||
0xb5, 0xbc, 0x6f, 0xb2, 0x1b, 0x42, 0xbb, 0x33, 0x74, 0x02, 0xdb, 0x6e, 0xc8, 0x97, 0x36, 0x1a,
|
||||
0xd9, 0x93, 0xe2, 0x59, 0xa5, 0x19, 0xe5, 0xaf, 0x69, 0xcc, 0xd5, 0x29, 0xd3, 0x62, 0x58, 0x7e,
|
||||
0x01, 0xb5, 0x94, 0x7a, 0x14, 0xd9, 0x3e, 0xe4, 0xa8, 0x39, 0xc3, 0x2c, 0x79, 0x03, 0x35, 0x67,
|
||||
0xc6, 0x5c, 0xfe, 0x01, 0x90, 0xe2, 0x33, 0x7b, 0x62, 0x32, 0x72, 0x49, 0x48, 0x1c, 0xcb, 0x31,
|
||||
0x14, 0x87, 0xae, 0x73, 0x87, 0x99, 0x49, 0x47, 0x24, 0x4e, 0x3b, 0x04, 0x26, 0x83, 0x5b, 0xe4,
|
||||
0x57, 0x50, 0x4b, 0xb9, 0x45, 0x97, 0x7c, 0xf2, 0x0d, 0xf2, 0xc7, 0x2c, 0x94, 0x6e, 0x88, 0x63,
|
||||
0xd9, 0xce, 0x48, 0x9f, 0x11, 0xe2, 0xa1, 0xef, 0x20, 0x1f, 0x44, 0xed, 0xc6, 0xa5, 0x2d, 0x9e,
|
||||
0xed, 0x34, 0xc7, 0xfc, 0x4d, 0xea, 0x94, 0xdd, 0x04, 0x66, 0x2d, 0x21, 0xa0, 0xd7, 0x50, 0x9a,
|
||||
0xd9, 0xcc, 0x21, 0xbe, 0x8f, 0xd9, 0xc2, 0x23, 0xbc, 0xce, 0x95, 0xb3, 0x83, 0x66, 0xd2, 0x5c,
|
||||
0xcd, 0xdb, 0x10, 0x36, 0x16, 0x1e, 0xd1, 0x8a, 0xb3, 0xe5, 0x21, 0x68, 0x10, 0x73, 0xe2, 0x4e,
|
||||
0x1d, 0x86, 0x7d, 0x93, 0x49, 0xd9, 0x46, 0xe6, 0xa4, 0xac, 0x15, 0x42, 0x8b, 0x6e, 0x32, 0xd4,
|
||||
0x80, 0x52, 0x1c, 0xf5, 0x60, 0xc1, 0x88, 0xb4, 0xc9, 0x09, 0x10, 0xc6, 0x7d, 0xb1, 0x60, 0x04,
|
||||
0xbd, 0x04, 0x34, 0xa0, 0xae, 0x69, 0x0d, 0x4d, 0x9f, 0x61, 0x93, 0x31, 0x32, 0xf1, 0x98, 0x2f,
|
||||
0x6d, 0x71, 0xde, 0x6e, 0x82, 0x9c, 0x47, 0x00, 0x3a, 0x83, 0x7d, 0x87, 0xcc, 0x19, 0x5e, 0xfa,
|
||||
0xdc, 0x13, 0x7b, 0x74, 0xcf, 0xa4, 0x1c, 0xf7, 0xa8, 0x05, 0xe0, 0x45, 0x8c, 0x75, 0x38, 0x14,
|
||||
0xf8, 0xd0, 0x30, 0xfb, 0xc4, 0xc2, 0x62, 0xf2, 0xf3, 0xa1, 0x4f, 0x02, 0xb6, 0x92, 0x2a, 0xa0,
|
||||
0x57, 0x70, 0xb0, 0xf4, 0x49, 0x3d, 0xa1, 0xb0, 0xe2, 0xa4, 0x2f, 0xdf, 0xb2, 0x07, 0x5b, 0x77,
|
||||
0x2e, 0x1d, 0x12, 0x69, 0xbb, 0x91, 0x39, 0xc9, 0x6b, 0xe1, 0x41, 0x3e, 0x80, 0x3d, 0xb1, 0x34,
|
||||
0x71, 0x57, 0xca, 0xb7, 0xb0, 0xbf, 0x62, 0x8f, 0x4a, 0xfd, 0x2b, 0x54, 0xbc, 0x10, 0xc0, 0x3e,
|
||||
0x47, 0xa4, 0x0c, 0xef, 0xcb, 0x43, 0xa1, 0x20, 0xa2, 0xa7, 0x56, 0xf6, 0x44, 0x1d, 0xf9, 0x9f,
|
||||
0x0c, 0x54, 0x2e, 0xa6, 0x13, 0x4f, 0xe8, 0xba, 0xff, 0xd5, 0x0e, 0xc7, 0x50, 0x0c, 0x13, 0xc4,
|
||||
0x93, 0xc5, 0xbb, 0xa1, 0xac, 0x41, 0x68, 0x0a, 0x52, 0xb4, 0x56, 0xd5, 0xec, 0x5a, 0x55, 0x93,
|
||||
0x4c, 0x6c, 0x8a, 0x99, 0xd8, 0x85, 0x9d, 0x24, 0xae, 0xf0, 0xad, 0xf2, 0x4b, 0xd8, 0xed, 0xd9,
|
||||
0x3e, 0x4b, 0x65, 0x06, 0x49, 0xb0, 0xfd, 0x81, 0xd0, 0x81, 0xeb, 0x13, 0x1e, 0x6c, 0x5e, 0x8b,
|
||||
0x8f, 0xf2, 0x5f, 0x1b, 0x80, 0x44, 0x7e, 0x94, 0xb1, 0x1e, 0xd4, 0xd8, 0x72, 0xa8, 0x60, 0x8b,
|
||||
0x30, 0xd3, 0x1e, 0xfb, 0xd1, 0x4b, 0x9f, 0x46, 0x2f, 0x15, 0xc6, 0x4e, 0x3b, 0x24, 0x74, 0x9e,
|
||||
0x68, 0x88, 0xad, 0x59, 0xd1, 0x2d, 0xec, 0x88, 0x6a, 0xb6, 0xe5, 0xf3, 0x1c, 0x14, 0xcf, 0x5e,
|
||||
0x08, 0x05, 0x58, 0x8f, 0x42, 0xbc, 0xe0, 0xaa, 0x1d, 0x88, 0x57, 0x04, 0x99, 0x2b, 0xcb, 0xaf,
|
||||
0xbf, 0x86, 0x4a, 0x9a, 0x83, 0xbe, 0x59, 0xbf, 0x2a, 0xa8, 0x75, 0x61, 0xd5, 0xf5, 0x22, 0x0f,
|
||||
0xb9, 0xb0, 0x17, 0xbe, 0xfd, 0x98, 0x85, 0xa2, 0xf0, 0x39, 0xa2, 0x1a, 0xec, 0xbc, 0xe9, 0x77,
|
||||
0xfb, 0xea, 0x6d, 0x1f, 0xdf, 0x5e, 0x19, 0x7d, 0x45, 0xd7, 0xab, 0x4f, 0x90, 0x04, 0x7b, 0x2d,
|
||||
0xf5, 0xfa, 0xfa, 0xca, 0xb8, 0x56, 0xfa, 0x06, 0x36, 0xae, 0xae, 0x15, 0xdc, 0x53, 0x5b, 0xdd,
|
||||
0x6a, 0x06, 0x1d, 0x42, 0x4d, 0x40, 0xfa, 0x2a, 0x6e, 0x2b, 0xbd, 0xf3, 0x77, 0xd5, 0x0d, 0xb4,
|
||||
0x0f, 0xbb, 0x02, 0xa0, 0x29, 0x6f, 0xd5, 0xae, 0x52, 0xcd, 0x06, 0xfc, 0x8e, 0xd1, 0x6b, 0x61,
|
||||
0xf5, 0xf2, 0x52, 0xd1, 0x94, 0x76, 0x0c, 0x6c, 0x06, 0x57, 0x70, 0xe0, 0xbc, 0xd5, 0x52, 0x6e,
|
||||
0x8c, 0x25, 0xb2, 0x85, 0xbe, 0x82, 0xcf, 0x53, 0x2e, 0xc1, 0xf5, 0xea, 0x1b, 0x03, 0xeb, 0x4a,
|
||||
0x4b, 0xed, 0xb7, 0x71, 0x4f, 0x79, 0xab, 0xf4, 0xaa, 0x39, 0xf4, 0x35, 0xc8, 0x69, 0x01, 0xfd,
|
||||
0x4d, 0xab, 0xa5, 0xe8, 0x7a, 0x9a, 0xb7, 0x8d, 0x8e, 0xe1, 0xd9, 0x4a, 0x04, 0xd7, 0xaa, 0xa1,
|
||||
0xc4, 0xaa, 0xd5, 0x3c, 0x6a, 0xc0, 0xd1, 0x6a, 0x24, 0x9c, 0x11, 0xe9, 0x55, 0x0b, 0xe8, 0x08,
|
||||
0x24, 0xce, 0x10, 0x95, 0xe3, 0x78, 0x01, 0xed, 0x41, 0x35, 0xca, 0x1c, 0xee, 0x2a, 0xef, 0x70,
|
||||
0xe7, 0x5c, 0xef, 0x54, 0x8b, 0xe8, 0x19, 0x1c, 0xf6, 0x15, 0x3d, 0x90, 0x5b, 0x03, 0x4b, 0x2b,
|
||||
0xc9, 0x3a, 0xef, 0xb7, 0x3a, 0xaa, 0x56, 0x2d, 0x9f, 0xfd, 0xbd, 0x05, 0x85, 0x5b, 0xde, 0x22,
|
||||
0x5d, 0x9b, 0xa1, 0x9f, 0xa1, 0xdc, 0x26, 0xd4, 0xfe, 0x40, 0xfa, 0x64, 0xce, 0xba, 0x64, 0x81,
|
||||
0x76, 0x85, 0xfe, 0x09, 0x57, 0x71, 0xfd, 0x20, 0xd9, 0x35, 0x5d, 0xb2, 0x68, 0x13, 0x7f, 0x48,
|
||||
0x6d, 0x8f, 0xb9, 0x14, 0xfd, 0x04, 0x85, 0xd0, 0x37, 0xf0, 0xab, 0x89, 0xa4, 0x9e, 0x3b, 0x34,
|
||||
0x99, 0x4b, 0x1f, 0xf5, 0xfc, 0x05, 0xf2, 0xc1, 0x7d, 0xc1, 0x22, 0x46, 0xe2, 0x08, 0x17, 0x16,
|
||||
0x75, 0xfd, 0x70, 0xcd, 0x1e, 0x7d, 0x48, 0x1d, 0x40, 0xd1, 0xde, 0x15, 0x97, 0xb4, 0x28, 0x23,
|
||||
0xd8, 0xeb, 0x75, 0x71, 0x20, 0xad, 0xac, 0xeb, 0x1e, 0x14, 0x85, 0x5d, 0x89, 0x9e, 0x0b, 0xd4,
|
||||
0xf5, 0x0d, 0x5d, 0xff, 0xec, 0x31, 0x78, 0xa9, 0x26, 0x2c, 0xc5, 0x94, 0xda, 0xfa, 0x8e, 0x4d,
|
||||
0xa9, 0xfd, 0xd7, 0x2e, 0xd5, 0xa0, 0x9c, 0x9a, 0xbc, 0xe8, 0xf8, 0x91, 0xc9, 0x9a, 0xc4, 0xd7,
|
||||
0x78, 0x9c, 0x10, 0x69, 0xfe, 0x06, 0xdb, 0xd1, 0x6c, 0x43, 0x4f, 0x05, 0x72, 0x7a, 0x0e, 0xa7,
|
||||
0x32, 0xb6, 0x32, 0x0a, 0xd1, 0x15, 0xc0, 0x72, 0xa8, 0xa0, 0xa3, 0x47, 0x66, 0x4d, 0xa8, 0xf3,
|
||||
0xfc, 0x93, 0x93, 0xe8, 0xe2, 0xfb, 0x3f, 0x4e, 0x47, 0x36, 0xbb, 0x9f, 0x0e, 0x9a, 0x43, 0x77,
|
||||
0x72, 0x3a, 0x0e, 0xb6, 0xa0, 0x63, 0x3b, 0x23, 0x87, 0xb0, 0x99, 0x4b, 0x1f, 0x4e, 0xc7, 0x8e,
|
||||
0x75, 0xca, 0x67, 0xe2, 0x69, 0xa2, 0x32, 0xc8, 0xf1, 0x7f, 0x12, 0x5f, 0xfd, 0x1b, 0x00, 0x00,
|
||||
0xff, 0xff, 0x88, 0x6c, 0x32, 0x8c, 0x6d, 0x0a, 0x00, 0x00,
|
||||
// 1190 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x56, 0x6d, 0x6f, 0xda, 0xd6,
|
||||
0x17, 0x6f, 0x42, 0x20, 0x70, 0x78, 0x08, 0xb9, 0xe4, 0x81, 0xd2, 0xf4, 0x9f, 0xfc, 0x3d, 0x6d,
|
||||
0x8b, 0xb6, 0x96, 0x68, 0xa9, 0x36, 0xad, 0x9d, 0x34, 0x8d, 0x80, 0x23, 0x10, 0x04, 0x33, 0xdb,
|
||||
0x2d, 0xea, 0xde, 0x5c, 0x19, 0x7c, 0x4b, 0xac, 0x80, 0xed, 0x5e, 0x5f, 0x0a, 0xbc, 0xdb, 0x9b,
|
||||
0x7d, 0x85, 0x49, 0xfd, 0xb6, 0x93, 0xaf, 0x1f, 0xb8, 0x86, 0xa5, 0xd2, 0x5e, 0x85, 0x7b, 0x7e,
|
||||
0xbf, 0xf3, 0x7c, 0x7c, 0x4e, 0xe0, 0xe9, 0xc2, 0x98, 0x4e, 0x09, 0xa3, 0xee, 0xf8, 0x2a, 0xf8,
|
||||
0xf5, 0x60, 0xb1, 0xba, 0x4b, 0x1d, 0xe6, 0xa0, 0x5c, 0x0c, 0xd5, 0x72, 0xd4, 0x1d, 0x07, 0xd2,
|
||||
0xda, 0x91, 0x67, 0x4d, 0x6c, 0x9f, 0xee, 0xff, 0x25, 0x34, 0x90, 0x4a, 0xbf, 0x43, 0xa6, 0x4b,
|
||||
0x56, 0x2a, 0xf9, 0x88, 0x2e, 0xa1, 0xfc, 0x40, 0x56, 0xf8, 0x83, 0x65, 0x4f, 0x08, 0xc5, 0x2e,
|
||||
0xb5, 0x6c, 0x56, 0xdd, 0xb9, 0xd8, 0xb9, 0x4c, 0xab, 0xa5, 0x07, 0xb2, 0xba, 0xe5, 0xe2, 0x81,
|
||||
0x2f, 0x45, 0xcf, 0x01, 0x38, 0xd3, 0x98, 0x59, 0xd3, 0x55, 0x75, 0x97, 0x73, 0x72, 0x3e, 0x87,
|
||||
0x0b, 0xa4, 0x22, 0xe4, 0x1b, 0xa6, 0x49, 0x55, 0xf2, 0x71, 0x4e, 0x3c, 0x26, 0x49, 0x50, 0x08,
|
||||
0x9e, 0x9e, 0xeb, 0xd8, 0x1e, 0x41, 0x08, 0xf6, 0x0c, 0xd3, 0xa4, 0xdc, 0x76, 0x4e, 0xe5, 0xbf,
|
||||
0xa5, 0x37, 0x90, 0xd7, 0xa9, 0x61, 0x7b, 0xc6, 0x98, 0x59, 0x8e, 0x8d, 0x8e, 0x21, 0xc3, 0x96,
|
||||
0xf8, 0x9e, 0x2c, 0x39, 0xa9, 0xa0, 0xa6, 0xd9, 0xb2, 0x4d, 0x96, 0xe8, 0x08, 0xd2, 0x53, 0x63,
|
||||
0x44, 0xa6, 0xdc, 0x65, 0x4e, 0x0d, 0x1e, 0xd2, 0x4f, 0x70, 0x30, 0x98, 0x8f, 0xa6, 0x96, 0x77,
|
||||
0x1f, 0xbb, 0xf8, 0x0a, 0x8a, 0x6e, 0x20, 0xc2, 0x84, 0x52, 0x27, 0xf2, 0x55, 0x08, 0x85, 0xb2,
|
||||
0x2f, 0x93, 0x28, 0x20, 0x8d, 0xd8, 0xa6, 0x32, 0x67, 0xee, 0x9c, 0x79, 0x61, 0xb4, 0xe8, 0x0c,
|
||||
0xc0, 0x33, 0x18, 0x76, 0x09, 0xc5, 0x0f, 0x0b, 0xae, 0x97, 0x52, 0xb3, 0x9e, 0xc1, 0x06, 0x84,
|
||||
0x76, 0x17, 0xe8, 0x12, 0xf6, 0x9d, 0x80, 0x5f, 0xdd, 0xbd, 0x48, 0x5d, 0xe6, 0xaf, 0x4b, 0xf5,
|
||||
0xb0, 0xaa, 0x75, 0x7d, 0xa9, 0xcc, 0x99, 0x1a, 0xc1, 0xeb, 0x58, 0x53, 0x62, 0xac, 0x2f, 0xa0,
|
||||
0x92, 0xf0, 0x19, 0xc6, 0x7b, 0x0c, 0x19, 0x6a, 0x2c, 0x30, 0x8b, 0xf3, 0xa5, 0xc6, 0x42, 0x5f,
|
||||
0x4a, 0x3f, 0x02, 0x92, 0x3d, 0x66, 0xcd, 0x0c, 0x46, 0x6e, 0x09, 0x89, 0x22, 0x3c, 0x87, 0xfc,
|
||||
0xd8, 0xb1, 0x3f, 0x60, 0x66, 0xd0, 0x09, 0x89, 0x5a, 0x04, 0xbe, 0x48, 0xe7, 0x12, 0xe9, 0x15,
|
||||
0x54, 0x12, 0x6a, 0xa1, 0x93, 0x2f, 0x66, 0x26, 0x7d, 0x4e, 0x41, 0x61, 0x40, 0x6c, 0xd3, 0xb2,
|
||||
0x27, 0xda, 0x82, 0x10, 0x17, 0x7d, 0x0f, 0x59, 0x3f, 0x17, 0x27, 0x1a, 0x83, 0xfc, 0xf5, 0x41,
|
||||
0x7d, 0xca, 0x33, 0x55, 0xe6, 0x6c, 0xe0, 0x8b, 0xd5, 0x98, 0x80, 0x5e, 0x43, 0x61, 0x61, 0x31,
|
||||
0x9b, 0x78, 0x1e, 0x66, 0x2b, 0x97, 0xf0, 0x06, 0x95, 0xae, 0x4f, 0xea, 0xf1, 0x20, 0xd6, 0x87,
|
||||
0x01, 0xac, 0xaf, 0x5c, 0xa2, 0xe6, 0x17, 0xeb, 0x87, 0x3f, 0x4c, 0xc6, 0xcc, 0x99, 0xdb, 0x0c,
|
||||
0x7b, 0x06, 0xe3, 0xd5, 0x2a, 0xaa, 0xb9, 0x40, 0xa2, 0x19, 0x0c, 0x5d, 0x40, 0x21, 0x8a, 0x7a,
|
||||
0xb4, 0x62, 0xa4, 0xba, 0xc7, 0x09, 0x10, 0xc4, 0x7d, 0xb3, 0x62, 0x04, 0xbd, 0x04, 0x34, 0xa2,
|
||||
0x8e, 0x61, 0x8e, 0x0d, 0x8f, 0x61, 0x83, 0x31, 0x32, 0x73, 0x99, 0x57, 0x4d, 0x73, 0xde, 0x61,
|
||||
0x8c, 0x34, 0x42, 0x00, 0x5d, 0xc3, 0xb1, 0x4d, 0x96, 0x0c, 0xaf, 0x75, 0xee, 0x89, 0x35, 0xb9,
|
||||
0x67, 0xd5, 0x0c, 0xd7, 0xa8, 0xf8, 0xe0, 0x4d, 0x84, 0xb5, 0x39, 0xe4, 0xeb, 0xd0, 0xa0, 0xfa,
|
||||
0xc4, 0xc4, 0x62, 0xf1, 0xb3, 0x81, 0x4e, 0x0c, 0x36, 0xe3, 0x2e, 0xa0, 0x57, 0x70, 0xb2, 0xd6,
|
||||
0x49, 0xa4, 0x90, 0xdb, 0x50, 0xd2, 0xd6, 0xb9, 0x1c, 0x41, 0xfa, 0x83, 0x43, 0xc7, 0xa4, 0xba,
|
||||
0x7f, 0xb1, 0x73, 0x99, 0x55, 0x83, 0x87, 0x74, 0x02, 0x47, 0x62, 0x6b, 0xa2, 0x59, 0x95, 0x86,
|
||||
0x70, 0xbc, 0x21, 0x0f, 0x5b, 0xfd, 0x2b, 0x94, 0xdc, 0x00, 0xc0, 0x1e, 0x47, 0xaa, 0x3b, 0x7c,
|
||||
0x5a, 0x4f, 0x85, 0x86, 0x88, 0x9a, 0x6a, 0xd1, 0x15, 0xed, 0x48, 0x7f, 0xef, 0x40, 0xe9, 0x66,
|
||||
0x3e, 0x73, 0x85, 0xa9, 0xfb, 0x4f, 0xe3, 0x70, 0x0e, 0xf9, 0xa0, 0x40, 0xbc, 0x58, 0x7c, 0x1a,
|
||||
0x8a, 0x2a, 0x04, 0x22, 0xbf, 0x44, 0x5b, 0x5d, 0x4d, 0x6d, 0x75, 0x35, 0xae, 0xc4, 0x9e, 0x58,
|
||||
0x89, 0x43, 0x38, 0x88, 0xe3, 0x0a, 0x72, 0x95, 0x5e, 0xc2, 0x61, 0xcf, 0xf2, 0x58, 0xa2, 0x32,
|
||||
0xa8, 0x0a, 0xfb, 0x9f, 0x08, 0x1d, 0x39, 0x1e, 0xe1, 0xc1, 0x66, 0xd5, 0xe8, 0x29, 0xfd, 0xb9,
|
||||
0x0b, 0x48, 0xe4, 0x87, 0x15, 0xeb, 0x41, 0x85, 0xad, 0x17, 0x10, 0x36, 0x09, 0x33, 0xac, 0xa9,
|
||||
0x17, 0x66, 0xfa, 0x34, 0xcc, 0x54, 0x58, 0x51, 0xad, 0x80, 0xd0, 0x7e, 0xa2, 0x22, 0xb6, 0x25,
|
||||
0x45, 0x43, 0x38, 0x10, 0xad, 0x59, 0xa6, 0xc7, 0x6b, 0x90, 0xbf, 0x7e, 0x21, 0x34, 0x60, 0x3b,
|
||||
0x0a, 0xd1, 0x41, 0xa7, 0xe5, 0x1b, 0x2f, 0x09, 0x66, 0x3a, 0xa6, 0x57, 0x7b, 0x0d, 0xa5, 0x24,
|
||||
0x07, 0x7d, 0xbb, 0xed, 0xca, 0xef, 0x75, 0x6e, 0x53, 0xf5, 0x26, 0x0b, 0x99, 0x60, 0x16, 0xbe,
|
||||
0xfb, 0x9c, 0x82, 0xbc, 0xf0, 0x39, 0xa2, 0x0a, 0x1c, 0xbc, 0xed, 0x77, 0xfb, 0xca, 0xb0, 0x8f,
|
||||
0x87, 0x1d, 0xbd, 0x2f, 0x6b, 0x5a, 0xf9, 0x09, 0xaa, 0xc2, 0x51, 0x53, 0xb9, 0xbb, 0xeb, 0xe8,
|
||||
0x77, 0x72, 0x5f, 0xc7, 0x7a, 0xe7, 0x4e, 0xc6, 0x3d, 0xa5, 0xd9, 0x2d, 0xef, 0xa0, 0x53, 0xa8,
|
||||
0x08, 0x48, 0x5f, 0xc1, 0x2d, 0xb9, 0xd7, 0x78, 0x5f, 0xde, 0x45, 0xc7, 0x70, 0x28, 0x00, 0xaa,
|
||||
0xfc, 0x4e, 0xe9, 0xca, 0xe5, 0x94, 0xcf, 0x6f, 0xeb, 0xbd, 0x26, 0x56, 0x6e, 0x6f, 0x65, 0x55,
|
||||
0x6e, 0x45, 0xc0, 0x9e, 0xef, 0x82, 0x03, 0x8d, 0x66, 0x53, 0x1e, 0xe8, 0x6b, 0x24, 0x8d, 0xbe,
|
||||
0x86, 0xff, 0x27, 0x54, 0x7c, 0xf7, 0xca, 0x5b, 0x1d, 0x6b, 0x72, 0x53, 0xe9, 0xb7, 0x70, 0x4f,
|
||||
0x7e, 0x27, 0xf7, 0xca, 0x19, 0xf4, 0x0d, 0x48, 0x49, 0x03, 0xda, 0xdb, 0x66, 0x53, 0xd6, 0xb4,
|
||||
0x24, 0x6f, 0x1f, 0x9d, 0xc3, 0xb3, 0x8d, 0x08, 0xee, 0x14, 0x5d, 0x8e, 0xac, 0x96, 0xb3, 0xe8,
|
||||
0x02, 0xce, 0x36, 0x23, 0xe1, 0x8c, 0xd0, 0x5e, 0x39, 0x87, 0xce, 0xa0, 0xca, 0x19, 0xa2, 0xe5,
|
||||
0x28, 0x5e, 0x40, 0x47, 0x50, 0x0e, 0x2b, 0x87, 0xbb, 0xf2, 0x7b, 0xdc, 0x6e, 0x68, 0xed, 0x72,
|
||||
0x1e, 0x3d, 0x83, 0xd3, 0xbe, 0xac, 0xf9, 0xe6, 0xb6, 0xc0, 0xc2, 0x46, 0xb1, 0x1a, 0xfd, 0x66,
|
||||
0x5b, 0x51, 0xcb, 0xc5, 0xeb, 0xbf, 0xd2, 0x90, 0x1b, 0xf2, 0x11, 0xe9, 0x5a, 0x0c, 0xbd, 0x81,
|
||||
0x62, 0x8b, 0x50, 0xeb, 0x13, 0xe9, 0x93, 0x25, 0xeb, 0x92, 0x15, 0x3a, 0x14, 0xe6, 0x27, 0x38,
|
||||
0xdb, 0xb5, 0x93, 0xf8, 0x02, 0x75, 0xc9, 0xaa, 0x45, 0xbc, 0x31, 0xb5, 0x5c, 0xe6, 0x50, 0xf4,
|
||||
0x33, 0xe4, 0x02, 0x5d, 0x5f, 0xaf, 0x22, 0x92, 0x7a, 0xce, 0xd8, 0x60, 0x0e, 0x7d, 0x54, 0xf3,
|
||||
0x17, 0xc8, 0xfa, 0xfe, 0xfc, 0xa3, 0x8d, 0xc4, 0x15, 0x2e, 0x1c, 0xf5, 0xda, 0xe9, 0x96, 0x3c,
|
||||
0xfc, 0x90, 0xda, 0x80, 0xc2, 0x6b, 0x2c, 0x1e, 0x74, 0xd1, 0x8c, 0x20, 0xaf, 0xd5, 0xc4, 0x85,
|
||||
0xb4, 0x71, 0xc4, 0x7b, 0x90, 0x17, 0x6e, 0x25, 0x7a, 0x2e, 0x50, 0xb7, 0xef, 0x76, 0xed, 0x7f,
|
||||
0x8f, 0xc1, 0x6b, 0x6b, 0xc2, 0x51, 0x4c, 0x58, 0xdb, 0xbe, 0xb1, 0x09, 0x6b, 0xff, 0x76, 0x4b,
|
||||
0x55, 0x28, 0x26, 0x36, 0x2f, 0x3a, 0x7f, 0x64, 0xb3, 0xc6, 0xf1, 0x5d, 0x3c, 0x4e, 0x08, 0x6d,
|
||||
0xfe, 0x06, 0xfb, 0xe1, 0x6e, 0x43, 0x4f, 0x05, 0x72, 0x72, 0x0f, 0x27, 0x2a, 0xb6, 0xb1, 0x0a,
|
||||
0x51, 0x07, 0x60, 0xbd, 0x54, 0xd0, 0xd9, 0x23, 0xbb, 0x26, 0xb0, 0xf3, 0xfc, 0x8b, 0x9b, 0xe8,
|
||||
0xe6, 0x87, 0x3f, 0xae, 0x26, 0x16, 0xbb, 0x9f, 0x8f, 0xea, 0x63, 0x67, 0x76, 0x35, 0xf5, 0xaf,
|
||||
0xa0, 0x6d, 0xd9, 0x13, 0x9b, 0xb0, 0x85, 0x43, 0x1f, 0xae, 0xa6, 0xb6, 0x79, 0xc5, 0x77, 0xe2,
|
||||
0x55, 0x6c, 0x65, 0x94, 0xe1, 0xff, 0x50, 0xbe, 0xfa, 0x27, 0x00, 0x00, 0xff, 0xff, 0xde, 0x94,
|
||||
0x5b, 0x29, 0x99, 0x0a, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
|
|
@ -129,6 +129,11 @@ message Transaction {
|
|||
The raw serialized transaction.
|
||||
*/
|
||||
bytes tx_hex = 1;
|
||||
|
||||
/*
|
||||
An optional label to save with the transaction. Limited to 500 characters.
|
||||
*/
|
||||
string label = 2;
|
||||
}
|
||||
message PublishResponse {
|
||||
/*
|
||||
|
@ -152,6 +157,9 @@ message SendOutputsRequest {
|
|||
A slice of the outputs that should be created in the transaction produced.
|
||||
*/
|
||||
repeated signrpc.TxOut outputs = 2;
|
||||
|
||||
// An optional label for the transaction, limited to 500 characters.
|
||||
string label = 3;
|
||||
}
|
||||
message SendOutputsResponse {
|
||||
/*
|
||||
|
|
|
@ -93,6 +93,10 @@
|
|||
"raw_tx_hex": {
|
||||
"type": "string",
|
||||
"description": "The raw transaction hex."
|
||||
},
|
||||
"label": {
|
||||
"type": "string",
|
||||
"description": "A label that was optionally set on transaction broadcast."
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
"github.com/lightningnetwork/lnd/labels"
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
"github.com/lightningnetwork/lnd/lnrpc/signrpc"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
|
@ -273,7 +274,12 @@ func (w *WalletKit) PublishTransaction(ctx context.Context,
|
|||
return nil, err
|
||||
}
|
||||
|
||||
err := w.cfg.Wallet.PublishTransaction(tx)
|
||||
label, err := labels.ValidateAPI(req.Label)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = w.cfg.Wallet.PublishTransaction(tx, label)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -306,10 +312,15 @@ func (w *WalletKit) SendOutputs(ctx context.Context,
|
|||
})
|
||||
}
|
||||
|
||||
label, err := labels.ValidateAPI(req.Label)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Now that we have the outputs mapped, we can request that the wallet
|
||||
// attempt to create this transaction.
|
||||
tx, err := w.cfg.Wallet.SendOutputs(
|
||||
outputsToCreate, chainfee.SatPerKWeight(req.SatPerKw),
|
||||
outputsToCreate, chainfee.SatPerKWeight(req.SatPerKw), label,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -12486,9 +12486,13 @@ func testSweepAllCoins(net *lntest.NetworkHarness, t *harnessTest) {
|
|||
t.Fatalf("unable to get node info: %v", err)
|
||||
}
|
||||
|
||||
// Create a label that we will used to label the transaction with.
|
||||
sendCoinsLabel := "send all coins"
|
||||
|
||||
sweepReq := &lnrpc.SendCoinsRequest{
|
||||
Addr: info.IdentityPubkey,
|
||||
SendAll: true,
|
||||
Label: sendCoinsLabel,
|
||||
}
|
||||
_, err = ainz.SendCoins(ctxt, sweepReq)
|
||||
if err == nil {
|
||||
|
@ -12504,6 +12508,7 @@ func testSweepAllCoins(net *lntest.NetworkHarness, t *harnessTest) {
|
|||
sweepReq = &lnrpc.SendCoinsRequest{
|
||||
Addr: info.IdentityPubkey,
|
||||
SendAll: true,
|
||||
Label: sendCoinsLabel,
|
||||
}
|
||||
_, err = ainz.SendCoins(ctxt, sweepReq)
|
||||
if err == nil {
|
||||
|
@ -12522,6 +12527,7 @@ func testSweepAllCoins(net *lntest.NetworkHarness, t *harnessTest) {
|
|||
sweepReq = &lnrpc.SendCoinsRequest{
|
||||
Addr: "tb1qfc8fusa98jx8uvnhzavxccqlzvg749tvjw82tg",
|
||||
SendAll: true,
|
||||
Label: sendCoinsLabel,
|
||||
}
|
||||
_, err = ainz.SendCoins(ctxt, sweepReq)
|
||||
if err == nil {
|
||||
|
@ -12533,6 +12539,7 @@ func testSweepAllCoins(net *lntest.NetworkHarness, t *harnessTest) {
|
|||
sweepReq = &lnrpc.SendCoinsRequest{
|
||||
Addr: "1MPaXKp5HhsLNjVSqaL7fChE3TVyrTMRT3",
|
||||
SendAll: true,
|
||||
Label: sendCoinsLabel,
|
||||
}
|
||||
_, err = ainz.SendCoins(ctxt, sweepReq)
|
||||
if err == nil {
|
||||
|
@ -12548,6 +12555,7 @@ func testSweepAllCoins(net *lntest.NetworkHarness, t *harnessTest) {
|
|||
sweepReq = &lnrpc.SendCoinsRequest{
|
||||
Addr: minerAddr.String(),
|
||||
SendAll: true,
|
||||
Label: sendCoinsLabel,
|
||||
}
|
||||
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
||||
_, err = ainz.SendCoins(ctxt, sweepReq)
|
||||
|
@ -12566,6 +12574,24 @@ func testSweepAllCoins(net *lntest.NetworkHarness, t *harnessTest) {
|
|||
t.Fatalf("expected 2 inputs instead have %v", len(sweepTx.TxIn))
|
||||
}
|
||||
|
||||
// List all transactions relevant to our wallet, and find the sweep tx
|
||||
// so that we can check the correct label has been set.
|
||||
ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
|
||||
txResp, err := ainz.GetTransactions(ctxt, &lnrpc.GetTransactionsRequest{})
|
||||
if err != nil {
|
||||
t.Fatalf("could not get transactions: %v", err)
|
||||
}
|
||||
|
||||
sweepTxStr := sweepTx.TxHash().String()
|
||||
for _, txn := range txResp.Transactions {
|
||||
if txn.TxHash == sweepTxStr {
|
||||
if txn.Label != sendCoinsLabel {
|
||||
t.Fatalf("expected label: %v, got: %v",
|
||||
sendCoinsLabel, txn.Label)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, Ainz should now have no coins at all within his wallet.
|
||||
balReq := &lnrpc.WalletBalanceRequest{}
|
||||
resp, err := ainz.WalletBalance(ctxt, balReq)
|
||||
|
|
|
@ -294,7 +294,7 @@ func (b *BtcWallet) IsOurAddress(a btcutil.Address) bool {
|
|||
//
|
||||
// This is a part of the WalletController interface.
|
||||
func (b *BtcWallet) SendOutputs(outputs []*wire.TxOut,
|
||||
feeRate chainfee.SatPerKWeight) (*wire.MsgTx, error) {
|
||||
feeRate chainfee.SatPerKWeight, label string) (*wire.MsgTx, error) {
|
||||
|
||||
// Convert our fee rate from sat/kw to sat/kb since it's required by
|
||||
// SendOutputs.
|
||||
|
@ -304,7 +304,10 @@ func (b *BtcWallet) SendOutputs(outputs []*wire.TxOut,
|
|||
if len(outputs) < 1 {
|
||||
return nil, lnwallet.ErrNoOutputs
|
||||
}
|
||||
return b.wallet.SendOutputs(outputs, defaultAccount, 1, feeSatPerKB, "")
|
||||
|
||||
return b.wallet.SendOutputs(
|
||||
outputs, defaultAccount, 1, feeSatPerKB, label,
|
||||
)
|
||||
}
|
||||
|
||||
// CreateSimpleTx creates a Bitcoin transaction paying to the specified
|
||||
|
@ -433,8 +436,8 @@ func (b *BtcWallet) ListUnspentWitness(minConfs, maxConfs int32) (
|
|||
// publishing the transaction fails, an error describing the reason is returned
|
||||
// (currently ErrDoubleSpend). If the transaction is already published to the
|
||||
// network (either in the mempool or chain) no error will be returned.
|
||||
func (b *BtcWallet) PublishTransaction(tx *wire.MsgTx) error {
|
||||
if err := b.wallet.PublishTransaction(tx, ""); err != nil {
|
||||
func (b *BtcWallet) PublishTransaction(tx *wire.MsgTx, label string) error {
|
||||
if err := b.wallet.PublishTransaction(tx, label); err != nil {
|
||||
|
||||
// If we failed to publish the transaction, check whether we
|
||||
// got an error of known type.
|
||||
|
@ -516,6 +519,7 @@ func minedTransactionsToDetails(
|
|||
TotalFees: int64(tx.Fee),
|
||||
DestAddresses: destAddresses,
|
||||
RawTx: tx.Transaction,
|
||||
Label: tx.Label,
|
||||
}
|
||||
|
||||
balanceDelta, err := extractBalanceDelta(tx, wireTx)
|
||||
|
@ -561,6 +565,7 @@ func unminedTransactionsToDetail(
|
|||
Timestamp: summary.Timestamp,
|
||||
DestAddresses: destAddresses,
|
||||
RawTx: summary.Transaction,
|
||||
Label: summary.Label,
|
||||
}
|
||||
|
||||
balanceDelta, err := extractBalanceDelta(summary, wireTx)
|
||||
|
|
|
@ -103,6 +103,9 @@ type TransactionDetail struct {
|
|||
|
||||
// RawTx returns the raw serialized transaction.
|
||||
RawTx []byte
|
||||
|
||||
// Label is an optional transaction label.
|
||||
Label string
|
||||
}
|
||||
|
||||
// TransactionSubscription is an interface which describes an object capable of
|
||||
|
@ -174,7 +177,7 @@ type WalletController interface {
|
|||
// This method also takes the target fee expressed in sat/kw that should
|
||||
// be used when crafting the transaction.
|
||||
SendOutputs(outputs []*wire.TxOut,
|
||||
feeRate chainfee.SatPerKWeight) (*wire.MsgTx, error)
|
||||
feeRate chainfee.SatPerKWeight, label string) (*wire.MsgTx, error)
|
||||
|
||||
// CreateSimpleTx creates a Bitcoin transaction paying to the specified
|
||||
// outputs. The transaction is not broadcasted to the network. In the
|
||||
|
@ -224,8 +227,9 @@ type WalletController interface {
|
|||
// already known transaction, ErrDoubleSpend is returned. If the
|
||||
// transaction is already known (published already), no error will be
|
||||
// returned. Other error returned depends on the currently active chain
|
||||
// backend.
|
||||
PublishTransaction(tx *wire.MsgTx) error
|
||||
// backend. It takes an optional label which will save a label with the
|
||||
// published transaction.
|
||||
PublishTransaction(tx *wire.MsgTx, label string) error
|
||||
|
||||
// SubscribeTransactions returns a TransactionSubscription client which
|
||||
// is capable of receiving async notifications as new transactions
|
||||
|
|
|
@ -38,6 +38,7 @@ import (
|
|||
"github.com/lightningnetwork/lnd/channeldb/kvdb"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
"github.com/lightningnetwork/lnd/labels"
|
||||
"github.com/lightningnetwork/lnd/lntest/wait"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/btcwallet"
|
||||
|
@ -173,7 +174,9 @@ func sendCoins(t *testing.T, miner *rpctest.Harness,
|
|||
|
||||
t.Helper()
|
||||
|
||||
tx, err := sender.SendOutputs([]*wire.TxOut{output}, 2500)
|
||||
tx, err := sender.SendOutputs(
|
||||
[]*wire.TxOut{output}, 2500, labels.External,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to send transaction: %v", err)
|
||||
}
|
||||
|
@ -529,7 +532,8 @@ func testDualFundingReservationWorkflow(miner *rpctest.Harness,
|
|||
}
|
||||
|
||||
// Let Alice publish the funding transaction.
|
||||
if err := alice.PublishTransaction(fundingTx); err != nil {
|
||||
err = alice.PublishTransaction(fundingTx, "")
|
||||
if err != nil {
|
||||
t.Fatalf("unable to publish funding tx: %v", err)
|
||||
}
|
||||
|
||||
|
@ -1024,7 +1028,8 @@ func testSingleFunderReservationWorkflow(miner *rpctest.Harness,
|
|||
}
|
||||
|
||||
// Let Alice publish the funding transaction.
|
||||
if err := alice.PublishTransaction(fundingTx); err != nil {
|
||||
err = alice.PublishTransaction(fundingTx, "")
|
||||
if err != nil {
|
||||
t.Fatalf("unable to publish funding tx: %v", err)
|
||||
}
|
||||
|
||||
|
@ -1217,7 +1222,9 @@ func testListTransactionDetails(miner *rpctest.Harness,
|
|||
t.Fatalf("unable to make output script: %v", err)
|
||||
}
|
||||
burnOutput := wire.NewTxOut(outputAmt, outputScript)
|
||||
burnTX, err := alice.SendOutputs([]*wire.TxOut{burnOutput}, 2500)
|
||||
burnTX, err := alice.SendOutputs(
|
||||
[]*wire.TxOut{burnOutput}, 2500, labels.External,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create burn tx: %v", err)
|
||||
}
|
||||
|
@ -1490,7 +1497,9 @@ func testTransactionSubscriptions(miner *rpctest.Harness,
|
|||
t.Fatalf("unable to make output script: %v", err)
|
||||
}
|
||||
burnOutput := wire.NewTxOut(outputAmt, outputScript)
|
||||
tx, err := alice.SendOutputs([]*wire.TxOut{burnOutput}, 2500)
|
||||
tx, err := alice.SendOutputs(
|
||||
[]*wire.TxOut{burnOutput}, 2500, labels.External,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create burn tx: %v", err)
|
||||
}
|
||||
|
@ -1681,7 +1690,9 @@ func newTx(t *testing.T, r *rpctest.Harness, pubKey *btcec.PublicKey,
|
|||
Value: btcutil.SatoshiPerBitcoin,
|
||||
PkScript: keyScript,
|
||||
}
|
||||
tx, err := alice.SendOutputs([]*wire.TxOut{newOutput}, 2500)
|
||||
tx, err := alice.SendOutputs(
|
||||
[]*wire.TxOut{newOutput}, 2500, labels.External,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create output: %v", err)
|
||||
}
|
||||
|
@ -1721,7 +1732,8 @@ func testPublishTransaction(r *rpctest.Harness,
|
|||
tx1 := newTx(t, r, keyDesc.PubKey, alice, false)
|
||||
|
||||
// Publish the transaction.
|
||||
if err := alice.PublishTransaction(tx1); err != nil {
|
||||
err = alice.PublishTransaction(tx1, labels.External)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to publish: %v", err)
|
||||
}
|
||||
|
||||
|
@ -1733,7 +1745,8 @@ func testPublishTransaction(r *rpctest.Harness,
|
|||
|
||||
// Publish the exact same transaction again. This should not return an
|
||||
// error, even though the transaction is already in the mempool.
|
||||
if err := alice.PublishTransaction(tx1); err != nil {
|
||||
err = alice.PublishTransaction(tx1, labels.External)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to publish: %v", err)
|
||||
}
|
||||
|
||||
|
@ -1752,7 +1765,8 @@ func testPublishTransaction(r *rpctest.Harness,
|
|||
tx2 := newTx(t, r, keyDesc.PubKey, alice, false)
|
||||
|
||||
// Publish this tx.
|
||||
if err := alice.PublishTransaction(tx2); err != nil {
|
||||
err = alice.PublishTransaction(tx2, labels.External)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to publish: %v", err)
|
||||
}
|
||||
|
||||
|
@ -1763,7 +1777,8 @@ func testPublishTransaction(r *rpctest.Harness,
|
|||
|
||||
// Publish the transaction again. It is already mined, and we don't
|
||||
// expect this to return an error.
|
||||
if err := alice.PublishTransaction(tx2); err != nil {
|
||||
err = alice.PublishTransaction(tx2, labels.External)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to publish: %v", err)
|
||||
}
|
||||
|
||||
|
@ -1779,7 +1794,8 @@ func testPublishTransaction(r *rpctest.Harness,
|
|||
// transaction. Create a new tx and publish it. This is the
|
||||
// output we'll try to double spend.
|
||||
tx3 = newTx(t, r, keyDesc.PubKey, alice, false)
|
||||
if err := alice.PublishTransaction(tx3); err != nil {
|
||||
err := alice.PublishTransaction(tx3, labels.External)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to publish: %v", err)
|
||||
}
|
||||
|
||||
|
@ -1799,7 +1815,8 @@ func testPublishTransaction(r *rpctest.Harness,
|
|||
}
|
||||
|
||||
// This should be accepted into the mempool.
|
||||
if err := alice.PublishTransaction(tx4); err != nil {
|
||||
err = alice.PublishTransaction(tx4, labels.External)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to publish: %v", err)
|
||||
}
|
||||
|
||||
|
@ -1833,7 +1850,7 @@ func testPublishTransaction(r *rpctest.Harness,
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = alice.PublishTransaction(tx5)
|
||||
err = alice.PublishTransaction(tx5, labels.External)
|
||||
if err != lnwallet.ErrDoubleSpend {
|
||||
t.Fatalf("expected ErrDoubleSpend, got: %v", err)
|
||||
}
|
||||
|
@ -1861,7 +1878,7 @@ func testPublishTransaction(r *rpctest.Harness,
|
|||
expErr = nil
|
||||
tx3Spend = tx6
|
||||
}
|
||||
err = alice.PublishTransaction(tx6)
|
||||
err = alice.PublishTransaction(tx6, labels.External)
|
||||
if err != expErr {
|
||||
t.Fatalf("expected ErrDoubleSpend, got: %v", err)
|
||||
}
|
||||
|
@ -1896,7 +1913,7 @@ func testPublishTransaction(r *rpctest.Harness,
|
|||
}
|
||||
|
||||
// Expect rejection.
|
||||
err = alice.PublishTransaction(tx7)
|
||||
err = alice.PublishTransaction(tx7, labels.External)
|
||||
if err != lnwallet.ErrDoubleSpend {
|
||||
t.Fatalf("expected ErrDoubleSpend, got: %v", err)
|
||||
}
|
||||
|
@ -1964,7 +1981,9 @@ func testSignOutputUsingTweaks(r *rpctest.Harness,
|
|||
Value: btcutil.SatoshiPerBitcoin,
|
||||
PkScript: keyScript,
|
||||
}
|
||||
tx, err := alice.SendOutputs([]*wire.TxOut{newOutput}, 2500)
|
||||
tx, err := alice.SendOutputs(
|
||||
[]*wire.TxOut{newOutput}, 2500, labels.External,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create output: %v", err)
|
||||
}
|
||||
|
@ -2086,7 +2105,9 @@ func testReorgWalletBalance(r *rpctest.Harness, w *lnwallet.LightningWallet,
|
|||
Value: 1e8,
|
||||
PkScript: script,
|
||||
}
|
||||
tx, err := w.SendOutputs([]*wire.TxOut{output}, 2500)
|
||||
tx, err := w.SendOutputs(
|
||||
[]*wire.TxOut{output}, 2500, labels.External,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to send outputs: %v", err)
|
||||
}
|
||||
|
@ -2467,7 +2488,7 @@ func testCreateSimpleTx(r *rpctest.Harness, w *lnwallet.LightningWallet,
|
|||
// _very_ similar to the one we just created being sent. The
|
||||
// only difference is that the dry run tx is not signed, and
|
||||
// that the change output position might be different.
|
||||
tx, sendErr := w.SendOutputs(outputs, feeRate)
|
||||
tx, sendErr := w.SendOutputs(outputs, feeRate, labels.External)
|
||||
switch {
|
||||
case test.valid && sendErr != nil:
|
||||
t.Fatalf("got unexpected error when sending tx: %v",
|
||||
|
|
4
mock.go
4
mock.go
|
@ -281,7 +281,7 @@ func (*mockWalletController) IsOurAddress(a btcutil.Address) bool {
|
|||
}
|
||||
|
||||
func (*mockWalletController) SendOutputs(outputs []*wire.TxOut,
|
||||
_ chainfee.SatPerKWeight) (*wire.MsgTx, error) {
|
||||
_ chainfee.SatPerKWeight, _ string) (*wire.MsgTx, error) {
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
@ -322,7 +322,7 @@ func (*mockWalletController) ListTransactionDetails(_, _ int32) ([]*lnwallet.Tra
|
|||
}
|
||||
func (*mockWalletController) LockOutpoint(o wire.OutPoint) {}
|
||||
func (*mockWalletController) UnlockOutpoint(o wire.OutPoint) {}
|
||||
func (m *mockWalletController) PublishTransaction(tx *wire.MsgTx) error {
|
||||
func (m *mockWalletController) PublishTransaction(tx *wire.MsgTx, _ string) error {
|
||||
m.publishedTransactions <- tx
|
||||
return nil
|
||||
}
|
||||
|
|
23
rpcserver.go
23
rpcserver.go
|
@ -44,6 +44,7 @@ import (
|
|||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/invoices"
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
"github.com/lightningnetwork/lnd/labels"
|
||||
"github.com/lightningnetwork/lnd/lncfg"
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
"github.com/lightningnetwork/lnd/lnrpc/invoicesrpc"
|
||||
|
@ -924,14 +925,14 @@ func addrPairsToOutputs(addrPairs map[string]int64) ([]*wire.TxOut, error) {
|
|||
// more addresses specified in the passed payment map. The payment map maps an
|
||||
// address to a specified output value to be sent to that address.
|
||||
func (r *rpcServer) sendCoinsOnChain(paymentMap map[string]int64,
|
||||
feeRate chainfee.SatPerKWeight) (*chainhash.Hash, error) {
|
||||
feeRate chainfee.SatPerKWeight, label string) (*chainhash.Hash, error) {
|
||||
|
||||
outputs, err := addrPairsToOutputs(paymentMap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tx, err := r.server.cc.wallet.SendOutputs(outputs, feeRate)
|
||||
tx, err := r.server.cc.wallet.SendOutputs(outputs, feeRate, label)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -1147,6 +1148,11 @@ func (r *rpcServer) SendCoins(ctx context.Context,
|
|||
return nil, fmt.Errorf("cannot send coins to pubkeys")
|
||||
}
|
||||
|
||||
label, err := labels.ValidateAPI(in.Label)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var txid *chainhash.Hash
|
||||
|
||||
wallet := r.server.cc.wallet
|
||||
|
@ -1187,7 +1193,7 @@ func (r *rpcServer) SendCoins(ctx context.Context,
|
|||
// As our sweep transaction was created, successfully, we'll
|
||||
// now attempt to publish it, cancelling the sweep pkg to
|
||||
// return all outputs if it fails.
|
||||
err = wallet.PublishTransaction(sweepTxPkg.SweepTx)
|
||||
err = wallet.PublishTransaction(sweepTxPkg.SweepTx, label)
|
||||
if err != nil {
|
||||
sweepTxPkg.CancelSweepAttempt()
|
||||
|
||||
|
@ -1205,7 +1211,9 @@ func (r *rpcServer) SendCoins(ctx context.Context,
|
|||
// while we instruct the wallet to send this transaction.
|
||||
paymentMap := map[string]int64{targetAddr.String(): in.Amount}
|
||||
err := wallet.WithCoinSelectLock(func() error {
|
||||
newTXID, err := r.sendCoinsOnChain(paymentMap, feePerKw)
|
||||
newTXID, err := r.sendCoinsOnChain(
|
||||
paymentMap, feePerKw, label,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -1242,6 +1250,11 @@ func (r *rpcServer) SendMany(ctx context.Context,
|
|||
return nil, err
|
||||
}
|
||||
|
||||
label, err := labels.ValidateAPI(in.Label)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rpcsLog.Infof("[sendmany] outputs=%v, sat/kw=%v",
|
||||
spew.Sdump(in.AddrToAmount), int64(feePerKw))
|
||||
|
||||
|
@ -1253,7 +1266,7 @@ func (r *rpcServer) SendMany(ctx context.Context,
|
|||
wallet := r.server.cc.wallet
|
||||
err = wallet.WithCoinSelectLock(func() error {
|
||||
sendManyTXID, err := r.sendCoinsOnChain(
|
||||
in.AddrToAmount, feePerKw,
|
||||
in.AddrToAmount, feePerKw, label,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -75,7 +75,7 @@ func (b *mockBackend) publishTransaction(tx *wire.MsgTx) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (b *mockBackend) PublishTransaction(tx *wire.MsgTx) error {
|
||||
func (b *mockBackend) PublishTransaction(tx *wire.MsgTx, _ string) error {
|
||||
log.Tracef("Publishing tx %v", tx.TxHash())
|
||||
err := b.publishTransaction(tx)
|
||||
select {
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
type Wallet interface {
|
||||
// PublishTransaction performs cursory validation (dust checks, etc) and
|
||||
// broadcasts the passed transaction to the Bitcoin network.
|
||||
PublishTransaction(tx *wire.MsgTx) error
|
||||
PublishTransaction(tx *wire.MsgTx, label string) error
|
||||
|
||||
// ListUnspentWitness returns all unspent outputs which are version 0
|
||||
// witness programs. The 'minconfirms' and 'maxconfirms' parameters
|
||||
|
|
|
@ -355,7 +355,7 @@ func (s *UtxoSweeper) Start() error {
|
|||
|
||||
// Error can be ignored. Because we are starting up, there are
|
||||
// no pending inputs to update based on the publish result.
|
||||
err := s.cfg.Wallet.PublishTransaction(lastTx)
|
||||
err := s.cfg.Wallet.PublishTransaction(lastTx, "")
|
||||
if err != nil && err != lnwallet.ErrDoubleSpend {
|
||||
log.Errorf("last tx publish: %v", err)
|
||||
}
|
||||
|
@ -988,7 +988,7 @@ func (s *UtxoSweeper) sweep(inputs inputSet, feeRate chainfee.SatPerKWeight,
|
|||
}),
|
||||
)
|
||||
|
||||
err = s.cfg.Wallet.PublishTransaction(tx)
|
||||
err = s.cfg.Wallet.PublishTransaction(tx, "")
|
||||
|
||||
// In case of an unexpected error, don't try to recover.
|
||||
if err != nil && err != lnwallet.ErrDoubleSpend {
|
||||
|
|
|
@ -194,7 +194,7 @@ type NurseryConfig struct {
|
|||
|
||||
// PublishTransaction facilitates the process of broadcasting a signed
|
||||
// transaction to the appropriate network.
|
||||
PublishTransaction func(*wire.MsgTx) error
|
||||
PublishTransaction func(*wire.MsgTx, string) error
|
||||
|
||||
// Store provides access to and modification of the persistent state
|
||||
// maintained about the utxo nursery's incubating outputs.
|
||||
|
@ -867,7 +867,7 @@ func (u *utxoNursery) sweepCribOutput(classHeight uint32, baby *babyOutput) erro
|
|||
|
||||
// We'll now broadcast the HTLC transaction, then wait for it to be
|
||||
// confirmed before transitioning it to kindergarten.
|
||||
err := u.cfg.PublishTransaction(baby.timeoutTx)
|
||||
err := u.cfg.PublishTransaction(baby.timeoutTx, "")
|
||||
if err != nil && err != lnwallet.ErrDoubleSpend {
|
||||
utxnLog.Errorf("Unable to broadcast baby tx: "+
|
||||
"%v, %v", err, spew.Sdump(baby.timeoutTx))
|
||||
|
|
|
@ -467,7 +467,7 @@ func createNurseryTestContext(t *testing.T,
|
|||
Store: storeIntercepter,
|
||||
ChainIO: chainIO,
|
||||
SweepInput: sweeper.sweepInput,
|
||||
PublishTransaction: func(tx *wire.MsgTx) error {
|
||||
PublishTransaction: func(tx *wire.MsgTx, _ string) error {
|
||||
return publishFunc(tx, "nursery")
|
||||
},
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ type Config struct {
|
|||
//
|
||||
// TODO(conner): replace with lnwallet.WalletController interface to
|
||||
// have stronger guarantees wrt. returned error types.
|
||||
PublishTx func(*wire.MsgTx) error
|
||||
PublishTx func(*wire.MsgTx, string) error
|
||||
|
||||
// ListenAddrs specifies the listening addresses of the tower.
|
||||
ListenAddrs []net.Addr
|
||||
|
|
|
@ -293,7 +293,7 @@ func testJusticeDescriptor(t *testing.T, blobType blob.Type) {
|
|||
// over the buffered channel.
|
||||
publications := make(chan *wire.MsgTx, 1)
|
||||
punisher := lookout.NewBreachPunisher(&lookout.PunisherConfig{
|
||||
PublishTx: func(tx *wire.MsgTx) error {
|
||||
PublishTx: func(tx *wire.MsgTx, _ string) error {
|
||||
publications <- tx
|
||||
return nil
|
||||
},
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
type PunisherConfig struct {
|
||||
// PublishTx provides the ability to send a signed transaction to the
|
||||
// network.
|
||||
PublishTx func(*wire.MsgTx) error
|
||||
PublishTx func(*wire.MsgTx, string) error
|
||||
|
||||
// TODO(conner) add DB tracking and spend ntfn registration to see if
|
||||
// ours confirmed or not
|
||||
|
@ -42,7 +42,7 @@ func (p *BreachPunisher) Punish(desc *JusticeDescriptor, quit <-chan struct{}) e
|
|||
log.Infof("Publishing justice transaction for client=%s with txid=%s",
|
||||
desc.SessionInfo.ID, justiceTxn.TxHash())
|
||||
|
||||
err = p.cfg.PublishTx(justiceTxn)
|
||||
err = p.cfg.PublishTx(justiceTxn, "")
|
||||
if err != nil {
|
||||
log.Errorf("Unable to publish justice txn for client=%s"+
|
||||
"with breach-txid=%s: %v",
|
||||
|
|
Loading…
Add table
Reference in a new issue