109 lines
2.3 KiB
Go
109 lines
2.3 KiB
Go
package transaction
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"errors"
|
|
"fmt"
|
|
"git.gammaspectra.live/P2Pool/consensus/v3/monero/crypto"
|
|
"git.gammaspectra.live/P2Pool/consensus/v3/utils"
|
|
"io"
|
|
)
|
|
|
|
type Outputs []Output
|
|
|
|
func (s *Outputs) FromReader(reader utils.ReaderAndByteReader) (err error) {
|
|
var outputCount uint64
|
|
|
|
if outputCount, err = binary.ReadUvarint(reader); err != nil {
|
|
return err
|
|
}
|
|
|
|
if outputCount > 0 {
|
|
if outputCount < 8192 {
|
|
*s = make(Outputs, 0, outputCount)
|
|
}
|
|
|
|
var o Output
|
|
for index := 0; index < int(outputCount); index++ {
|
|
o.Index = uint64(index)
|
|
|
|
if o.Reward, err = binary.ReadUvarint(reader); err != nil {
|
|
return err
|
|
}
|
|
|
|
if o.Type, err = reader.ReadByte(); err != nil {
|
|
return err
|
|
}
|
|
|
|
switch o.Type {
|
|
case TxOutToTaggedKey, TxOutToKey:
|
|
if _, err = io.ReadFull(reader, o.EphemeralPublicKey[:]); err != nil {
|
|
return err
|
|
}
|
|
|
|
if o.Type == TxOutToTaggedKey {
|
|
if o.ViewTag, err = reader.ReadByte(); err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
o.ViewTag = 0
|
|
}
|
|
default:
|
|
return fmt.Errorf("unknown %d TXOUT key", o.Type)
|
|
}
|
|
|
|
*s = append(*s, o)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *Outputs) BufferLength() (n int) {
|
|
n = utils.UVarInt64Size(len(*s))
|
|
for _, o := range *s {
|
|
n += utils.UVarInt64Size(o.Reward) +
|
|
1 +
|
|
crypto.PublicKeySize
|
|
if o.Type == TxOutToTaggedKey {
|
|
n++
|
|
}
|
|
}
|
|
return n
|
|
}
|
|
|
|
func (s *Outputs) MarshalBinary() (data []byte, err error) {
|
|
return s.AppendBinary(make([]byte, 0, s.BufferLength()))
|
|
}
|
|
|
|
func (s *Outputs) AppendBinary(preAllocatedBuf []byte) (data []byte, err error) {
|
|
data = preAllocatedBuf
|
|
|
|
data = binary.AppendUvarint(data, uint64(len(*s)))
|
|
|
|
for _, o := range *s {
|
|
data = binary.AppendUvarint(data, o.Reward)
|
|
data = append(data, o.Type)
|
|
|
|
switch o.Type {
|
|
case TxOutToTaggedKey, TxOutToKey:
|
|
data = append(data, o.EphemeralPublicKey[:]...)
|
|
|
|
if o.Type == TxOutToTaggedKey {
|
|
data = append(data, o.ViewTag)
|
|
}
|
|
default:
|
|
return nil, errors.New("unknown output type")
|
|
}
|
|
}
|
|
return data, nil
|
|
}
|
|
|
|
type Output struct {
|
|
Index uint64 `json:"index"`
|
|
Reward uint64 `json:"reward"`
|
|
// Type would be here
|
|
EphemeralPublicKey crypto.PublicKeyBytes `json:"ephemeral_public_key"`
|
|
// Type re-arranged here to improve memory layout space
|
|
Type uint8 `json:"type"`
|
|
ViewTag uint8 `json:"view_tag"`
|
|
}
|