state: store the length of NEP5TransferLog in the first byte

We lose `size` field after serialization/deserialization which can lead to
adding more than NEP5TransferBatchSize elements into the NEP5TransferLog.
This commit is contained in:
Roman Khimov 2020-09-21 21:46:40 +03:00
parent 6902003044
commit 806b89db76
3 changed files with 17 additions and 9 deletions

View file

@ -95,7 +95,7 @@ func (cd *Cached) AppendNEP5Transfer(acc util.Uint160, index uint32, tr *state.N
if err := lg.Append(tr); err != nil {
return false, err
}
return lg.Size() >= nep5TransferBatchSize, cd.PutNEP5TransferLog(acc, index, lg)
return lg.Size() >= state.NEP5TransferBatchSize, cd.PutNEP5TransferLog(acc, index, lg)
}
// Persist flushes all the changes made into the (supposedly) persistent

View file

@ -208,8 +208,6 @@ func (dao *Simple) putNEP5Balances(acc util.Uint160, bs *state.NEP5Balances, buf
// -- start transfer log.
const nep5TransferBatchSize = 128
func getNEP5TransferLogKey(acc util.Uint160, index uint32) []byte {
key := make([]byte, 1+util.Uint160Size+4)
key[0] = byte(storage.STNEP5Transfers)
@ -250,7 +248,7 @@ func (dao *Simple) AppendNEP5Transfer(acc util.Uint160, index uint32, tr *state.
if err := lg.Append(tr); err != nil {
return false, err
}
return lg.Size() >= nep5TransferBatchSize, dao.PutNEP5TransferLog(acc, index, lg)
return lg.Size() >= state.NEP5TransferBatchSize, dao.PutNEP5TransferLog(acc, index, lg)
}
// -- end transfer log.

View file

@ -8,6 +8,9 @@ import (
"github.com/nspcc-dev/neo-go/pkg/util"
)
// NEP5TransferBatchSize is the maximum number of entries for NEP5TransferLog.
const NEP5TransferBatchSize = 128
// NEP5Tracker contains info about a single account in a NEP5 contract.
type NEP5Tracker struct {
// Balance is the current balance of the account.
@ -20,8 +23,6 @@ type NEP5Tracker struct {
// NEP5TransferLog is a log of NEP5 token transfers for the specific command.
type NEP5TransferLog struct {
Raw []byte
// size is the number of NEP5Transfers written into Raw
size int
}
// NEP5Transfer represents a single NEP5 Transfer event.
@ -85,12 +86,18 @@ func (bs *NEP5Balances) EncodeBinary(w *io.BinWriter) {
// Append appends single transfer to a log.
func (lg *NEP5TransferLog) Append(tr *NEP5Transfer) error {
w := io.NewBufBinWriter()
// The first entry, set up counter.
if len(lg.Raw) == 0 {
w.WriteB(1)
}
tr.EncodeBinary(w.BinWriter)
if w.Err != nil {
return w.Err
}
if len(lg.Raw) != 0 {
lg.Raw[0]++
}
lg.Raw = append(lg.Raw, w.Bytes()...)
lg.size++
return nil
}
@ -101,7 +108,7 @@ func (lg *NEP5TransferLog) ForEach(f func(*NEP5Transfer) error) error {
}
tr := new(NEP5Transfer)
var bytesRead int
for i := 0; i < len(lg.Raw); i += bytesRead {
for i := 1; i < len(lg.Raw); i += bytesRead {
r := io.NewBinReaderFromBuf(lg.Raw[i:])
bytesRead = tr.DecodeBinaryReturnCount(r)
if r.Err != nil {
@ -115,7 +122,10 @@ func (lg *NEP5TransferLog) ForEach(f func(*NEP5Transfer) error) error {
// Size returns an amount of transfer written in log.
func (lg *NEP5TransferLog) Size() int {
return lg.size
if len(lg.Raw) == 0 {
return 0
}
return int(lg.Raw[0])
}
// EncodeBinary implements io.Serializable interface.