github.com/insight-chain/inb-go@v1.1.3-0.20191221022159-da049980ae38/core/state/state_object.go (about)

     1  // Copyright 2014 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software MiningReward, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package state
    18  
    19  import (
    20  	"bytes"
    21  	"errors"
    22  	"fmt"
    23  	"github.com/insight-chain/inb-go/common"
    24  	"github.com/insight-chain/inb-go/core/types"
    25  	"github.com/insight-chain/inb-go/params"
    26  
    27  	"github.com/insight-chain/inb-go/crypto"
    28  	"github.com/insight-chain/inb-go/rlp"
    29  	"io"
    30  	"math/big"
    31  )
    32  
    33  var emptyCodeHash = crypto.Keccak256(nil)
    34  
    35  type Code []byte
    36  
    37  func (self Code) String() string {
    38  	return string(self) //strings.Join(Disassemble(self), " ")
    39  }
    40  
    41  type Storage map[common.Hash]common.Hash
    42  
    43  func (self Storage) String() (str string) {
    44  	for key, value := range self {
    45  		str += fmt.Sprintf("%X : %X\n", key, value)
    46  	}
    47  
    48  	return
    49  }
    50  
    51  func (self Storage) Copy() Storage {
    52  	cpy := make(Storage)
    53  	for key, value := range self {
    54  		cpy[key] = value
    55  	}
    56  
    57  	return cpy
    58  }
    59  
    60  // stateObject represents an Ethereum account which is being modified.
    61  //
    62  // The usage pattern is as follows:
    63  // First you need to obtain a state object.
    64  // Account values can be accessed and modified through the object.
    65  // Finally, call CommitTrie to write the modified storage trie into a database.
    66  type stateObject struct {
    67  	address  common.Address
    68  	addrHash common.Hash // hash of ethereum address of the account
    69  	data     Account
    70  	db       *StateDB
    71  
    72  	// DB error.
    73  	// State objects are used by the consensus core and VM which are
    74  	// unable to deal with database-level errors. Any error that occurs
    75  	// during a database read is memoized here and will eventually be returned
    76  	// by StateDB.Commit.
    77  	dbErr error
    78  
    79  	// Write caches.
    80  	trie Trie // storage trie, which becomes non-nil on first access
    81  	code Code // contract bytecode, which gets set when code is loaded
    82  
    83  	originStorage Storage // Storage cache of original entries to dedup rewrites
    84  	dirtyStorage  Storage // Storage entries that need to be flushed to disk
    85  
    86  	// Cache flags.
    87  	// When an object is marked suicided it will be delete from the trie
    88  	// during the "update" phase of the state transition.
    89  	dirtyCode bool // true if the code was updated
    90  	suicided  bool
    91  	deleted   bool
    92  }
    93  
    94  // empty returns whether the account is considered empty.
    95  func (s *stateObject) empty() bool {
    96  	return s.data.Nonce == 0 && s.data.Balance.Sign() == 0 && bytes.Equal(s.data.CodeHash, emptyCodeHash)
    97  }
    98  
    99  // Account is the Ethereum consensus representation of accounts.
   100  // These objects are stored in the main account trie.
   101  type Account struct {
   102  	Nonce    uint64
   103  	Balance  *big.Int
   104  	Root     common.Hash // merkle root of the storage trie
   105  	CodeHash []byte
   106  	Res      Resource // resource for account
   107  	Stakings   []Staking  // slice of regular mortgaging
   108  	//Recommender common.Address
   109  	UnStaking                      UnStaking // redeeming nets
   110  	//Regular                      *big.Int //  total of regular mortgaging
   111  	Voted                        *big.Int //current vote to someone else number
   112  	LastReceivedVoteRewardHeight *big.Int
   113  }
   114  
   115  type Resource struct {
   116  	Used     *big.Int // used
   117  	Usable   *big.Int // unuse
   118  	StakingValue *big.Int // total number of mortgage
   119  	Height   *big.Int
   120  }
   121  
   122  //Resource by zc
   123  //type Resources struct {
   124  //	CPU  Resource
   125  //	NET  Resource
   126  //	Date *big.Int
   127  //}
   128  //type Resource struct {
   129  //	Used         *big.Int // used
   130  //	Usableness   *big.Int // unuse
   131  //	MortgagteINB *big.Int //
   132  //}
   133  
   134  type Staking struct {
   135  	Hash               common.Hash // transaction of regular mortgaging
   136  	StartHeight        *big.Int    // start time
   137  	LockHeights        *big.Int    // duration of mortgaging
   138  	Value              *big.Int    // amount of mortgaging
   139  	Received           *big.Int    // amount of already received value
   140  	LastReceivedHeight *big.Int    // Last receive time
   141  }
   142  
   143  type UnStaking struct {
   144  	StartHeight *big.Int // start time
   145  	Value       *big.Int // amount of redeeming
   146  }
   147  
   148  //Resource by zc
   149  // newObject creates a state object.
   150  func newObject(db *StateDB, address common.Address, data Account) *stateObject {
   151  	if data.Balance == nil {
   152  		data.Balance = new(big.Int)
   153  	}
   154  	if data.CodeHash == nil {
   155  		data.CodeHash = emptyCodeHash
   156  	}
   157  	//Resource by zc
   158  	if data.Res.Used == nil {
   159  		data.Res.Used = new(big.Int)
   160  	}
   161  	if data.Res.Usable == nil {
   162  		data.Res.Usable = new(big.Int)
   163  	}
   164  	if data.Res.StakingValue == nil {
   165  		data.Res.StakingValue = new(big.Int)
   166  	}
   167  	if data.Res.Height == nil {
   168  		data.Res.Height = new(big.Int)
   169  	}
   170  	if data.Stakings == nil {
   171  		data.Stakings = make([]Staking, 0)
   172  	}
   173  	//if data.UnStaking == nil {
   174  	//	data.UnStaking = new(UnStaking)
   175  	//}
   176  	//if data.Regular == nil {
   177  	//	data.Regular = new(big.Int)
   178  	//}
   179  	if data.LastReceivedVoteRewardHeight == nil {
   180  		data.LastReceivedVoteRewardHeight = new(big.Int)
   181  	}
   182  	if data.Voted == nil {
   183  		data.Voted = new(big.Int)
   184  	}
   185  	//Resource by zc
   186  	return &stateObject{
   187  		db:            db,
   188  		address:       address,
   189  		addrHash:      crypto.Keccak256Hash(address[:]),
   190  		data:          data,
   191  		originStorage: make(Storage),
   192  		dirtyStorage:  make(Storage),
   193  	}
   194  }
   195  
   196  // EncodeRLP implements rlp.Encoder.
   197  func (c *stateObject) EncodeRLP(w io.Writer) error {
   198  	return rlp.Encode(w, c.data)
   199  }
   200  
   201  // setError remembers the first non-nil error it is called with.
   202  func (self *stateObject) setError(err error) {
   203  	if self.dbErr == nil {
   204  		self.dbErr = err
   205  	}
   206  }
   207  
   208  func (self *stateObject) markSuicided() {
   209  	self.suicided = true
   210  }
   211  
   212  func (c *stateObject) touch() {
   213  	c.db.journal.append(touchChange{
   214  		account: &c.address,
   215  	})
   216  	if c.address == ripemd {
   217  		// Explicitly put it in the dirty-cache, which is otherwise generated from
   218  		// flattened journals.
   219  		c.db.journal.dirty(c.address)
   220  	}
   221  }
   222  
   223  func (c *stateObject) getTrie(db Database) Trie {
   224  	if c.trie == nil {
   225  		var err error
   226  		c.trie, err = db.OpenStorageTrie(c.addrHash, c.data.Root)
   227  		if err != nil {
   228  			c.trie, _ = db.OpenStorageTrie(c.addrHash, common.Hash{})
   229  			c.setError(fmt.Errorf("can't create storage trie: %v", err))
   230  		}
   231  	}
   232  	return c.trie
   233  }
   234  
   235  // GetState retrieves a value from the account storage trie.
   236  func (self *stateObject) GetState(db Database, key common.Hash) common.Hash {
   237  	// If we have a dirty value for this state entry, return it
   238  	value, dirty := self.dirtyStorage[key]
   239  	if dirty {
   240  		return value
   241  	}
   242  	// Otherwise return the entry's original value
   243  	return self.GetCommittedState(db, key)
   244  }
   245  
   246  // GetCommittedState retrieves a value from the committed account storage trie.
   247  func (self *stateObject) GetCommittedState(db Database, key common.Hash) common.Hash {
   248  	// If we have the original value cached, return that
   249  	value, cached := self.originStorage[key]
   250  	if cached {
   251  		return value
   252  	}
   253  	// Otherwise load the value from the database
   254  	enc, err := self.getTrie(db).TryGet(key[:])
   255  	if err != nil {
   256  		self.setError(err)
   257  		return common.Hash{}
   258  	}
   259  	if len(enc) > 0 {
   260  		_, content, _, err := rlp.Split(enc)
   261  		if err != nil {
   262  			self.setError(err)
   263  		}
   264  		value.SetBytes(content)
   265  	}
   266  	self.originStorage[key] = value
   267  	return value
   268  }
   269  
   270  // SetState updates a value in account storage.
   271  func (self *stateObject) SetState(db Database, key, value common.Hash) {
   272  	// If the new value is the same as old, don't set
   273  	prev := self.GetState(db, key)
   274  	if prev == value {
   275  		return
   276  	}
   277  	// New value is different, update and journal the change
   278  	self.db.journal.append(storageChange{
   279  		account:  &self.address,
   280  		key:      key,
   281  		prevalue: prev,
   282  	})
   283  	self.setState(key, value)
   284  }
   285  
   286  func (self *stateObject) setState(key, value common.Hash) {
   287  	self.dirtyStorage[key] = value
   288  }
   289  
   290  // updateTrie writes cached storage modifications into the object's storage trie.
   291  func (self *stateObject) updateTrie(db Database) Trie {
   292  	tr := self.getTrie(db)
   293  	for key, value := range self.dirtyStorage {
   294  		delete(self.dirtyStorage, key)
   295  
   296  		// Skip noop changes, persist actual changes
   297  		if value == self.originStorage[key] {
   298  			continue
   299  		}
   300  		self.originStorage[key] = value
   301  
   302  		if (value == common.Hash{}) {
   303  			self.setError(tr.TryDelete(key[:]))
   304  			continue
   305  		}
   306  		// Encoding []byte cannot fail, ok to ignore the error.
   307  		v, _ := rlp.EncodeToBytes(bytes.TrimLeft(value[:], "\x00"))
   308  		self.setError(tr.TryUpdate(key[:], v))
   309  	}
   310  	return tr
   311  }
   312  
   313  // UpdateRoot sets the trie root to the current root hash of
   314  func (self *stateObject) updateRoot(db Database) {
   315  	self.updateTrie(db)
   316  	self.data.Root = self.trie.Hash()
   317  }
   318  
   319  // CommitTrie the storage trie of the object to db.
   320  // This updates the trie root.
   321  func (self *stateObject) CommitTrie(db Database) error {
   322  	self.updateTrie(db)
   323  	if self.dbErr != nil {
   324  		return self.dbErr
   325  	}
   326  	root, err := self.trie.Commit(nil)
   327  	if err == nil {
   328  		self.data.Root = root
   329  	}
   330  	return err
   331  }
   332  
   333  // AddBalance removes amount from c's balance.
   334  // It is used to add funds to the destination account of a transfer.
   335  func (c *stateObject) AddBalance(amount *big.Int) {
   336  	// EIP158: We must check emptiness for the objects such that the account
   337  	// clearing (0,0,0 objects) can take effect.
   338  	if amount.Sign() == 0 {
   339  		if c.empty() {
   340  			c.touch()
   341  		}
   342  
   343  		return
   344  	}
   345  	c.SetBalance(new(big.Int).Add(c.Balance(), amount))
   346  }
   347  
   348  func (c *stateObject) AddVoteRecord(amount *big.Int) {
   349  	// EIP158: We must check emptiness for the objects such that the account
   350  	// clearing (0,0,0 objects) can take effect.
   351  	//if amount.Sign() == 0 {
   352  	//	if c.empty() {
   353  	//		c.touch()
   354  	//	}
   355  	//
   356  	//	return
   357  	//}
   358  	c.SetVoteRecord(amount)
   359  }
   360  
   361  // SubBalance removes amount from c's balance.
   362  // It is used to remove funds from the origin account of a transfer.
   363  func (c *stateObject) SubBalance(amount *big.Int) {
   364  	if amount.Sign() == 0 {
   365  		return
   366  	}
   367  	c.SetBalance(new(big.Int).Sub(c.Balance(), amount))
   368  }
   369  
   370  func (self *stateObject) SetBalance(amount *big.Int) {
   371  	self.db.journal.append(balanceChange{
   372  		account: &self.address,
   373  		prev:    new(big.Int).Set(self.data.Balance),
   374  	})
   375  	self.setBalance(amount)
   376  }
   377  
   378  func (self *stateObject) SetVoteRecord(amount *big.Int) {
   379  
   380  	self.setVoteRecord(amount)
   381  }
   382  
   383  func (self *stateObject) setBalance(amount *big.Int) {
   384  	self.data.Balance = amount
   385  }
   386  
   387  func (self *stateObject) setVoteRecord(amount *big.Int) {
   388  	self.data.Voted = amount
   389  }
   390  
   391  //achilles MortgageNet add nets from c's resource
   392  func (self *stateObject) MortgageNet(amount *big.Int, duration *big.Int, sTime big.Int, hash common.Hash) *big.Int {
   393  	if amount.Sign() == 0 {
   394  		return nil
   395  	}
   396  	netUse := self.db.ConvertToNets(amount)
   397  	self.SetRes(self.UsedNet(), new(big.Int).Add(self.Net(), netUse), new(big.Int).Add(self.StakingValue(), amount))
   398  
   399  	mortgageStateObject := self.db.GetMortgageStateObject()
   400  	mortgageStateObject.AddBalance(amount)
   401  
   402  	if duration.Cmp(big.NewInt(0)) > 0 {
   403  		staking := Staking{
   404  			Hash:               hash,
   405  			StartHeight:        &sTime,
   406  			LockHeights:        duration,
   407  			Value:              amount,
   408  			LastReceivedHeight: &sTime,
   409  		}
   410  		stakings := append(self.data.Stakings, staking)
   411  		self.SetStakings(stakings)
   412  	}
   413  
   414  	if !(big.NewInt(0).Cmp(self.Date()) < 0) {
   415  		self.SetDate(&sTime)
   416  	}
   417  
   418  	//2019.8.29 inb by ghy begin
   419  	votes := self.data.Voted
   420  
   421  	if votes.Cmp(big.NewInt(0)) == 1 && self.data.LastReceivedVoteRewardHeight.Cmp(big.NewInt(0)) == 1 {
   422  		self.Vote(&sTime)
   423  		HeightNow := sTime
   424  		lastReceiveVoteAwardHeight := self.data.LastReceivedVoteRewardHeight
   425  		if HeightNow.Cmp(lastReceiveVoteAwardHeight) != 1 {
   426  			return netUse
   427  		}
   428  		fromLastReceiveVoteAwardTimeToNowHeight := new(big.Int).Sub(&HeightNow, lastReceiveVoteAwardHeight)
   429  		cycles := new(big.Int).Div(fromLastReceiveVoteAwardTimeToNowHeight, common.VoteRewardCycleSecondsForChange)
   430  		if cycles.Cmp(common.VoteRewardCycleTimesForChange) != -1 {
   431  			votes1 := new(big.Int).Mul(votes, common.VoteDenominatorForChange)
   432  			votes2 := new(big.Int).Div(votes1, common.VoteHundredForChange)
   433  			votes3 := new(big.Int).Div(votes2, common.VoteNumberOfDaysOneYearForChange)
   434  			value := new(big.Int).Mul(votes3, cycles)
   435  			self.ReceiveVoteAward(value, &HeightNow)
   436  		}
   437  	}
   438  	//2019.8.29 inb by ghy end
   439  	return netUse
   440  }
   441  
   442  func (self *stateObject) ResetNet(update *big.Int) *big.Int {
   443  	netUse := self.db.ConvertToNets(self.StakingValue())
   444  	netUsed := big.NewInt(0)
   445  
   446  	self.SetRes(netUsed, netUse, self.StakingValue())
   447  	self.SetDate(update)
   448  	return netUse
   449  }
   450  
   451  //2019.7.22 inb by ghy begin
   452  func (self *stateObject) CanReceiveLockedAward(nonce common.Hash, height *big.Int, consensus types.SpecialConsensus) (err error, value *big.Int, isAll bool) {
   453  	if self.data.Voted.Cmp(big.NewInt(0)) != 1 {
   454  		return errors.New("can only receive locked rewards after voting"), big.NewInt(0), false
   455  	}
   456  	if len(self.data.Stakings) == 0 {
   457  		return errors.New("no lock record"), big.NewInt(0), false
   458  	}
   459  	LockedRewardCycleHeight := new(big.Int)
   460  	LockedRewardCycleTimes := new(big.Int)
   461  	LockedDenominator := new(big.Int)
   462  	LockedHundred := new(big.Int)
   463  	LockedNumberOfDaysOneYear := new(big.Int)
   464  
   465  	for _, v := range self.data.Stakings {
   466  		if nonce == v.Hash {
   467  			switch v.LockHeights.Uint64() {
   468  			case params.HeightOf30Days.Uint64():
   469  				LockedRewardCycleHeight = common.LockedRewardCycleSecondsFor30days
   470  				LockedRewardCycleTimes = common.LockedRewardCycleTimesFor30days
   471  				LockedDenominator = common.LockedDenominatorFor30days
   472  				LockedHundred = common.LockedHundredFor30days
   473  				LockedNumberOfDaysOneYear = common.LockedNumberOfDaysOneYearFor30days
   474  			case params.HeightOf90Days.Uint64():
   475  				LockedRewardCycleHeight = common.LockedRewardCycleSecondsFor90days
   476  				LockedRewardCycleTimes = common.LockedRewardCycleTimesFor90days
   477  				LockedDenominator = common.LockedDenominatorFor90days
   478  				LockedHundred = common.LockedHundredFor90days
   479  				LockedNumberOfDaysOneYear = common.LockedNumberOfDaysOneYearFor90days
   480  			case params.HeightOf180Days.Uint64():
   481  				LockedRewardCycleHeight = common.LockedRewardCycleSecondsFor180days
   482  				LockedRewardCycleTimes = common.LockedRewardCycleTimesFor180days
   483  				LockedDenominator = common.LockedDenominatorFor180days
   484  				LockedHundred = common.LockedHundredFor180days
   485  				LockedNumberOfDaysOneYear = common.LockedNumberOfDaysOneYearFor180days
   486  			case params.HeightOf360Days.Uint64(), params.HeightOf720Days.Uint64(), params.HeightOf1080Days.Uint64(), params.HeightOf1800Days.Uint64(), params.HeightOf3600Days.Uint64():
   487  				LockedRewardCycleHeight = common.LockedRewardCycleSecondsForMoreThan360days
   488  				LockedRewardCycleTimes = common.LockedRewardCycleTimesForMoreThan360days
   489  				LockedDenominator = common.LockedDenominatorForMoreThan360days
   490  				LockedHundred = common.LockedHundredForMoreThan360days
   491  				LockedNumberOfDaysOneYear = common.LockedNumberOfDaysOneYearForMoreThan360days
   492  			default:
   493  				return errors.New("unknow times"), big.NewInt(0), false
   494  			}
   495  
   496  			HeightNow := height
   497  
   498  			startHeight := v.StartHeight
   499  
   500  			lastReceivedHeight := v.LastReceivedHeight
   501  
   502  			lockHeights := v.LockHeights
   503  
   504  			endTimeHeight := new(big.Int).Add(startHeight, lockHeights)
   505  
   506  			totalValue := v.Value
   507  			receivedValue := v.Received
   508  
   509  			if startHeight.Cmp(lastReceivedHeight) == 1 {
   510  				return errors.New("last receipt time and start time error"), big.NewInt(0), false
   511  			}
   512  			if lastReceivedHeight.Cmp(HeightNow) == 1 {
   513  				return errors.New("last receipt time error"), big.NewInt(0), false
   514  			}
   515  			if lastReceivedHeight.Cmp(endTimeHeight) == 1 {
   516  				return errors.New("all the rewards are received"), big.NewInt(0), false
   517  			}
   518  
   519  			FromLastReceivedPassTimeHeight := new(big.Int).Sub(HeightNow, lastReceivedHeight)
   520  			FromStartPassTimeHeight := new(big.Int).Sub(HeightNow, startHeight)
   521  
   522  			if HeightNow.Cmp(endTimeHeight) >= 0 {
   523  				//HeightNow = endTimeHeight
   524  				FromLastReceivedPassTimeHeight = new(big.Int).Sub(endTimeHeight, lastReceivedHeight)
   525  				FromStartPassTimeHeight = new(big.Int).Sub(endTimeHeight, startHeight)
   526  			}
   527  
   528  			FromLastReceivedPassDays := new(big.Int).Div(FromLastReceivedPassTimeHeight, LockedRewardCycleHeight)
   529  
   530  			FromStartPassDays := new(big.Int).Div(FromStartPassTimeHeight, LockedRewardCycleHeight)
   531  
   532  			totalValue1 := new(big.Int).Mul(totalValue, LockedDenominator)
   533  			totalValue2 := new(big.Int).Mul(totalValue1, FromStartPassDays)
   534  			totalValue3 := new(big.Int).Div(totalValue2, LockedHundred)
   535  			MaxReceivedValueNow := new(big.Int).Div(totalValue3, LockedNumberOfDaysOneYear)
   536  			subValue := new(big.Int).Sub(MaxReceivedValueNow, receivedValue)
   537  
   538  			if subValue.Cmp(big.NewInt(0)) != 1 {
   539  				return errors.New("have no rewards to received"), big.NewInt(0), false
   540  			}
   541  
   542  			if HeightNow.Cmp(endTimeHeight) == -1 && FromLastReceivedPassDays.Cmp(LockedRewardCycleTimes) == -1 {
   543  				return errors.New("not block height to receive rewards"), big.NewInt(0), false
   544  			}
   545  			return nil, subValue, HeightNow.Cmp(endTimeHeight) >= 0
   546  		}
   547  	}
   548  	return errors.New("no such lock record"), big.NewInt(0), false
   549  
   550  }
   551  
   552  func (self *stateObject) ReceiveLockedAward(nonce common.Hash, value *big.Int, isAll bool, height *big.Int) {
   553  
   554  	if len(self.data.Stakings) > 0 {
   555  		for k, v := range self.data.Stakings {
   556  			if nonce == v.Hash {
   557  				self.AddBalance(value)
   558  				self.data.Stakings[k].LastReceivedHeight = height
   559  				if isAll {
   560  					self.AddBalance(v.Value)
   561  
   562  					//afterRegular := new(big.Int).Sub(self.data.Regular, v.Value)
   563  					//self.data.Regular = afterRegular
   564  					afterMortgagteINB := new(big.Int).Sub(self.data.Res.StakingValue, v.Value)
   565  					self.data.Res.StakingValue = afterMortgagteINB
   566  
   567  					self.data.Stakings = append(self.data.Stakings[:k], self.data.Stakings[k+1:]...)
   568  
   569  					mortgageStateObject := self.db.GetMortgageStateObject()
   570  					if mortgageStateObject.Balance().Cmp(value) < 0 {
   571  						return
   572  					}
   573  					//balance := new(big.Int).Sub(mortgageStateObject.MortgageOfRes(), value)
   574  					mortgageStateObject.SubBalance(value)
   575  
   576  				} else {
   577  
   578  					//receiveAdd := v.Received.Int64() + int64(value)
   579  					receiveAdd := new(big.Int).Add(v.Received, value)
   580  					self.data.Stakings[k].Received = receiveAdd
   581  				}
   582  			}
   583  		}
   584  	}
   585  }
   586  
   587  func (self *stateObject) CanReceiveVoteAward(height *big.Int) (err error, value *big.Int) {
   588  	//account := pool.currentState.GetAccountInfo(from)
   589  	votes := self.data.Voted
   590  	if votes.Cmp(big.NewInt(0)) != 1 {
   591  		return errors.New("please receive vote award after voting"), big.NewInt(0)
   592  
   593  	}
   594  	heightNow := height
   595  	lastReceiveVoteAwardHeight := self.data.LastReceivedVoteRewardHeight
   596  	if heightNow.Cmp(lastReceiveVoteAwardHeight) != 1 {
   597  		return errors.New("please receive vote award after voting"), big.NewInt(0)
   598  	}
   599  	fromLastReceiveVoteAwardTimeToNowHeights := new(big.Int).Sub(heightNow, lastReceiveVoteAwardHeight)
   600  	cycles := new(big.Int).Div(fromLastReceiveVoteAwardTimeToNowHeights, common.VoteRewardCycleSeconds)
   601  	if cycles.Cmp(common.VoteRewardCycleTimes) != -1 {
   602  		votes1 := new(big.Int).Mul(votes, common.VoteDenominator)
   603  		votes2 := new(big.Int).Mul(votes1, cycles)
   604  		votes3 := new(big.Int).Div(votes2, common.VoteHundred)
   605  		value := new(big.Int).Div(votes3, common.VoteNumberOfDaysOneYear)
   606  		return nil, value
   607  	}
   608  	return errors.New("not receive vote award time"), big.NewInt(0)
   609  }
   610  
   611  func (self *stateObject) ReceiveVoteAward(value *big.Int, height *big.Int) {
   612  	self.data.LastReceivedVoteRewardHeight = height
   613  	self.AddBalance(value)
   614  
   615  }
   616  
   617  func (self *stateObject) Vote(height *big.Int) {
   618  	self.data.Voted = self.data.Res.StakingValue
   619  	self.data.LastReceivedVoteRewardHeight = height
   620  }
   621  
   622  //2019.7.22 inb by ghy end
   623  
   624  //achilles Redeem freeze inb of mortgaging from c's balance
   625  func (self *stateObject) Redeem(amount *big.Int, sTime *big.Int) {
   626  	if amount.Sign() == 0 {
   627  		return
   628  	}
   629  	available := new(big.Int).Sub(self.StakingValue(), self.GetTotalStaking())
   630  	available.Sub(available, self.GetUnStaking())
   631  	if available.Cmp(amount) < 0 {
   632  		return
   633  	}
   634  	// freeze inb of redeeming
   635  	mortgaging := new(big.Int).Sub(self.StakingValue(), amount)
   636  	self.SetRes(self.UsedNet(), self.Net(), mortgaging)
   637  
   638  	unStaking := UnStaking{
   639  		StartHeight: sTime,
   640  		Value:       new(big.Int).Add(self.GetUnStaking(), amount),
   641  	}
   642  	self.SetUnStaking(unStaking)
   643  }
   644  
   645  func (self *stateObject) Receive(sTime *big.Int) *big.Int {
   646  
   647  	value := self.GetUnStaking()
   648  	unStaking := UnStaking{
   649  		StartHeight: sTime,
   650  		Value:       big.NewInt(0),
   651  	}
   652  	self.SetUnStaking(unStaking)
   653  
   654  	self.AddBalance(value)
   655  	mortgageStateObject := self.db.GetMortgageStateObject()
   656  	if mortgageStateObject.Balance().Cmp(value) < 0 {
   657  		return nil
   658  	}
   659  	//balance := new(big.Int).Sub(mortgageStateObject.MortgageOfRes(), value)
   660  	mortgageStateObject.SubBalance(value)
   661  
   662  	//2019.8.29 inb by ghy begin
   663  	votes := self.data.Voted
   664  
   665  	if votes.Cmp(big.NewInt(0)) == 1 && self.data.LastReceivedVoteRewardHeight.Cmp(big.NewInt(0)) == 1 {
   666  		self.Vote(sTime)
   667  		HeightNow := sTime
   668  		lastReceiveVoteAwardHeight := self.data.LastReceivedVoteRewardHeight
   669  		if HeightNow.Cmp(lastReceiveVoteAwardHeight) != 1 {
   670  			return value
   671  		}
   672  		fromLastReceiveVoteAwardTimeToNowHeight := new(big.Int).Sub(HeightNow, lastReceiveVoteAwardHeight)
   673  		cycles := new(big.Int).Div(fromLastReceiveVoteAwardTimeToNowHeight, common.VoteRewardCycleSecondsForChange)
   674  		if cycles.Cmp(common.VoteRewardCycleTimesForChange) != -1 {
   675  			votes1 := new(big.Int).Mul(votes, common.VoteDenominatorForChange)
   676  			votes2 := new(big.Int).Div(votes1, common.VoteHundredForChange)
   677  			votes3 := new(big.Int).Div(votes2, common.VoteNumberOfDaysOneYearForChange)
   678  			value := new(big.Int).Mul(votes3, cycles)
   679  			self.ReceiveVoteAward(value, HeightNow)
   680  		}
   681  	}
   682  	//2019.8.29 inb by ghy end
   683  	return value
   684  }
   685  
   686  func (self *stateObject) SetRes(used *big.Int, usable *big.Int, stakingValue *big.Int) {
   687  
   688  	self.db.journal.append(resChange{
   689  		account:      &self.address,
   690  		Used:         new(big.Int).Set(self.data.Res.Used),
   691  		Usable:   new(big.Int).Set(self.data.Res.Usable),
   692  		StakingValue: new(big.Int).Set(self.data.Res.StakingValue),
   693  	})
   694  	self.setRes(used, usable, stakingValue)
   695  }
   696  
   697  func (self *stateObject) setRes(used *big.Int, usable *big.Int, stakingValue *big.Int) {
   698  	self.data.Res.Used = used
   699  	self.data.Res.Usable = usable
   700  	self.data.Res.StakingValue = stakingValue
   701  }
   702  
   703  func (self *stateObject) SetUnStaking(unStaking UnStaking) {
   704  	self.db.journal.append(unStakingChange{
   705  		account: &self.address,
   706  		unStaking: self.data.UnStaking,
   707  	})
   708  	self.setUnStaking(unStaking)
   709  }
   710  
   711  func (self *stateObject) setUnStaking(unStaking UnStaking) {
   712  	self.data.UnStaking = unStaking
   713  }
   714  
   715  func (self *stateObject) SetDate(update *big.Int) {
   716  
   717  	self.db.journal.append(dateChange{
   718  		account: &self.address,
   719  		prev:    new(big.Int).Set(self.data.Res.Height),
   720  	})
   721  	self.setDate(update)
   722  }
   723  
   724  func (self *stateObject) setDate(update *big.Int) {
   725  	self.data.Res.Height = update
   726  }
   727  
   728  //achilles0718 regular mortgagtion
   729  func (self *stateObject) SetStakings(stakings []Staking) {
   730  	self.db.journal.append(stakingChange{
   731  		account: &self.address,
   732  		stakings:  self.data.Stakings,
   733  	})
   734  	self.setStakings(stakings)
   735  }
   736  
   737  func (self *stateObject) setStakings(stakings []Staking) {
   738  	self.data.Stakings = stakings
   739  }
   740  
   741  // Return the gas back to the origin. Used by the Virtual machine or Closures
   742  func (c *stateObject) ReturnGas(gas *big.Int) {}
   743  
   744  func (self *stateObject) deepCopy(db *StateDB) *stateObject {
   745  	stateObject := newObject(db, self.address, self.data)
   746  	if self.trie != nil {
   747  		stateObject.trie = db.db.CopyTrie(self.trie)
   748  	}
   749  	stateObject.code = self.code
   750  	stateObject.dirtyStorage = self.dirtyStorage.Copy()
   751  	stateObject.originStorage = self.originStorage.Copy()
   752  	stateObject.suicided = self.suicided
   753  	stateObject.dirtyCode = self.dirtyCode
   754  	stateObject.deleted = self.deleted
   755  	return stateObject
   756  }
   757  
   758  //
   759  // Attribute accessors
   760  //
   761  
   762  // Returns the address of the contract/account
   763  func (c *stateObject) Address() common.Address {
   764  	return c.address
   765  }
   766  
   767  // Code returns the contract code associated with this object, if any.
   768  func (self *stateObject) Code(db Database) []byte {
   769  	if self.code != nil {
   770  		return self.code
   771  	}
   772  	if bytes.Equal(self.CodeHash(), emptyCodeHash) {
   773  		return nil
   774  	}
   775  	code, err := db.ContractCode(self.addrHash, common.BytesToHash(self.CodeHash()))
   776  	if err != nil {
   777  		self.setError(fmt.Errorf("can't load code hash %x: %v", self.CodeHash(), err))
   778  	}
   779  	self.code = code
   780  	return code
   781  }
   782  
   783  func (self *stateObject) SetCode(codeHash common.Hash, code []byte) {
   784  	prevcode := self.Code(self.db.db)
   785  	self.db.journal.append(codeChange{
   786  		account:  &self.address,
   787  		prevhash: self.CodeHash(),
   788  		prevcode: prevcode,
   789  	})
   790  	self.setCode(codeHash, code)
   791  }
   792  
   793  func (self *stateObject) setCode(codeHash common.Hash, code []byte) {
   794  	self.code = code
   795  	self.data.CodeHash = codeHash[:]
   796  	self.dirtyCode = true
   797  }
   798  
   799  func (self *stateObject) SetNonce(nonce uint64) {
   800  	self.db.journal.append(nonceChange{
   801  		account: &self.address,
   802  		prev:    self.data.Nonce,
   803  	})
   804  	self.setNonce(nonce)
   805  }
   806  
   807  func (self *stateObject) setNonce(nonce uint64) {
   808  	self.data.Nonce = nonce
   809  }
   810  
   811  func (self *stateObject) CodeHash() []byte {
   812  	return self.data.CodeHash
   813  }
   814  
   815  func (self *stateObject) Balance() *big.Int {
   816  	return self.data.Balance
   817  }
   818  
   819  //achilles0718 regular mortgagtion
   820  func (self *stateObject) StoreLength() int {
   821  	stakings := self.data.Stakings
   822  	return len(stakings)
   823  }
   824  
   825  //Resource by zc
   826  func (self *stateObject) Net() *big.Int {
   827  	return self.data.Res.Usable
   828  }
   829  func (self *stateObject) UsedNet() *big.Int {
   830  	return self.data.Res.Used
   831  }
   832  func (self *stateObject) StakingValue() *big.Int {
   833  	return self.data.Res.StakingValue
   834  }
   835  
   836  func (self *stateObject) GetUnStaking() *big.Int {
   837  	return self.data.UnStaking.Value
   838  }
   839  
   840  func (self *stateObject) GetUnStakingHeight() *big.Int {
   841  	return self.data.UnStaking.StartHeight
   842  }
   843  
   844  func (self *stateObject) GetTotalStaking() *big.Int {
   845  	total := big.NewInt(0)
   846  	if nil != self.data.Stakings && len(self.data.Stakings) > 0 {
   847  		for _,staking := range self.data.Stakings {
   848  			total.Add(total, staking.Value)
   849  		}
   850  	}
   851  	return total
   852  }
   853  
   854  func (self *stateObject) GetTotalStakingYear() *big.Int {
   855  	total := big.NewInt(0)
   856  	if nil != self.data.Stakings && len(self.data.Stakings) > 0 {
   857  		for _,staking := range self.data.Stakings {
   858  			if staking.LockHeights.Cmp(params.HeightOf360Days) >= 0{
   859  				total.Add(total, staking.Value)
   860  			}
   861  		}
   862  	}
   863  	return total
   864  }
   865  
   866  func (self *stateObject) Date() *big.Int {
   867  	return self.data.Res.Height
   868  }
   869  
   870  //Resource by zc
   871  func (self *stateObject) Nonce() uint64 {
   872  	return self.data.Nonce
   873  }
   874  
   875  //2019.6.28 inb by ghy begin
   876  func (self *stateObject) Resource() Resource {
   877  	return self.data.Res
   878  }
   879  
   880  //
   881  //func (self *stateObject) MortgageOfINB() *big.Int {
   882  //	return self.data.Res.Mortgage
   883  //}
   884  
   885  //2019.6.28 inb by ghy end
   886  // Never called, but must be present to allow stateObject to be used
   887  // as a vm.Account interface that also satisfies the vm.ContractRef
   888  // interface. Interfaces are awesome.
   889  func (self *stateObject) Value() *big.Int {
   890  	panic("Value on stateObject should never be called")
   891  }