core: refactor GASRecord handling
We should store each GAS record as { Key: ContractID + RecordsPrefix + RecordID, Value: RecordValue, } So don't use state.GASRecord for storing anymore. However, it's still useful to cache GasRecord values by using state.GASRecords, because we have to keep GASIndexPairs sorted by indexes.
This commit is contained in:
parent
0da01fde7f
commit
0232bbcb0c
4 changed files with 80 additions and 145 deletions
|
@ -2,7 +2,6 @@ package state
|
|||
|
||||
import (
|
||||
"crypto/elliptic"
|
||||
"errors"
|
||||
"math/big"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
|
@ -22,76 +21,6 @@ type NEOBalanceState struct {
|
|||
VoteTo *keys.PublicKey
|
||||
}
|
||||
|
||||
// GASIndexPair contains block index together with generated gas per block.
|
||||
type GASIndexPair struct {
|
||||
Index uint32
|
||||
GASPerBlock big.Int
|
||||
}
|
||||
|
||||
// GASRecord contains history of gas per block changes.
|
||||
type GASRecord []GASIndexPair
|
||||
|
||||
// Bytes serializes g to []byte.
|
||||
func (g *GASRecord) Bytes() []byte {
|
||||
w := io.NewBufBinWriter()
|
||||
g.EncodeBinary(w.BinWriter)
|
||||
return w.Bytes()
|
||||
}
|
||||
|
||||
// FromBytes deserializes g from data.
|
||||
func (g *GASRecord) FromBytes(data []byte) error {
|
||||
r := io.NewBinReaderFromBuf(data)
|
||||
g.DecodeBinary(r)
|
||||
return r.Err
|
||||
}
|
||||
|
||||
// DecodeBinary implements io.Serializable.
|
||||
func (g *GASRecord) DecodeBinary(r *io.BinReader) {
|
||||
item := stackitem.DecodeBinaryStackItem(r)
|
||||
if r.Err == nil {
|
||||
r.Err = g.fromStackItem(item)
|
||||
}
|
||||
}
|
||||
|
||||
// EncodeBinary implements io.Serializable.
|
||||
func (g *GASRecord) EncodeBinary(w *io.BinWriter) {
|
||||
item := g.toStackItem()
|
||||
stackitem.EncodeBinaryStackItem(item, w)
|
||||
}
|
||||
|
||||
// toStackItem converts GASRecord to a stack item.
|
||||
func (g *GASRecord) toStackItem() stackitem.Item {
|
||||
items := make([]stackitem.Item, len(*g))
|
||||
for i := range items {
|
||||
items[i] = stackitem.NewStruct([]stackitem.Item{
|
||||
stackitem.NewBigInteger(big.NewInt(int64((*g)[i].Index))),
|
||||
stackitem.NewBigInteger(&(*g)[i].GASPerBlock),
|
||||
})
|
||||
}
|
||||
return stackitem.NewArray(items)
|
||||
}
|
||||
|
||||
var errInvalidFormat = errors.New("invalid item format")
|
||||
|
||||
// fromStackItem converts item to a GASRecord.
|
||||
func (g *GASRecord) fromStackItem(item stackitem.Item) error {
|
||||
arr, ok := item.Value().([]stackitem.Item)
|
||||
if !ok {
|
||||
return errInvalidFormat
|
||||
}
|
||||
for i := range arr {
|
||||
s, ok := arr[i].Value().([]stackitem.Item)
|
||||
if !ok || len(s) != 2 || s[0].Type() != stackitem.IntegerT || s[1].Type() != stackitem.IntegerT {
|
||||
return errInvalidFormat
|
||||
}
|
||||
*g = append(*g, GASIndexPair{
|
||||
Index: uint32(s[0].Value().(*big.Int).Uint64()),
|
||||
GASPerBlock: *s[1].Value().(*big.Int),
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NEP5BalanceStateFromBytes converts serialized NEP5BalanceState to structure.
|
||||
func NEP5BalanceStateFromBytes(b []byte) (*NEP5BalanceState, error) {
|
||||
balance := new(NEP5BalanceState)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue