github.com/amazechain/amc@v0.1.3/modules/state/plain_readonly.go (about)

     1  // Copyright 2023 The AmazeChain Authors
     2  // This file is part of the AmazeChain library.
     3  //
     4  // The AmazeChain 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 Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The AmazeChain 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 AmazeChain library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package state
    18  
    19  import (
    20  	"bytes"
    21  	"encoding/binary"
    22  	"fmt"
    23  	"github.com/amazechain/amc/common/account"
    24  	"github.com/amazechain/amc/common/types"
    25  	"github.com/amazechain/amc/log"
    26  	"github.com/amazechain/amc/modules"
    27  	"github.com/google/btree"
    28  	"github.com/holiman/uint256"
    29  	"github.com/ledgerwatch/erigon-lib/kv"
    30  )
    31  
    32  type storageItem struct {
    33  	key, seckey types.Hash
    34  	value       uint256.Int
    35  }
    36  
    37  func (a *storageItem) Less(b btree.Item) bool {
    38  	bi := b.(*storageItem)
    39  	return bytes.Compare(a.key[:], bi.key[:]) < 0
    40  }
    41  
    42  // State at the beginning of blockNr
    43  type PlainState struct {
    44  	accHistoryC, storageHistoryC kv.Cursor
    45  	accChangesC, storageChangesC kv.CursorDupSort
    46  	tx                           kv.Tx
    47  	blockNr                      uint64
    48  	storage                      map[types.Address]*btree.BTree
    49  	trace                        bool
    50  }
    51  
    52  func NewPlainState(tx kv.Tx, blockNr uint64) *PlainState {
    53  	c1, _ := tx.Cursor(modules.AccountsHistory)
    54  	c2, _ := tx.Cursor(modules.StorageHistory)
    55  	c3, _ := tx.CursorDupSort(modules.AccountChangeSet)
    56  	c4, _ := tx.CursorDupSort(modules.StorageChangeSet)
    57  
    58  	return &PlainState{
    59  		tx:          tx,
    60  		blockNr:     blockNr,
    61  		storage:     make(map[types.Address]*btree.BTree),
    62  		accHistoryC: c1, storageHistoryC: c2, accChangesC: c3, storageChangesC: c4,
    63  	}
    64  }
    65  
    66  func (s *PlainState) SetTrace(trace bool) {
    67  	s.trace = trace
    68  }
    69  
    70  func (s *PlainState) SetBlockNr(blockNr uint64) {
    71  	s.blockNr = blockNr
    72  }
    73  
    74  func (s *PlainState) GetBlockNr() uint64 {
    75  	return s.blockNr
    76  }
    77  
    78  func (s *PlainState) ForEachStorage(addr types.Address, startLocation types.Hash, cb func(key, seckey types.Hash, value uint256.Int) bool, maxResults int) error {
    79  	st := btree.New(16)
    80  	var k [types.AddressLength + types.IncarnationLength + types.HashLength]byte
    81  	copy(k[:], addr[:])
    82  	accData, err := GetAsOf(s.tx, s.accHistoryC, s.accChangesC, false /* storage */, addr[:], s.blockNr)
    83  	if err != nil {
    84  		return err
    85  	}
    86  	var acc account.StateAccount
    87  	if err := acc.DecodeForStorage(accData); err != nil {
    88  		log.Error("Error decoding account", "err", err)
    89  		return err
    90  	}
    91  	binary.BigEndian.PutUint16(k[types.AddressLength:], acc.Incarnation)
    92  	copy(k[types.AddressLength+types.IncarnationLength:], startLocation[:])
    93  	var lastKey types.Hash
    94  	overrideCounter := 0
    95  	min := &storageItem{key: startLocation}
    96  	if t, ok := s.storage[addr]; ok {
    97  		t.AscendGreaterOrEqual(min, func(i btree.Item) bool {
    98  			item := i.(*storageItem)
    99  			st.ReplaceOrInsert(item)
   100  			if !item.value.IsZero() {
   101  				copy(lastKey[:], item.key[:])
   102  				// Only count non-zero items
   103  				overrideCounter++
   104  			}
   105  			return overrideCounter < maxResults
   106  		})
   107  	}
   108  	numDeletes := st.Len() - overrideCounter
   109  	if err := WalkAsOfStorage(s.tx, addr, acc.Incarnation, startLocation, s.blockNr, func(kAddr, kLoc, vs []byte) (bool, error) {
   110  		if !bytes.Equal(kAddr, addr[:]) {
   111  			return false, nil
   112  		}
   113  		if len(vs) == 0 {
   114  			// Skip deleted entries
   115  			return true, nil
   116  		}
   117  		keyHash, err1 := types.HashData(kLoc)
   118  		if err1 != nil {
   119  			return false, err1
   120  		}
   121  		//fmt.Printf("seckey: %x\n", seckey)
   122  		si := storageItem{}
   123  		copy(si.key[:], kLoc)
   124  		copy(si.seckey[:], keyHash[:])
   125  		if st.Has(&si) {
   126  			return true, nil
   127  		}
   128  		si.value.SetBytes(vs)
   129  		st.ReplaceOrInsert(&si)
   130  		if bytes.Compare(kLoc, lastKey[:]) > 0 {
   131  			// Beyond overrides
   132  			return st.Len() < maxResults+numDeletes, nil
   133  		}
   134  		return st.Len() < maxResults+overrideCounter+numDeletes, nil
   135  	}); err != nil {
   136  		log.Error("ForEachStorage walk error", "err", err)
   137  		return err
   138  	}
   139  	results := 0
   140  	var innerErr error
   141  	st.AscendGreaterOrEqual(min, func(i btree.Item) bool {
   142  		item := i.(*storageItem)
   143  		if !item.value.IsZero() {
   144  			// Skip if value == 0
   145  			cb(item.key, item.seckey, item.value)
   146  			results++
   147  		}
   148  		return results < maxResults
   149  	})
   150  	return innerErr
   151  }
   152  
   153  func (s *PlainState) ReadAccountData(address types.Address) (*account.StateAccount, error) {
   154  	enc, err := GetAsOf(s.tx, s.accHistoryC, s.accChangesC, false /* storage */, address[:], s.blockNr)
   155  	if err != nil {
   156  		return nil, err
   157  	}
   158  	if len(enc) == 0 {
   159  		if s.trace {
   160  			fmt.Printf("ReadAccountData [%x] => []\n", address)
   161  		}
   162  		return nil, nil
   163  	}
   164  	var a account.StateAccount
   165  	if err = a.DecodeForStorage(enc); err != nil {
   166  		return nil, err
   167  	}
   168  	//restore codehash
   169  	if a.Incarnation > 0 && a.IsEmptyCodeHash() {
   170  		if codeHash, err1 := s.tx.GetOne(modules.PlainContractCode, modules.PlainGenerateStoragePrefix(address[:], a.Incarnation)); err1 == nil {
   171  			if len(codeHash) > 0 {
   172  				a.CodeHash = types.BytesToHash(codeHash)
   173  			}
   174  		} else {
   175  			return nil, err1
   176  		}
   177  	}
   178  	if s.trace {
   179  		fmt.Printf("ReadAccountData [%x] => [nonce: %d, balance: %d, codeHash: %x]\n", address, a.Nonce, &a.Balance, a.CodeHash)
   180  	}
   181  	return &a, nil
   182  }
   183  
   184  func (s *PlainState) ReadAccountStorage(address types.Address, incarnation uint16, key *types.Hash) ([]byte, error) {
   185  	compositeKey := modules.PlainGenerateCompositeStorageKey(address.Bytes(), incarnation, key.Bytes())
   186  	enc, err := GetAsOf(s.tx, s.storageHistoryC, s.storageChangesC, true /* storage */, compositeKey, s.blockNr)
   187  	if err != nil {
   188  		return nil, err
   189  	}
   190  	if s.trace {
   191  		fmt.Printf("ReadAccountStorage [%x] [%x] => [%x]\n", address, *key, enc)
   192  	}
   193  	if len(enc) == 0 {
   194  		return nil, nil
   195  	}
   196  	return enc, nil
   197  }
   198  
   199  func (s *PlainState) ReadAccountCode(address types.Address, incarnation uint16, codeHash types.Hash) ([]byte, error) {
   200  	if bytes.Equal(codeHash[:], emptyCodeHash) {
   201  		return nil, nil
   202  	}
   203  	code, err := s.tx.GetOne(modules.Code, codeHash[:])
   204  	if s.trace {
   205  		fmt.Printf("ReadAccountCode [%x %x] => [%x]\n", address, codeHash, code)
   206  	}
   207  	if len(code) == 0 {
   208  		return nil, nil
   209  	}
   210  	return code, err
   211  }
   212  
   213  func (s *PlainState) ReadAccountCodeSize(address types.Address, incarnation uint16, codeHash types.Hash) (int, error) {
   214  	code, err := s.ReadAccountCode(address, incarnation, codeHash)
   215  	return len(code), err
   216  }
   217  
   218  func (s *PlainState) ReadAccountIncarnation(address types.Address) (uint16, error) {
   219  	enc, err := GetAsOf(s.tx, s.accHistoryC, s.accChangesC, false /* storage */, address[:], s.blockNr+1)
   220  	if err != nil {
   221  		return 0, err
   222  	}
   223  	if len(enc) == 0 {
   224  		return 0, nil
   225  	}
   226  	var acc account.StateAccount
   227  	if err = acc.DecodeForStorage(enc); err != nil {
   228  		return 0, err
   229  	}
   230  	if acc.Incarnation == 0 {
   231  		return 0, nil
   232  	}
   233  	return acc.Incarnation - 1, nil
   234  }
   235  
   236  func (s *PlainState) UpdateAccountData(address types.Address, original, account *account.StateAccount) error {
   237  	return nil
   238  }
   239  
   240  func (s *PlainState) DeleteAccount(address types.Address, original *account.StateAccount) error {
   241  	return nil
   242  }
   243  
   244  func (s *PlainState) UpdateAccountCode(address types.Address, incarnation uint16, codeHash types.Hash, code []byte) error {
   245  	return nil
   246  }
   247  
   248  func (s *PlainState) WriteAccountStorage(address types.Address, incarnation uint16, key *types.Hash, original, value *uint256.Int) error {
   249  	t, ok := s.storage[address]
   250  	if !ok {
   251  		t = btree.New(16)
   252  		s.storage[address] = t
   253  	}
   254  	h := types.NewHasher()
   255  	defer types.ReturnHasherToPool(h)
   256  	h.Sha.Reset()
   257  	_, err := h.Sha.Write(key[:])
   258  	if err != nil {
   259  		return err
   260  	}
   261  	i := &storageItem{key: *key, value: *value}
   262  	_, err = h.Sha.Read(i.seckey[:])
   263  	if err != nil {
   264  		return err
   265  	}
   266  
   267  	t.ReplaceOrInsert(i)
   268  	return nil
   269  }
   270  
   271  func (s *PlainState) CreateContract(address types.Address) error {
   272  	delete(s.storage, address)
   273  	return nil
   274  }