forked from TrueCloudLab/neoneo-go
state: make NEP5Transfer log more generic
This commit is contained in:
parent
49f9c4ad7e
commit
e4fcd90b6d
8 changed files with 35 additions and 34 deletions
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue