-
Notifications
You must be signed in to change notification settings - Fork 2.1k
/
input.go
190 lines (158 loc) · 5.82 KB
/
input.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
package input
import (
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
)
// Input represents an abstract UTXO which is to be spent using a sweeping
// transaction. The method provided give the caller all information needed to
// construct a valid input within a sweeping transaction to sweep this
// lingering UTXO.
type Input interface {
// Outpoint returns the reference to the output being spent, used to
// construct the corresponding transaction input.
OutPoint() *wire.OutPoint
// WitnessType returns an enum specifying the type of witness that must
// be generated in order to spend this output.
WitnessType() WitnessType
// SignDesc returns a reference to a spendable output's sign
// descriptor, which is used during signing to compute a valid witness
// that spends this output.
SignDesc() *SignDescriptor
// CraftInputScript returns a valid set of input scripts allowing this
// output to be spent. The returns input scripts should target the
// input at location txIndex within the passed transaction. The input
// scripts generated by this method support spending p2wkh, p2wsh, and
// also nested p2sh outputs.
CraftInputScript(signer Signer, txn *wire.MsgTx,
hashCache *txscript.TxSigHashes,
txinIdx int) (*Script, error)
// BlocksToMaturity returns the relative timelock, as a number of
// blocks, that must be built on top of the confirmation height before
// the output can be spent. For non-CSV locked inputs this is always
// zero.
BlocksToMaturity() uint32
// HeightHint returns the minimum height at which a confirmed spending
// tx can occur.
HeightHint() uint32
}
type inputKit struct {
outpoint wire.OutPoint
witnessType WitnessType
signDesc SignDescriptor
heightHint uint32
}
// OutPoint returns the breached output's identifier that is to be included as
// a transaction input.
func (i *inputKit) OutPoint() *wire.OutPoint {
return &i.outpoint
}
// WitnessType returns the type of witness that must be generated to spend the
// breached output.
func (i *inputKit) WitnessType() WitnessType {
return i.witnessType
}
// SignDesc returns the breached output's SignDescriptor, which is used during
// signing to compute the witness.
func (i *inputKit) SignDesc() *SignDescriptor {
return &i.signDesc
}
// HeightHint returns the minimum height at which a confirmed spending
// tx can occur.
func (i *inputKit) HeightHint() uint32 {
return i.heightHint
}
// BaseInput contains all the information needed to sweep a basic output
// (CSV/CLTV/no time lock)
type BaseInput struct {
inputKit
}
// MakeBaseInput assembles a new BaseInput that can be used to construct a
// sweep transaction.
func MakeBaseInput(outpoint *wire.OutPoint, witnessType WitnessType,
signDescriptor *SignDescriptor, heightHint uint32) BaseInput {
return BaseInput{
inputKit{
outpoint: *outpoint,
witnessType: witnessType,
signDesc: *signDescriptor,
heightHint: heightHint,
},
}
}
// NewBaseInput allocates and assembles a new *BaseInput that can be used to
// construct a sweep transaction.
func NewBaseInput(outpoint *wire.OutPoint, witnessType WitnessType,
signDescriptor *SignDescriptor, heightHint uint32) *BaseInput {
input := MakeBaseInput(
outpoint, witnessType, signDescriptor, heightHint,
)
return &input
}
// CraftInputScript returns a valid set of input scripts allowing this output
// to be spent. The returned input scripts should target the input at location
// txIndex within the passed transaction. The input scripts generated by this
// method support spending p2wkh, p2wsh, and also nested p2sh outputs.
func (bi *BaseInput) CraftInputScript(signer Signer, txn *wire.MsgTx,
hashCache *txscript.TxSigHashes, txinIdx int) (*Script, error) {
witnessFunc := bi.witnessType.GenWitnessFunc(
signer, bi.SignDesc(),
)
return witnessFunc(txn, hashCache, txinIdx)
}
// BlocksToMaturity returns the relative timelock, as a number of blocks, that
// must be built on top of the confirmation height before the output can be
// spent. For non-CSV locked inputs this is always zero.
func (bi *BaseInput) BlocksToMaturity() uint32 {
return 0
}
// HtlcSucceedInput constitutes a sweep input that needs a pre-image. The input
// is expected to reside on the commitment tx of the remote party and should
// not be a second level tx output.
type HtlcSucceedInput struct {
inputKit
preimage []byte
}
// MakeHtlcSucceedInput assembles a new redeem input that can be used to
// construct a sweep transaction.
func MakeHtlcSucceedInput(outpoint *wire.OutPoint,
signDescriptor *SignDescriptor,
preimage []byte, heightHint uint32) HtlcSucceedInput {
return HtlcSucceedInput{
inputKit: inputKit{
outpoint: *outpoint,
witnessType: HtlcAcceptedRemoteSuccess,
signDesc: *signDescriptor,
heightHint: heightHint,
},
preimage: preimage,
}
}
// CraftInputScript returns a valid set of input scripts allowing this output
// to be spent. The returns input scripts should target the input at location
// txIndex within the passed transaction. The input scripts generated by this
// method support spending p2wkh, p2wsh, and also nested p2sh outputs.
func (h *HtlcSucceedInput) CraftInputScript(signer Signer, txn *wire.MsgTx,
hashCache *txscript.TxSigHashes, txinIdx int) (*Script, error) {
desc := h.signDesc
desc.SigHashes = hashCache
desc.InputIndex = txinIdx
witness, err := SenderHtlcSpendRedeem(
signer, &desc, txn, h.preimage,
)
if err != nil {
return nil, err
}
return &Script{
Witness: witness,
}, nil
}
// BlocksToMaturity returns the relative timelock, as a number of blocks, that
// must be built on top of the confirmation height before the output can be
// spent.
func (h *HtlcSucceedInput) BlocksToMaturity() uint32 {
return 0
}
// Compile-time constraints to ensure each input struct implement the Input
// interface.
var _ Input = (*BaseInput)(nil)
var _ Input = (*HtlcSucceedInput)(nil)