added limitbytereader to utils, less buffer usage on block decoding
This commit is contained in:
parent
e4be941d5e
commit
0cd75a0509
|
@ -10,6 +10,7 @@ import (
|
|||
"git.gammaspectra.live/P2Pool/p2pool-observer/monero/randomx"
|
||||
"git.gammaspectra.live/P2Pool/p2pool-observer/monero/transaction"
|
||||
"git.gammaspectra.live/P2Pool/p2pool-observer/types"
|
||||
"git.gammaspectra.live/P2Pool/p2pool-observer/utils"
|
||||
"io"
|
||||
)
|
||||
|
||||
|
@ -39,11 +40,6 @@ type Header struct {
|
|||
Id types.Hash `json:"id"`
|
||||
}
|
||||
|
||||
type readerAndByteReader interface {
|
||||
io.Reader
|
||||
io.ByteReader
|
||||
}
|
||||
|
||||
func (b *Block) MarshalBinary() (buf []byte, err error) {
|
||||
return b.MarshalBinaryFlags(false, false)
|
||||
}
|
||||
|
@ -93,11 +89,11 @@ func (b *Block) AppendBinaryFlags(preAllocatedBuf []byte, pruned, compact bool)
|
|||
return buf, nil
|
||||
}
|
||||
|
||||
func (b *Block) FromReader(reader readerAndByteReader) (err error) {
|
||||
func (b *Block) FromReader(reader utils.ReaderAndByteReader) (err error) {
|
||||
return b.FromReaderFlags(reader, false)
|
||||
}
|
||||
|
||||
func (b *Block) FromCompactReader(reader readerAndByteReader) (err error) {
|
||||
func (b *Block) FromCompactReader(reader utils.ReaderAndByteReader) (err error) {
|
||||
return b.FromReaderFlags(reader, true)
|
||||
}
|
||||
|
||||
|
@ -106,7 +102,7 @@ func (b *Block) UnmarshalBinary(data []byte) error {
|
|||
return b.FromReader(reader)
|
||||
}
|
||||
|
||||
func (b *Block) FromReaderFlags(reader readerAndByteReader, compact bool) (err error) {
|
||||
func (b *Block) FromReaderFlags(reader utils.ReaderAndByteReader, compact bool) (err error) {
|
||||
var (
|
||||
txCount uint64
|
||||
transactionHash types.Hash
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"git.gammaspectra.live/P2Pool/p2pool-observer/monero"
|
||||
"git.gammaspectra.live/P2Pool/p2pool-observer/monero/crypto"
|
||||
"git.gammaspectra.live/P2Pool/p2pool-observer/types"
|
||||
"io"
|
||||
"git.gammaspectra.live/P2Pool/p2pool-observer/utils"
|
||||
"sync"
|
||||
)
|
||||
|
||||
|
@ -32,17 +32,12 @@ type CoinbaseTransaction struct {
|
|||
ExtraBaseRCT uint8 `json:"extra_base_rct"`
|
||||
}
|
||||
|
||||
type readerAndByteReader interface {
|
||||
io.Reader
|
||||
io.ByteReader
|
||||
}
|
||||
|
||||
func (c *CoinbaseTransaction) UnmarshalBinary(data []byte) error {
|
||||
reader := bytes.NewReader(data)
|
||||
return c.FromReader(reader)
|
||||
}
|
||||
|
||||
func (c *CoinbaseTransaction) FromReader(reader readerAndByteReader) (err error) {
|
||||
func (c *CoinbaseTransaction) FromReader(reader utils.ReaderAndByteReader) (err error) {
|
||||
var (
|
||||
txExtraSize uint64
|
||||
)
|
||||
|
@ -121,12 +116,12 @@ func (c *CoinbaseTransaction) FromReader(reader readerAndByteReader) (err error)
|
|||
return errors.New("tx extra too large")
|
||||
}
|
||||
|
||||
txExtra := make([]byte, txExtraSize)
|
||||
if _, err = io.ReadFull(reader, txExtra); err != nil {
|
||||
limitReader := utils.LimitByteReader(reader, int64(txExtraSize))
|
||||
if err = c.Extra.FromReader(limitReader); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = c.Extra.UnmarshalBinary(txExtra); err != nil {
|
||||
return err
|
||||
if limitReader.Left() > 0 {
|
||||
return errors.New("bytes leftover in extra data")
|
||||
}
|
||||
if err = binary.Read(reader, binary.LittleEndian, &c.ExtraBaseRCT); err != nil {
|
||||
return err
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"fmt"
|
||||
"git.gammaspectra.live/P2Pool/p2pool-observer/monero/crypto"
|
||||
"git.gammaspectra.live/P2Pool/p2pool-observer/types"
|
||||
"git.gammaspectra.live/P2Pool/p2pool-observer/utils"
|
||||
"io"
|
||||
)
|
||||
|
||||
|
@ -78,7 +79,7 @@ func (t *ExtraTags) SideChainHashingBlob(preAllocatedBuf []byte, zeroTemplateId
|
|||
return buf, nil
|
||||
}
|
||||
|
||||
func (t *ExtraTags) FromReader(reader readerAndByteReader) (err error) {
|
||||
func (t *ExtraTags) FromReader(reader utils.ReaderAndByteReader) (err error) {
|
||||
var tag ExtraTag
|
||||
for {
|
||||
if err = tag.FromReader(reader); err != nil {
|
||||
|
@ -148,7 +149,7 @@ func (t *ExtraTag) SideChainHashingBlob(preAllocatedBuf []byte, zeroTemplateId b
|
|||
return buf, nil
|
||||
}
|
||||
|
||||
func (t *ExtraTag) FromReader(reader readerAndByteReader) (err error) {
|
||||
func (t *ExtraTag) FromReader(reader utils.ReaderAndByteReader) (err error) {
|
||||
|
||||
if err = binary.Read(reader, binary.LittleEndian, &t.Tag); err != nil {
|
||||
return err
|
||||
|
|
|
@ -5,12 +5,13 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"git.gammaspectra.live/P2Pool/p2pool-observer/monero/crypto"
|
||||
"git.gammaspectra.live/P2Pool/p2pool-observer/utils"
|
||||
"io"
|
||||
)
|
||||
|
||||
type Outputs []Output
|
||||
|
||||
func (s *Outputs) FromReader(reader readerAndByteReader) (err error) {
|
||||
func (s *Outputs) FromReader(reader utils.ReaderAndByteReader) (err error) {
|
||||
var outputCount uint64
|
||||
|
||||
if outputCount, err = binary.ReadUvarint(reader); err != nil {
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"git.gammaspectra.live/P2Pool/p2pool-observer/monero/transaction"
|
||||
p2poolcrypto "git.gammaspectra.live/P2Pool/p2pool-observer/p2pool/crypto"
|
||||
"git.gammaspectra.live/P2Pool/p2pool-observer/types"
|
||||
"git.gammaspectra.live/P2Pool/p2pool-observer/utils"
|
||||
"golang.org/x/exp/slices"
|
||||
"io"
|
||||
"sync"
|
||||
|
@ -463,7 +464,7 @@ func (b *PoolBlock) AppendBinaryFlags(preAllocatedBuf []byte, pruned, compact bo
|
|||
}
|
||||
}
|
||||
|
||||
func (b *PoolBlock) FromReader(consensus *Consensus, derivationCache DerivationCacheInterface, reader readerAndByteReader) (err error) {
|
||||
func (b *PoolBlock) FromReader(consensus *Consensus, derivationCache DerivationCacheInterface, reader utils.ReaderAndByteReader) (err error) {
|
||||
if err = b.Main.FromReader(reader); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -489,7 +490,7 @@ func (b *PoolBlock) FromReader(consensus *Consensus, derivationCache DerivationC
|
|||
}
|
||||
|
||||
// FromCompactReader used in Protocol 1.1 and above
|
||||
func (b *PoolBlock) FromCompactReader(consensus *Consensus, derivationCache DerivationCacheInterface, reader readerAndByteReader) (err error) {
|
||||
func (b *PoolBlock) FromCompactReader(consensus *Consensus, derivationCache DerivationCacheInterface, reader utils.ReaderAndByteReader) (err error) {
|
||||
if err = b.Main.FromCompactReader(reader); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -675,7 +676,7 @@ type poolBlockCache struct {
|
|||
powHash types.Hash
|
||||
}
|
||||
|
||||
func (c *poolBlockCache) FromReader(reader readerAndByteReader) (err error) {
|
||||
func (c *poolBlockCache) FromReader(reader utils.ReaderAndByteReader) (err error) {
|
||||
buf := make([]byte, types.HashSize*3+types.DifficultySize+FullIdSize)
|
||||
if _, err = reader.Read(buf); err != nil {
|
||||
return err
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"git.gammaspectra.live/P2Pool/p2pool-observer/monero/crypto"
|
||||
p2pooltypes "git.gammaspectra.live/P2Pool/p2pool-observer/p2pool/types"
|
||||
"git.gammaspectra.live/P2Pool/p2pool-observer/types"
|
||||
"git.gammaspectra.live/P2Pool/p2pool-observer/utils"
|
||||
"io"
|
||||
)
|
||||
|
||||
|
@ -31,11 +32,6 @@ type SideData struct {
|
|||
}
|
||||
}
|
||||
|
||||
type readerAndByteReader interface {
|
||||
io.Reader
|
||||
io.ByteReader
|
||||
}
|
||||
|
||||
func (b *SideData) BufferLength() int {
|
||||
return crypto.PublicKeySize + crypto.PublicKeySize + types.HashSize + types.HashSize + binary.MaxVarintLen64 + len(b.Uncles)*types.HashSize + binary.MaxVarintLen64 + binary.MaxVarintLen64 + binary.MaxVarintLen64 + binary.MaxVarintLen64 + binary.MaxVarintLen64 + 4*4
|
||||
}
|
||||
|
@ -73,7 +69,7 @@ func (b *SideData) AppendBinary(preAllocatedBuf []byte, version ShareVersion) (b
|
|||
return buf, nil
|
||||
}
|
||||
|
||||
func (b *SideData) FromReader(reader readerAndByteReader, version ShareVersion) (err error) {
|
||||
func (b *SideData) FromReader(reader utils.ReaderAndByteReader, version ShareVersion) (err error) {
|
||||
var (
|
||||
uncleCount uint64
|
||||
uncleHash types.Hash
|
||||
|
|
49
utils/limitreader.go
Normal file
49
utils/limitreader.go
Normal file
|
@ -0,0 +1,49 @@
|
|||
package utils
|
||||
|
||||
import "io"
|
||||
|
||||
type ReaderAndByteReader interface {
|
||||
io.Reader
|
||||
io.ByteReader
|
||||
}
|
||||
|
||||
// LimitByteReader returns a Reader that reads from r
|
||||
// but stops with EOF after n bytes.
|
||||
// The underlying implementation is a *LimitedReader.
|
||||
func LimitByteReader(r ReaderAndByteReader, n int64) *LimitedByteReader {
|
||||
return &LimitedByteReader{r, n}
|
||||
}
|
||||
|
||||
// A LimitedByteReader reads from R but limits the amount of
|
||||
// data returned to just N bytes. Each call to Read
|
||||
// updates N to reflect the new amount remaining.
|
||||
// Read returns EOF when N <= 0 or when the underlying R returns EOF.
|
||||
type LimitedByteReader struct {
|
||||
R ReaderAndByteReader // underlying reader
|
||||
N int64 // max bytes remaining
|
||||
}
|
||||
|
||||
func (l *LimitedByteReader) Read(p []byte) (n int, err error) {
|
||||
if l.N <= 0 {
|
||||
return 0, io.EOF
|
||||
}
|
||||
if int64(len(p)) > l.N {
|
||||
p = p[0:l.N]
|
||||
}
|
||||
n, err = l.R.Read(p)
|
||||
l.N -= int64(n)
|
||||
return
|
||||
}
|
||||
|
||||
func (l *LimitedByteReader) ReadByte() (v uint8, err error) {
|
||||
if l.N <= 0 {
|
||||
return 0, io.EOF
|
||||
}
|
||||
v, err = l.R.ReadByte()
|
||||
l.N--
|
||||
return
|
||||
}
|
||||
|
||||
func (l *LimitedByteReader) Left() int64 {
|
||||
return l.N
|
||||
}
|
Loading…
Reference in a new issue