diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index c50e29584..504bebd1e 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -1454,7 +1454,7 @@ func appendTokenTransfer(cache *dao.Simple, transCache map[util.Uint160]transfer *nextBatch++ *currTimestamp = bTimestamp // Put makes a copy of it anyway. - log.Raw = log.Raw[:0] + log.Reset() } transCache[addr] = transferData return nil diff --git a/pkg/core/state/tokens.go b/pkg/core/state/tokens.go index c81d4e32d..81739ccdf 100644 --- a/pkg/core/state/tokens.go +++ b/pkg/core/state/tokens.go @@ -16,6 +16,8 @@ const TokenTransferBatchSize = 128 // TokenTransferLog is a serialized log of token transfers. type TokenTransferLog struct { Raw []byte + buf *bytes.Buffer + iow *io.BinWriter } // NEP17Transfer represents a single NEP-17 Transfer event. @@ -111,18 +113,30 @@ func (lg *TokenTransferLog) Append(tr io.Serializable) error { lg.Raw = append(lg.Raw, 0) } - b := bytes.NewBuffer(lg.Raw) - w := io.NewBinWriterFromIO(b) - - tr.EncodeBinary(w) - if w.Err != nil { - return w.Err + if lg.buf == nil { + lg.buf = bytes.NewBuffer(lg.Raw) } - lg.Raw = b.Bytes() + if lg.iow == nil { + lg.iow = io.NewBinWriterFromIO(lg.buf) + } + + tr.EncodeBinary(lg.iow) + if lg.iow.Err != nil { + return lg.iow.Err + } + lg.Raw = lg.buf.Bytes() lg.Raw[0]++ return nil } +// Reset resets the state of the log, clearing all entries, but keeping existing +// buffer for future writes. +func (lg *TokenTransferLog) Reset() { + lg.Raw = lg.Raw[:0] + lg.buf = nil + lg.iow = nil +} + // ForEachNEP11 iterates over a transfer log returning on the first error. func (lg *TokenTransferLog) ForEachNEP11(f func(*NEP11Transfer) (bool, error)) (bool, error) { if lg == nil || len(lg.Raw) == 0 {