forked from ltcsuite/ltcd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mwebtx.go
136 lines (121 loc) · 3.11 KB
/
mwebtx.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
package wire
import (
"errors"
"io"
"github.com/ltcmweb/ltcd/ltcutil/mweb/mw"
)
type (
MwebTxBody struct {
Inputs []*MwebInput
Outputs []*MwebOutput
Kernels []*MwebKernel
}
MwebTx struct {
KernelOffset mw.BlindingFactor
StealthOffset mw.BlindingFactor
TxBody *MwebTxBody
}
)
// Reads a litecoin mweb txbody from r. See Deserialize for
// decoding mweb txbodys stored to disk, such as in a database,
// as opposed to decoding from the wire.
func (tb *MwebTxBody) read(r io.Reader, pver uint32) (err error) {
var count uint64
if count, err = ReadVarInt(r, pver); err != nil {
return
}
if count > maxTxInPerMessage {
return errors.New("too many inputs")
}
tb.Inputs = make([]*MwebInput, count)
for i := range tb.Inputs {
tb.Inputs[i] = &MwebInput{}
if err = tb.Inputs[i].read(r, pver); err != nil {
return
}
}
if count, err = ReadVarInt(r, pver); err != nil {
return
}
if count > maxTxOutPerMessage {
return errors.New("too many outputs")
}
tb.Outputs = make([]*MwebOutput, count)
for i := range tb.Outputs {
tb.Outputs[i] = &MwebOutput{}
if err = tb.Outputs[i].read(r, pver, false); err != nil {
return
}
}
if count, err = ReadVarInt(r, pver); err != nil {
return
}
if count > maxTxPerBlock {
return errors.New("too many kernels")
}
tb.Kernels = make([]*MwebKernel, count)
for i := range tb.Kernels {
tb.Kernels[i] = &MwebKernel{}
if err = tb.Kernels[i].read(r, pver); err != nil {
return
}
}
return
}
// Writes a litecoin mweb txbody to w. See Serialize for
// encoding mweb txbodys to be stored to disk, such as in
// a database, as opposed to encoding for the wire.
func (tb *MwebTxBody) write(w io.Writer, pver uint32) (err error) {
if err = WriteVarInt(w, pver, uint64(len(tb.Inputs))); err != nil {
return
}
for i := range tb.Inputs {
if err = tb.Inputs[i].write(w, pver); err != nil {
return
}
}
if err = WriteVarInt(w, pver, uint64(len(tb.Outputs))); err != nil {
return
}
for i := range tb.Outputs {
if err = tb.Outputs[i].write(w, pver, false, false); err != nil {
return
}
}
if err = WriteVarInt(w, pver, uint64(len(tb.Kernels))); err != nil {
return
}
for i := range tb.Kernels {
if err = tb.Kernels[i].write(w, pver, false); err != nil {
return
}
}
return
}
// Reads a litecoin mweb tx from r. See Deserialize for
// decoding mweb txns stored to disk, such as in a database,
// as opposed to decoding from the wire.
func (tx *MwebTx) read(r io.Reader, pver uint32) error {
err := readElements(r, tx.KernelOffset[:], tx.StealthOffset[:])
if err != nil {
return err
}
tx.TxBody = &MwebTxBody{}
if err = tx.TxBody.read(r, pver); err != nil {
return err
}
if len(tx.TxBody.Kernels) < 1 {
return errors.New("transaction requires at least one kernel")
}
return nil
}
// Writes a litecoin mweb tx to w. See Serialize for
// encoding mweb txns to be stored to disk, such as in
// a database, as opposed to encoding for the wire.
func (tx *MwebTx) write(w io.Writer, pver uint32) error {
err := writeElements(w, tx.KernelOffset[:], tx.StealthOffset[:])
if err != nil {
return err
}
return tx.TxBody.write(w, pver)
}