github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/store/orgchain/states/account_state.go (about)

     1  package states
     2  
     3  import (
     4  	"encoding/binary"
     5  	"math/big"
     6  	"sort"
     7  
     8  	"github.com/sixexorg/magnetic-ring/common/sink"
     9  
    10  	"io"
    11  
    12  	"io/ioutil"
    13  
    14  	"bytes"
    15  
    16  	"github.com/sixexorg/magnetic-ring/common"
    17  	"github.com/sixexorg/magnetic-ring/errors"
    18  	mcom "github.com/sixexorg/magnetic-ring/store/orgchain/common"
    19  )
    20  
    21  type AccountState struct {
    22  	Address common.Address
    23  	hash    common.Hash
    24  	Height  uint64
    25  	Data    *Account
    26  }
    27  
    28  type Account struct {
    29  	Nonce       uint64
    30  	Balance     *big.Int
    31  	EnergyBalance *big.Int
    32  	BonusHeight uint64
    33  }
    34  
    35  type AccountStates []*AccountState
    36  
    37  func (s AccountStates) Len() int           { return len(s) }
    38  func (s AccountStates) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
    39  func (s AccountStates) Less(i, j int) bool { return s[i].hash.String() < s[j].hash.String() }
    40  func (s AccountStates) GetHashRoot() common.Hash {
    41  	sort.Sort(s)
    42  	hashes := make([]common.Hash, 0, s.Len())
    43  	for _, v := range s {
    44  		hashes = append(hashes, v.Hash())
    45  	}
    46  	return common.ComputeMerkleRoot(hashes)
    47  }
    48  
    49  func (this *AccountState) Hash() common.Hash {
    50  	buff := new(bytes.Buffer)
    51  	this.Serialization(buff)
    52  	hash, _ := common.ParseHashFromBytes(common.Sha256(buff.Bytes()))
    53  	this.hash = hash
    54  	return hash
    55  }
    56  func (this *AccountState) Serialize(w io.Writer) error {
    57  	sk := sink.NewZeroCopySink(nil)
    58  	sk.WriteUint64(this.Data.Nonce)
    59  	c1, _ := sink.BigIntToComplex(this.Data.Balance)
    60  	sk.WriteComplex(c1)
    61  	c2, _ := sink.BigIntToComplex(this.Data.EnergyBalance)
    62  	sk.WriteComplex(c2)
    63  	sk.WriteUint64(this.Data.BonusHeight)
    64  	w.Write(sk.Bytes())
    65  	return nil
    66  }
    67  func (this *AccountState) Serialization(w io.Writer) error {
    68  	sk := sink.NewZeroCopySink(nil)
    69  	sk.WriteAddress(this.Address)
    70  	sk.WriteUint64(this.Height)
    71  	sk.WriteUint64(this.Data.Nonce)
    72  	c1, _ := sink.BigIntToComplex(this.Data.Balance)
    73  	sk.WriteComplex(c1)
    74  	c2, _ := sink.BigIntToComplex(this.Data.EnergyBalance)
    75  	sk.WriteComplex(c2)
    76  	sk.WriteUint64(this.Data.BonusHeight)
    77  	w.Write(sk.Bytes())
    78  	//fmt.Println("⭕️ hash ", this.Address.ToString(), this.Height, this.Data.Balance.Uint64(), this.Data.EnergyBalance.Uint64(), this.Data.BonusHeight)
    79  	return nil
    80  }
    81  
    82  func (this *AccountState) Deserialize(r io.Reader) error {
    83  	buff, err := ioutil.ReadAll(r)
    84  	if err != nil {
    85  		return err
    86  	}
    87  	var eof bool
    88  	source := sink.NewZeroCopySource(buff)
    89  	_, eof = source.NextByte()
    90  	this.Address, eof = source.NextAddress()
    91  	this.Height, eof = source.NextUint64()
    92  	this.Data = &Account{}
    93  	this.Data.Nonce, eof = source.NextUint64()
    94  	bal, eof := source.NextComplex()
    95  	this.Data.Balance, err = bal.ComplexToBigInt()
    96  	if err != nil {
    97  		return err
    98  	}
    99  	bbl, eof := source.NextComplex()
   100  	this.Data.EnergyBalance, err = bbl.ComplexToBigInt()
   101  	if err != nil {
   102  		return err
   103  	}
   104  	this.Data.BonusHeight, eof = source.NextUint64()
   105  	if eof {
   106  		return errors.ERR_TXRAW_EOF
   107  	}
   108  	return nil
   109  }
   110  
   111  func (this *AccountState) GetKey() []byte {
   112  	return GetAccountStateKey(this.Address, this.Height)
   113  }
   114  func (this *AccountState) Account() common.Address {
   115  	return this.Address
   116  }
   117  func (this *AccountState) League() common.Address {
   118  	return common.Address{}
   119  }
   120  func (this *AccountState) BalanceAdd(num *big.Int) {
   121  	this.Data.Balance.Add(this.Data.Balance, num)
   122  }
   123  func (this *AccountState) BalanceSub(num *big.Int) {
   124  	this.Data.Balance.Sub(this.Data.Balance, num)
   125  }
   126  func (this *AccountState) EnergyAdd(num *big.Int) {
   127  	this.Data.EnergyBalance.Add(this.Data.EnergyBalance, num)
   128  }
   129  func (this *AccountState) EnergySub(num *big.Int) {
   130  	this.Data.EnergyBalance.Sub(this.Data.EnergyBalance, num)
   131  }
   132  func (this *AccountState) NonceSet(num uint64) {
   133  	this.Data.Nonce = num
   134  }
   135  func (this *AccountState) Balance() *big.Int {
   136  	return this.Data.Balance
   137  }
   138  func (this *AccountState) Energy() *big.Int {
   139  	return this.Data.EnergyBalance
   140  }
   141  func (this *AccountState) Nonce() uint64 {
   142  	return this.Data.Nonce
   143  }
   144  func (this *AccountState) BonusHeight() uint64 {
   145  	return this.Data.BonusHeight
   146  }
   147  
   148  func (this *AccountState) GetHeight() uint64 {
   149  	return this.Height
   150  }
   151  func (this *AccountState) GetVal() interface{} {
   152  	return this.Data.Balance
   153  }
   154  func (this *AccountState) BonusHSet(num uint64) {
   155  	this.Data.BonusHeight = num
   156  }
   157  func (this *AccountState) HeightSet(height uint64) {
   158  	this.Height = height
   159  }
   160  func GetAccountStateKey(address common.Address, height uint64) []byte {
   161  	buff := make([]byte, 1+common.AddrLength+8)
   162  	buff[0] = byte(mcom.ST_ACCOUNT)
   163  	copy(buff[1:common.AddrLength+1], address[:])
   164  	binary.LittleEndian.PutUint64(buff[common.AddrLength+1:], height)
   165  	return buff
   166  }
   167  func GetAccountStatePrifex(address common.Address) []byte {
   168  	buff := make([]byte, 1+common.AddrLength)
   169  	buff[0] = byte(mcom.ST_ACCOUNT)
   170  	copy(buff[1:common.AddrLength+1], address[:])
   171  	return buff
   172  }