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 }