github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/store/mainchain/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 "encoding/gob" 17 18 "github.com/sixexorg/magnetic-ring/common" 19 "github.com/sixexorg/magnetic-ring/errors" 20 mcom "github.com/sixexorg/magnetic-ring/store/mainchain/common" 21 ) 22 23 func init() { 24 gob.Register(&big.Int{}) 25 } 26 27 type AccountState struct { 28 Address common.Address 29 hash common.Hash 30 Height uint64 31 Data *Account 32 LeftBalance *big.Int //only for accountlevel 33 } 34 35 type Account struct { 36 Nonce uint64 37 Balance *big.Int 38 EnergyBalance *big.Int 39 BonusHeight uint64 40 } 41 42 func (this *AccountState) GetHeight() uint64 { 43 return this.Height 44 } 45 func (this *AccountState) GetVal() interface{} { 46 return this.Data.Balance 47 } 48 49 type AccountStates []*AccountState 50 51 func (s AccountStates) Len() int { return len(s) } 52 func (s AccountStates) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 53 func (s AccountStates) Less(i, j int) bool { return s[i].Hash().String() < s[j].Hash().String() } 54 func (s AccountStates) GetHashRoot() common.Hash { 55 sort.Sort(s) 56 hashes := make([]common.Hash, 0, s.Len()) 57 for _, v := range s { 58 hashes = append(hashes, v.Hash()) 59 } 60 return common.ComputeMerkleRoot(hashes) 61 } 62 63 func (this *AccountState) Hash() common.Hash { 64 buff := new(bytes.Buffer) 65 buff.Write(this.GetKey()) 66 this.Serialize(buff) 67 hash, _ := common.ParseHashFromBytes(common.Sha256(buff.Bytes())) 68 this.hash = hash 69 return hash 70 } 71 func (this *AccountState) Serialize(w io.Writer) error { 72 sk := sink.NewZeroCopySink(nil) 73 sk.WriteUint64(this.Data.Nonce) 74 c1, _ := sink.BigIntToComplex(this.Data.Balance) 75 sk.WriteComplex(c1) 76 c2, _ := sink.BigIntToComplex(this.Data.EnergyBalance) 77 sk.WriteComplex(c2) 78 sk.WriteUint64(this.Data.BonusHeight) 79 w.Write(sk.Bytes()) 80 return nil 81 } 82 83 func (this *AccountState) Deserialize(r io.Reader) error { 84 buff, err := ioutil.ReadAll(r) 85 if err != nil { 86 return err 87 } 88 var eof bool 89 source := sink.NewZeroCopySource(buff) 90 _, eof = source.NextByte() 91 this.Address, eof = source.NextAddress() 92 this.Height, eof = source.NextUint64() 93 this.Data = &Account{} 94 this.Data.Nonce, eof = source.NextUint64() 95 bal, eof := source.NextComplex() 96 this.Data.Balance, err = bal.ComplexToBigInt() 97 if err != nil { 98 return err 99 } 100 bbl, eof := source.NextComplex() 101 this.Data.EnergyBalance, err = bbl.ComplexToBigInt() 102 if err != nil { 103 return err 104 } 105 this.Data.BonusHeight, eof = source.NextUint64() 106 if eof { 107 return errors.ERR_TXRAW_EOF 108 } 109 return nil 110 } 111 112 func (this *AccountState) GetKey() []byte { 113 buff := make([]byte, 1+common.AddrLength+8) 114 buff[0] = byte(mcom.ST_ACCOUNT) 115 copy(buff[1:common.AddrLength+1], this.Address[:]) 116 binary.LittleEndian.PutUint64(buff[common.AddrLength+1:], this.Height) 117 return buff 118 }