mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-12-04 19:19:44 +00:00
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.
|
// 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)
|
balances, err := bc.dao.GetNEP5Balances(acc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
result := new(state.NEP5TransferLog)
|
result := new(state.TransferLog)
|
||||||
for i := uint32(0); i <= balances.NextTransferBatch; i++ {
|
for i := uint32(0); i <= balances.NextTransferBatch; i++ {
|
||||||
lg, err := bc.dao.GetNEP5TransferLog(acc, i)
|
lg, err := bc.dao.GetNEP5TransferLog(acc, i)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -36,7 +36,7 @@ type Blockchainer interface {
|
||||||
GetAccountState(util.Uint160) *state.Account
|
GetAccountState(util.Uint160) *state.Account
|
||||||
GetAppExecResult(util.Uint256) (*state.AppExecResult, error)
|
GetAppExecResult(util.Uint256) (*state.AppExecResult, error)
|
||||||
GetNEP5Metadata(util.Uint160) (*state.NEP5Metadata, error)
|
GetNEP5Metadata(util.Uint160) (*state.NEP5Metadata, error)
|
||||||
GetNEP5TransferLog(util.Uint160) *state.NEP5TransferLog
|
GetNEP5TransferLog(util.Uint160) *state.TransferLog
|
||||||
GetNEP5Balances(util.Uint160) *state.NEP5Balances
|
GetNEP5Balances(util.Uint160) *state.NEP5Balances
|
||||||
GetValidators(txes ...*transaction.Transaction) ([]*keys.PublicKey, error)
|
GetValidators(txes ...*transaction.Transaction) ([]*keys.PublicKey, error)
|
||||||
GetScriptHashesForVerifying(*transaction.Transaction) ([]util.Uint160, error)
|
GetScriptHashesForVerifying(*transaction.Transaction) ([]util.Uint160, error)
|
||||||
|
|
|
@ -20,7 +20,7 @@ type Cached struct {
|
||||||
contracts map[util.Uint160]*state.Contract
|
contracts map[util.Uint160]*state.Contract
|
||||||
unspents map[util.Uint256]*state.UnspentCoin
|
unspents map[util.Uint256]*state.UnspentCoin
|
||||||
balances map[util.Uint160]*state.NEP5Balances
|
balances map[util.Uint160]*state.NEP5Balances
|
||||||
nep5transfers map[util.Uint160]map[uint32]*state.NEP5TransferLog
|
nep5transfers map[util.Uint160]map[uint32]*state.TransferLog
|
||||||
storage *itemCache
|
storage *itemCache
|
||||||
|
|
||||||
dropNEP5Cache bool
|
dropNEP5Cache bool
|
||||||
|
@ -32,7 +32,7 @@ func NewCached(d DAO) *Cached {
|
||||||
ctrs := make(map[util.Uint160]*state.Contract)
|
ctrs := make(map[util.Uint160]*state.Contract)
|
||||||
unspents := make(map[util.Uint256]*state.UnspentCoin)
|
unspents := make(map[util.Uint256]*state.UnspentCoin)
|
||||||
balances := make(map[util.Uint160]*state.NEP5Balances)
|
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()
|
st := newItemCache()
|
||||||
dao := d.GetWrapped()
|
dao := d.GetWrapped()
|
||||||
if cd, ok := dao.(*Cached); ok {
|
if cd, ok := dao.(*Cached); ok {
|
||||||
|
@ -120,8 +120,8 @@ func (cd *Cached) PutNEP5Balances(acc util.Uint160, bs *state.NEP5Balances) erro
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNEP5TransferLog retrieves NEP5TransferLog for the acc.
|
// GetNEP5TransferLog retrieves TransferLog for the acc.
|
||||||
func (cd *Cached) GetNEP5TransferLog(acc util.Uint160, index uint32) (*state.NEP5TransferLog, error) {
|
func (cd *Cached) GetNEP5TransferLog(acc util.Uint160, index uint32) (*state.TransferLog, error) {
|
||||||
ts := cd.nep5transfers[acc]
|
ts := cd.nep5transfers[acc]
|
||||||
if ts != nil && ts[index] != nil {
|
if ts != nil && ts[index] != nil {
|
||||||
return 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)
|
return cd.DAO.GetNEP5TransferLog(acc, index)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutNEP5TransferLog saves NEP5TransferLog for the acc.
|
// PutNEP5TransferLog saves TransferLog for the acc.
|
||||||
func (cd *Cached) PutNEP5TransferLog(acc util.Uint160, index uint32, bs *state.NEP5TransferLog) error {
|
func (cd *Cached) PutNEP5TransferLog(acc util.Uint160, index uint32, bs *state.TransferLog) error {
|
||||||
ts := cd.nep5transfers[acc]
|
ts := cd.nep5transfers[acc]
|
||||||
if ts == nil {
|
if ts == nil {
|
||||||
ts = make(map[uint32]*state.NEP5TransferLog, 2)
|
ts = make(map[uint32]*state.TransferLog, 2)
|
||||||
cd.nep5transfers[acc] = ts
|
cd.nep5transfers[acc] = ts
|
||||||
}
|
}
|
||||||
ts[index] = bs
|
ts[index] = bs
|
||||||
|
|
|
@ -36,7 +36,7 @@ type DAO interface {
|
||||||
GetHeaderHashes() ([]util.Uint256, error)
|
GetHeaderHashes() ([]util.Uint256, error)
|
||||||
GetNEP5Balances(acc util.Uint160) (*state.NEP5Balances, error)
|
GetNEP5Balances(acc util.Uint160) (*state.NEP5Balances, error)
|
||||||
GetNEP5Metadata(h util.Uint160) (*state.NEP5Metadata, 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)
|
GetStateRoot(height uint32) (*state.MPTRootState, error)
|
||||||
PutStateRoot(root *state.MPTRootState) error
|
PutStateRoot(root *state.MPTRootState) error
|
||||||
GetStorageItem(scripthash util.Uint160, key []byte) *state.StorageItem
|
GetStorageItem(scripthash util.Uint160, key []byte) *state.StorageItem
|
||||||
|
@ -60,7 +60,7 @@ type DAO interface {
|
||||||
PutCurrentHeader(hashAndIndex []byte) error
|
PutCurrentHeader(hashAndIndex []byte) error
|
||||||
PutNEP5Balances(acc util.Uint160, bs *state.NEP5Balances) error
|
PutNEP5Balances(acc util.Uint160, bs *state.NEP5Balances) error
|
||||||
PutNEP5Metadata(h util.Uint160, meta *state.NEP5Metadata) 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
|
PutStorageItem(scripthash util.Uint160, key []byte, si *state.StorageItem) error
|
||||||
PutUnspentCoinState(hash util.Uint256, ucs *state.UnspentCoin) error
|
PutUnspentCoinState(hash util.Uint256, ucs *state.UnspentCoin) error
|
||||||
PutValidatorState(vs *state.Validator) error
|
PutValidatorState(vs *state.Validator) error
|
||||||
|
@ -262,7 +262,7 @@ func (dao *Simple) putNEP5Balances(acc util.Uint160, bs *state.NEP5Balances, buf
|
||||||
|
|
||||||
// -- start transfer log.
|
// -- start transfer log.
|
||||||
|
|
||||||
const nep5TransferBatchSize = 128
|
const nep5TransferBatchSize = 128 * state.NEP5TransferSize
|
||||||
|
|
||||||
func getNEP5TransferLogKey(acc util.Uint160, index uint32) []byte {
|
func getNEP5TransferLogKey(acc util.Uint160, index uint32) []byte {
|
||||||
key := make([]byte, 1+util.Uint160Size+4)
|
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.
|
// 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)
|
key := getNEP5TransferLogKey(acc, index)
|
||||||
value, err := dao.Store.Get(key)
|
value, err := dao.Store.Get(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == storage.ErrKeyNotFound {
|
if err == storage.ErrKeyNotFound {
|
||||||
return new(state.NEP5TransferLog), nil
|
return new(state.TransferLog), nil
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &state.NEP5TransferLog{Raw: value}, nil
|
return &state.TransferLog{Raw: value}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutNEP5TransferLog saves given transfer log in the cache.
|
// 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)
|
key := getNEP5TransferLogKey(acc, index)
|
||||||
return dao.Store.Put(key, lg.Raw)
|
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 {
|
if err != storage.ErrKeyNotFound {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
lg = new(state.NEP5TransferLog)
|
lg = new(state.TransferLog)
|
||||||
}
|
}
|
||||||
if err := lg.Append(tr); err != nil {
|
if err := lg.Append(tr); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
|
|
|
@ -14,8 +14,8 @@ type NEP5Tracker struct {
|
||||||
LastUpdatedBlock uint32
|
LastUpdatedBlock uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
// NEP5TransferLog is a log of NEP5 token transfers for the specific command.
|
// TransferLog is a log of NEP5 token transfers for the specific command.
|
||||||
type NEP5TransferLog struct {
|
type TransferLog struct {
|
||||||
Raw []byte
|
Raw []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ func (bs *NEP5Metadata) EncodeBinary(w *io.BinWriter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append appends single transfer to a log.
|
// 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()
|
w := io.NewBufBinWriter()
|
||||||
tr.EncodeBinary(w.BinWriter)
|
tr.EncodeBinary(w.BinWriter)
|
||||||
if w.Err != nil {
|
if w.Err != nil {
|
||||||
|
@ -110,26 +110,25 @@ func (lg *NEP5TransferLog) Append(tr *NEP5Transfer) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForEach iterates over transfer log returning on first 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 {
|
if lg == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
tr := new(NEP5Transfer)
|
for i := 0; i < len(lg.Raw); i += size {
|
||||||
for i := 0; i < len(lg.Raw); i += NEP5TransferSize {
|
r := io.NewBinReaderFromBuf(lg.Raw[i : i+size])
|
||||||
r := io.NewBinReaderFromBuf(lg.Raw[i : i+NEP5TransferSize])
|
|
||||||
tr.DecodeBinary(r)
|
tr.DecodeBinary(r)
|
||||||
if r.Err != nil {
|
if r.Err != nil {
|
||||||
return r.Err
|
return r.Err
|
||||||
} else if err := f(tr); err != nil {
|
} else if err := f(); err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size returns an amount of transfer written in log.
|
// Size returns an amount of transfer written in log provided size of a single transfer.
|
||||||
func (lg *NEP5TransferLog) Size() int {
|
func (lg *TransferLog) Size() int {
|
||||||
return len(lg.Raw) / NEP5TransferSize
|
return len(lg.Raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EncodeBinary implements io.Serializable interface.
|
// EncodeBinary implements io.Serializable interface.
|
||||||
|
|
|
@ -21,15 +21,16 @@ func TestNEP5TransferLog_Append(t *testing.T) {
|
||||||
randomTransfer(r),
|
randomTransfer(r),
|
||||||
}
|
}
|
||||||
|
|
||||||
lg := new(NEP5TransferLog)
|
lg := new(TransferLog)
|
||||||
for _, tr := range expected {
|
for _, tr := range expected {
|
||||||
require.NoError(t, lg.Append(tr))
|
require.NoError(t, lg.Append(tr))
|
||||||
}
|
}
|
||||||
|
|
||||||
require.Equal(t, len(expected), lg.Size())
|
require.Equal(t, len(expected), lg.Size()/NEP5TransferSize)
|
||||||
|
|
||||||
i := 0
|
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)
|
require.Equal(t, expected[i], tr)
|
||||||
i++
|
i++
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -96,7 +96,7 @@ func (chain testChain) GetAccountState(util.Uint160) *state.Account {
|
||||||
func (chain testChain) GetNEP5Metadata(util.Uint160) (*state.NEP5Metadata, error) {
|
func (chain testChain) GetNEP5Metadata(util.Uint160) (*state.NEP5Metadata, error) {
|
||||||
panic("TODO")
|
panic("TODO")
|
||||||
}
|
}
|
||||||
func (chain testChain) GetNEP5TransferLog(util.Uint160) *state.NEP5TransferLog {
|
func (chain testChain) GetNEP5TransferLog(util.Uint160) *state.TransferLog {
|
||||||
panic("TODO")
|
panic("TODO")
|
||||||
}
|
}
|
||||||
func (chain testChain) GetNEP5Balances(util.Uint160) *state.NEP5Balances {
|
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{},
|
Sent: []result.NEP5Transfer{},
|
||||||
}
|
}
|
||||||
lg := s.chain.GetNEP5TransferLog(u)
|
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{
|
transfer := result.NEP5Transfer{
|
||||||
Timestamp: tr.Timestamp,
|
Timestamp: tr.Timestamp,
|
||||||
Asset: tr.Asset,
|
Asset: tr.Asset,
|
||||||
|
|
Loading…
Reference in a new issue