github.com/amazechain/amc@v0.1.3/modules/state/entire.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  	"github.com/amazechain/amc/common/account"
    22  	"github.com/amazechain/amc/common/block"
    23  	"github.com/amazechain/amc/common/types"
    24  	"github.com/amazechain/amc/internal/avm/rlp"
    25  	types2 "github.com/amazechain/amc/internal/avm/types"
    26  	"github.com/amazechain/amc/modules"
    27  	"io"
    28  	"unsafe"
    29  )
    30  
    31  type GetOneFun func(table string, key []byte) ([]byte, error)
    32  
    33  type EntireCode struct {
    34  	CoinBase types.Address   `json:"coinBase"`
    35  	Entire   Entire          `json:"entire"`
    36  	Codes    []*HashCode     `json:"codes"`
    37  	Headers  []*block.Header `json:"headers"`
    38  	Rewards  []*block.Reward `json:"rewards"`
    39  }
    40  
    41  type HashCode struct {
    42  	Hash types.Hash `json:"hash"`
    43  	Code []byte     `json:"code"`
    44  }
    45  
    46  type HashCodes []*HashCode
    47  
    48  func (s HashCodes) Len() int           { return len(s) }
    49  func (s HashCodes) Less(i, j int) bool { return bytes.Compare(s[i].Hash[:], s[j].Hash[:]) < 0 }
    50  func (s HashCodes) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
    51  
    52  type Entire struct {
    53  	Header       *block.Header    `json:"header"`
    54  	Uncles       []*types2.Header `json:"uncles"`
    55  	Transactions [][]byte         `json:"transactions"`
    56  	Snap         *Snapshot        `json:"snap"`
    57  	Proof        types.Hash       `json:"proof"`
    58  	Senders      []types.Address  `json:"senders"`
    59  }
    60  
    61  func (e Entire) Clone() Entire {
    62  	var c Entire
    63  	//c.Header = &types2.Header{
    64  	//	ParentHash:  e.Header.ParentHash,
    65  	//	UncleHash:   e.Header.UncleHash,
    66  	//	Coinbase:    e.Header.Coinbase,
    67  	//	Root:        e.Header.Root,
    68  	//	TxHash:      e.Header.TxHash,
    69  	//	ReceiptHash: e.Header.ReceiptHash,
    70  	//	Bloom:       e.Header.Bloom,
    71  	//	Difficulty:  e.Header.Difficulty,
    72  	//	Number:      e.Header.Number,
    73  	//	GasLimit:    e.Header.GasLimit,
    74  	//	GasUsed:     e.Header.GasUsed,
    75  	//	Time:        e.Header.Time,
    76  	//	Extra:       e.Header.Extra,
    77  	//	MixDigest:   e.Header.MixDigest,
    78  	//	Nonce:       e.Header.Nonce,
    79  	//	BaseFee:     e.Header.BaseFee,
    80  	//}
    81  	copyHeader := *e.Header
    82  	c.Header = &copyHeader
    83  	c.Uncles = e.Uncles
    84  	c.Transactions = e.Transactions
    85  	c.Proof = e.Proof
    86  	c.Senders = e.Senders
    87  	c.Snap = &Snapshot{
    88  		Items:     e.Snap.Items,
    89  		OutHash:   e.Snap.OutHash,
    90  		accounts:  e.Snap.accounts,
    91  		storage:   e.Snap.storage,
    92  		written:   e.Snap.written,
    93  		getOneFun: e.Snap.getOneFun,
    94  	}
    95  	return c
    96  }
    97  
    98  type Items []*Item
    99  
   100  func (s Items) Len() int           { return len(s) }
   101  func (s Items) Less(i, j int) bool { return bytes.Compare(s[i].Key, s[j].Key) < 0 }
   102  func (s Items) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
   103  
   104  type Item struct {
   105  	Key   []byte `json:"key"`
   106  	Value []byte `json:"value"`
   107  }
   108  
   109  type Snapshot struct {
   110  	Items     Items          `json:"items"`
   111  	OutHash   types.Hash     `json:"outHash"`
   112  	accounts  map[string]int `json:"accounts"`
   113  	storage   map[string]int `json:"storage"`
   114  	written   bool           `json:"written"`
   115  	getOneFun GetOneFun      `json:"getOneFun"`
   116  }
   117  
   118  func NewWritableSnapshot() *Snapshot {
   119  	return &Snapshot{Items: make([]*Item, 0), written: true, OutHash: emptyCodeHashH, accounts: make(map[string]int), storage: make(map[string]int)}
   120  }
   121  
   122  func NewReadableSnapshot() *Snapshot {
   123  	return &Snapshot{Items: make([]*Item, 0), written: false, OutHash: emptyCodeHashH, accounts: make(map[string]int), storage: make(map[string]int)}
   124  }
   125  
   126  func (s *Snapshot) SetGetFun(f GetOneFun) {
   127  	s.getOneFun = f
   128  }
   129  
   130  func (s *Snapshot) ReadAccountStorage(address types.Address, incarnation uint16, key *types.Hash) ([]byte, error) {
   131  	if s.written {
   132  		return nil, nil
   133  	}
   134  	compositeKey := modules.PlainGenerateCompositeStorageKey(address.Bytes(), incarnation, key.Bytes())
   135  	index, ok := s.storage[*(*string)(unsafe.Pointer(&compositeKey))]
   136  	if !ok {
   137  		if s.getOneFun != nil {
   138  			return s.getOneFun(modules.Storage, compositeKey)
   139  		}
   140  		return nil, nil
   141  	}
   142  	if s.Items[index] == nil {
   143  		return nil, nil
   144  	}
   145  	return s.Items[index].Value, nil
   146  }
   147  
   148  func (s *Snapshot) CanWrite() bool {
   149  	return s.written
   150  }
   151  
   152  func ReadSnapshotData(data []byte) (*Snapshot, error) {
   153  	snap := NewReadableSnapshot()
   154  	if len(data) == 0 {
   155  		return snap, nil
   156  	}
   157  	if err := rlp.DecodeBytes(data, &snap); err != nil {
   158  		return nil, err
   159  	}
   160  	for k, v := range snap.Items {
   161  		if len(v.Key) == types.AddressLength {
   162  			snap.accounts[*(*string)(unsafe.Pointer(&v.Key))] = k
   163  		} else {
   164  			snap.storage[*(*string)(unsafe.Pointer(&v.Key))] = k
   165  		}
   166  	}
   167  	return snap, nil
   168  }
   169  
   170  func (s *Snapshot) SetHash(hash types.Hash) {
   171  	if s.written {
   172  		return
   173  	}
   174  	s.OutHash = hash
   175  }
   176  
   177  func (s *Snapshot) ReadAccountData(address types.Address) (*account.StateAccount, error) {
   178  	if s.written {
   179  		return nil, nil
   180  	}
   181  	addr := address[:]
   182  	index, ok := s.accounts[*(*string)(unsafe.Pointer(&addr))]
   183  	if !ok {
   184  		if s.getOneFun != nil {
   185  			v, err := s.getOneFun(modules.Account, address[:])
   186  			if err != nil {
   187  				return nil, err
   188  			}
   189  			if v == nil {
   190  				return nil, nil
   191  			}
   192  			var acc account.StateAccount
   193  			if err := acc.DecodeForStorage(v); err != nil {
   194  				return nil, err
   195  			}
   196  			return &acc, nil
   197  		}
   198  		return nil, nil
   199  	}
   200  	if s.Items[index] == nil {
   201  		return nil, nil
   202  	}
   203  	var acc account.StateAccount
   204  	if err := acc.DecodeForStorage(s.Items[index].Value); err != nil {
   205  		return nil, err
   206  	}
   207  	return &acc, nil
   208  }
   209  
   210  func (s *Snapshot) AddAccount(address types.Address, account *account.StateAccount) {
   211  	if !s.written || account == nil {
   212  		return
   213  	}
   214  	value := make([]byte, account.EncodingLengthForStorage())
   215  	account.EncodeForStorage(value)
   216  	s.Items = append(s.Items, &Item{Key: address[:], Value: value})
   217  	ss := address[:]
   218  	//fmt.Println("address", address.Hex())
   219  	s.accounts[*(*string)(unsafe.Pointer(&ss))] = len(s.Items)
   220  }
   221  
   222  func (s *Snapshot) AddStorage(address types.Address, key *types.Hash, incarnation uint16, value []byte) {
   223  	if !s.written || len(value) == 0 {
   224  		return
   225  	}
   226  	compositeKey := modules.PlainGenerateCompositeStorageKey(address.Bytes(), incarnation, key.Bytes())
   227  	s.Items = append(s.Items, &Item{Key: compositeKey, Value: value})
   228  	//fmt.Println("address", address.Hex(), key.Hex())
   229  	s.storage[*(*string)(unsafe.Pointer(&compositeKey))] = len(s.storage)
   230  }
   231  
   232  func EncodeBeforeState(w io.Writer, list Items, codeHash HashCodes) {
   233  	enc := make([]interface{}, 0, len(list)*2+len(codeHash)*2)
   234  	for _, i := range list {
   235  		enc = append(enc, i.Key, i.Value)
   236  	}
   237  
   238  	for _, h := range codeHash {
   239  		enc = append(enc, h.Hash, h.Code)
   240  	}
   241  	if err := rlp.Encode(w, enc); nil != err {
   242  		panic("before state encode failed:" + err.Error())
   243  	}
   244  }