diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index a0aba8148..732ddfcc5 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -972,12 +972,12 @@ func (bc *Blockchain) processNEP5Transfer(cache *dao.Cached, tx *transaction.Tra } // GetNEP5TransferLog returns NEP5 transfer log for the acc. -func (bc *Blockchain) GetNEP5TransferLog(acc util.Uint160) *state.NEP5TransferLog { +func (bc *Blockchain) GetNEP5TransferLog(acc util.Uint160) *state.TransferLog { balances, err := bc.dao.GetNEP5Balances(acc) if err != nil { return nil } - result := new(state.NEP5TransferLog) + result := new(state.TransferLog) for i := uint32(0); i <= balances.NextTransferBatch; i++ { lg, err := bc.dao.GetNEP5TransferLog(acc, i) if err != nil { diff --git a/pkg/core/blockchainer.go b/pkg/core/blockchainer.go index ea64853c9..6abbe4c23 100644 --- a/pkg/core/blockchainer.go +++ b/pkg/core/blockchainer.go @@ -36,7 +36,7 @@ type Blockchainer interface { GetAccountState(util.Uint160) *state.Account GetAppExecResult(util.Uint256) (*state.AppExecResult, error) GetNEP5Metadata(util.Uint160) (*state.NEP5Metadata, error) - GetNEP5TransferLog(util.Uint160) *state.NEP5TransferLog + GetNEP5TransferLog(util.Uint160) *state.TransferLog GetNEP5Balances(util.Uint160) *state.NEP5Balances GetValidators(txes ...*transaction.Transaction) ([]*keys.PublicKey, error) GetScriptHashesForVerifying(*transaction.Transaction) ([]util.Uint160, error) diff --git a/pkg/core/dao/cacheddao.go b/pkg/core/dao/cacheddao.go index f75368d2b..6d806c80b 100644 --- a/pkg/core/dao/cacheddao.go +++ b/pkg/core/dao/cacheddao.go @@ -20,7 +20,7 @@ type Cached struct { contracts map[util.Uint160]*state.Contract unspents map[util.Uint256]*state.UnspentCoin balances map[util.Uint160]*state.NEP5Balances - nep5transfers map[util.Uint160]map[uint32]*state.NEP5TransferLog + nep5transfers map[util.Uint160]map[uint32]*state.TransferLog storage *itemCache dropNEP5Cache bool @@ -32,7 +32,7 @@ func NewCached(d DAO) *Cached { ctrs := make(map[util.Uint160]*state.Contract) unspents := make(map[util.Uint256]*state.UnspentCoin) balances := make(map[util.Uint160]*state.NEP5Balances) - nep5transfers := make(map[util.Uint160]map[uint32]*state.NEP5TransferLog) + nep5transfers := make(map[util.Uint160]map[uint32]*state.TransferLog) st := newItemCache() dao := d.GetWrapped() if cd, ok := dao.(*Cached); ok { @@ -120,8 +120,8 @@ func (cd *Cached) PutNEP5Balances(acc util.Uint160, bs *state.NEP5Balances) erro return nil } -// GetNEP5TransferLog retrieves NEP5TransferLog for the acc. -func (cd *Cached) GetNEP5TransferLog(acc util.Uint160, index uint32) (*state.NEP5TransferLog, error) { +// GetNEP5TransferLog retrieves TransferLog for the acc. +func (cd *Cached) GetNEP5TransferLog(acc util.Uint160, index uint32) (*state.TransferLog, error) { ts := cd.nep5transfers[acc] if ts != nil && ts[index] != nil { return ts[index], nil @@ -129,11 +129,11 @@ func (cd *Cached) GetNEP5TransferLog(acc util.Uint160, index uint32) (*state.NEP return cd.DAO.GetNEP5TransferLog(acc, index) } -// PutNEP5TransferLog saves NEP5TransferLog for the acc. -func (cd *Cached) PutNEP5TransferLog(acc util.Uint160, index uint32, bs *state.NEP5TransferLog) error { +// PutNEP5TransferLog saves TransferLog for the acc. +func (cd *Cached) PutNEP5TransferLog(acc util.Uint160, index uint32, bs *state.TransferLog) error { ts := cd.nep5transfers[acc] if ts == nil { - ts = make(map[uint32]*state.NEP5TransferLog, 2) + ts = make(map[uint32]*state.TransferLog, 2) cd.nep5transfers[acc] = ts } ts[index] = bs diff --git a/pkg/core/dao/dao.go b/pkg/core/dao/dao.go index 726b036b8..dee1995ee 100644 --- a/pkg/core/dao/dao.go +++ b/pkg/core/dao/dao.go @@ -36,7 +36,7 @@ type DAO interface { GetHeaderHashes() ([]util.Uint256, error) GetNEP5Balances(acc util.Uint160) (*state.NEP5Balances, error) GetNEP5Metadata(h util.Uint160) (*state.NEP5Metadata, error) - GetNEP5TransferLog(acc util.Uint160, index uint32) (*state.NEP5TransferLog, error) + GetNEP5TransferLog(acc util.Uint160, index uint32) (*state.TransferLog, error) GetStateRoot(height uint32) (*state.MPTRootState, error) PutStateRoot(root *state.MPTRootState) error GetStorageItem(scripthash util.Uint160, key []byte) *state.StorageItem @@ -60,7 +60,7 @@ type DAO interface { PutCurrentHeader(hashAndIndex []byte) error PutNEP5Balances(acc util.Uint160, bs *state.NEP5Balances) error PutNEP5Metadata(h util.Uint160, meta *state.NEP5Metadata) error - PutNEP5TransferLog(acc util.Uint160, index uint32, lg *state.NEP5TransferLog) error + PutNEP5TransferLog(acc util.Uint160, index uint32, lg *state.TransferLog) error PutStorageItem(scripthash util.Uint160, key []byte, si *state.StorageItem) error PutUnspentCoinState(hash util.Uint256, ucs *state.UnspentCoin) error PutValidatorState(vs *state.Validator) error @@ -262,7 +262,7 @@ func (dao *Simple) putNEP5Balances(acc util.Uint160, bs *state.NEP5Balances, buf // -- start transfer log. -const nep5TransferBatchSize = 128 +const nep5TransferBatchSize = 128 * state.NEP5TransferSize func getNEP5TransferLogKey(acc util.Uint160, index uint32) []byte { key := make([]byte, 1+util.Uint160Size+4) @@ -273,20 +273,20 @@ func getNEP5TransferLogKey(acc util.Uint160, index uint32) []byte { } // GetNEP5TransferLog retrieves transfer log from the cache. -func (dao *Simple) GetNEP5TransferLog(acc util.Uint160, index uint32) (*state.NEP5TransferLog, error) { +func (dao *Simple) GetNEP5TransferLog(acc util.Uint160, index uint32) (*state.TransferLog, error) { key := getNEP5TransferLogKey(acc, index) value, err := dao.Store.Get(key) if err != nil { if err == storage.ErrKeyNotFound { - return new(state.NEP5TransferLog), nil + return new(state.TransferLog), nil } return nil, err } - return &state.NEP5TransferLog{Raw: value}, nil + return &state.TransferLog{Raw: value}, nil } // PutNEP5TransferLog saves given transfer log in the cache. -func (dao *Simple) PutNEP5TransferLog(acc util.Uint160, index uint32, lg *state.NEP5TransferLog) error { +func (dao *Simple) PutNEP5TransferLog(acc util.Uint160, index uint32, lg *state.TransferLog) error { key := getNEP5TransferLogKey(acc, index) return dao.Store.Put(key, lg.Raw) } @@ -299,7 +299,7 @@ func (dao *Simple) AppendNEP5Transfer(acc util.Uint160, index uint32, tr *state. if err != storage.ErrKeyNotFound { return false, err } - lg = new(state.NEP5TransferLog) + lg = new(state.TransferLog) } if err := lg.Append(tr); err != nil { return false, err diff --git a/pkg/core/state/nep5.go b/pkg/core/state/nep5.go index a3e510f40..0ef8543f5 100644 --- a/pkg/core/state/nep5.go +++ b/pkg/core/state/nep5.go @@ -14,8 +14,8 @@ type NEP5Tracker struct { LastUpdatedBlock uint32 } -// NEP5TransferLog is a log of NEP5 token transfers for the specific command. -type NEP5TransferLog struct { +// TransferLog is a log of NEP5 token transfers for the specific command. +type TransferLog struct { Raw []byte } @@ -99,7 +99,7 @@ func (bs *NEP5Metadata) EncodeBinary(w *io.BinWriter) { } // Append appends single transfer to a log. -func (lg *NEP5TransferLog) Append(tr *NEP5Transfer) error { +func (lg *TransferLog) Append(tr io.Serializable) error { w := io.NewBufBinWriter() tr.EncodeBinary(w.BinWriter) if w.Err != nil { @@ -110,26 +110,25 @@ func (lg *NEP5TransferLog) Append(tr *NEP5Transfer) error { } // ForEach iterates over transfer log returning on first error. -func (lg *NEP5TransferLog) ForEach(f func(*NEP5Transfer) error) error { +func (lg *TransferLog) ForEach(size int, tr io.Serializable, f func() error) error { if lg == nil { return nil } - tr := new(NEP5Transfer) - for i := 0; i < len(lg.Raw); i += NEP5TransferSize { - r := io.NewBinReaderFromBuf(lg.Raw[i : i+NEP5TransferSize]) + for i := 0; i < len(lg.Raw); i += size { + r := io.NewBinReaderFromBuf(lg.Raw[i : i+size]) tr.DecodeBinary(r) if r.Err != nil { return r.Err - } else if err := f(tr); err != nil { + } else if err := f(); err != nil { return nil } } return nil } -// Size returns an amount of transfer written in log. -func (lg *NEP5TransferLog) Size() int { - return len(lg.Raw) / NEP5TransferSize +// Size returns an amount of transfer written in log provided size of a single transfer. +func (lg *TransferLog) Size() int { + return len(lg.Raw) } // EncodeBinary implements io.Serializable interface. diff --git a/pkg/core/state/nep5_test.go b/pkg/core/state/nep5_test.go index 543d05819..92ae689ea 100644 --- a/pkg/core/state/nep5_test.go +++ b/pkg/core/state/nep5_test.go @@ -21,15 +21,16 @@ func TestNEP5TransferLog_Append(t *testing.T) { randomTransfer(r), } - lg := new(NEP5TransferLog) + lg := new(TransferLog) for _, tr := range expected { require.NoError(t, lg.Append(tr)) } - require.Equal(t, len(expected), lg.Size()) + require.Equal(t, len(expected), lg.Size()/NEP5TransferSize) i := 0 - err := lg.ForEach(func(tr *NEP5Transfer) error { + tr := new(NEP5Transfer) + err := lg.ForEach(NEP5TransferSize, tr, func() error { require.Equal(t, expected[i], tr) i++ return nil diff --git a/pkg/network/helper_test.go b/pkg/network/helper_test.go index 2789364df..5ee0c456d 100644 --- a/pkg/network/helper_test.go +++ b/pkg/network/helper_test.go @@ -96,7 +96,7 @@ func (chain testChain) GetAccountState(util.Uint160) *state.Account { func (chain testChain) GetNEP5Metadata(util.Uint160) (*state.NEP5Metadata, error) { panic("TODO") } -func (chain testChain) GetNEP5TransferLog(util.Uint160) *state.NEP5TransferLog { +func (chain testChain) GetNEP5TransferLog(util.Uint160) *state.TransferLog { panic("TODO") } func (chain testChain) GetNEP5Balances(util.Uint160) *state.NEP5Balances { diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index 752652280..4cce469d8 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -598,7 +598,8 @@ func (s *Server) getNEP5Transfers(ps request.Params) (interface{}, *response.Err Sent: []result.NEP5Transfer{}, } lg := s.chain.GetNEP5TransferLog(u) - err = lg.ForEach(func(tr *state.NEP5Transfer) error { + tr := new(state.NEP5Transfer) + err = lg.ForEach(state.NEP5TransferSize, tr, func() error { transfer := result.NEP5Transfer{ Timestamp: tr.Timestamp, Asset: tr.Asset,