2020-03-11 15:54:09 +00:00
|
|
|
package state
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
2020-05-25 11:12:25 +00:00
|
|
|
"github.com/holiman/uint256"
|
2023-12-12 10:03:41 +00:00
|
|
|
|
2023-01-13 18:12:18 +00:00
|
|
|
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
|
|
|
"github.com/ledgerwatch/erigon-lib/common/hexutility"
|
2021-07-29 11:53:13 +00:00
|
|
|
"github.com/ledgerwatch/erigon-lib/kv"
|
2023-12-12 10:03:41 +00:00
|
|
|
"github.com/ledgerwatch/erigon-lib/kv/dbutils"
|
2022-12-19 08:38:54 +00:00
|
|
|
historyv22 "github.com/ledgerwatch/erigon-lib/kv/temporal/historyv2"
|
2023-01-13 18:12:18 +00:00
|
|
|
|
2021-05-20 18:25:53 +00:00
|
|
|
"github.com/ledgerwatch/erigon/core/types/accounts"
|
2020-03-11 15:54:09 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// ChangeSetWriter is a mock StateWriter that accumulates changes in-memory into ChangeSets.
|
|
|
|
type ChangeSetWriter struct {
|
2021-07-28 02:47:38 +00:00
|
|
|
db kv.RwTx
|
2023-01-13 18:12:18 +00:00
|
|
|
accountChanges map[libcommon.Address][]byte
|
|
|
|
storageChanged map[libcommon.Address]bool
|
2020-03-11 15:54:09 +00:00
|
|
|
storageChanges map[string][]byte
|
2020-07-01 14:56:56 +00:00
|
|
|
blockNumber uint64
|
2020-03-11 15:54:09 +00:00
|
|
|
}
|
|
|
|
|
2021-01-20 07:16:20 +00:00
|
|
|
func NewChangeSetWriter() *ChangeSetWriter {
|
|
|
|
return &ChangeSetWriter{
|
2023-01-13 18:12:18 +00:00
|
|
|
accountChanges: make(map[libcommon.Address][]byte),
|
|
|
|
storageChanged: make(map[libcommon.Address]bool),
|
2021-01-20 07:16:20 +00:00
|
|
|
storageChanges: make(map[string][]byte),
|
|
|
|
}
|
|
|
|
}
|
2021-07-28 02:47:38 +00:00
|
|
|
func NewChangeSetWriterPlain(db kv.RwTx, blockNumber uint64) *ChangeSetWriter {
|
2020-05-15 07:52:45 +00:00
|
|
|
return &ChangeSetWriter{
|
2020-12-08 09:44:29 +00:00
|
|
|
db: db,
|
2023-01-13 18:12:18 +00:00
|
|
|
accountChanges: make(map[libcommon.Address][]byte),
|
|
|
|
storageChanged: make(map[libcommon.Address]bool),
|
2020-05-15 07:52:45 +00:00
|
|
|
storageChanges: make(map[string][]byte),
|
2020-07-01 14:56:56 +00:00
|
|
|
blockNumber: blockNumber,
|
2020-03-11 15:54:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-19 08:38:54 +00:00
|
|
|
func (w *ChangeSetWriter) GetAccountChanges() (*historyv22.ChangeSet, error) {
|
|
|
|
cs := historyv22.NewAccountChangeSet()
|
2020-05-15 07:52:45 +00:00
|
|
|
for address, val := range w.accountChanges {
|
2023-10-21 23:17:18 +00:00
|
|
|
if err := cs.Add(libcommon.CopyBytes(address[:]), val); err != nil {
|
2020-04-09 17:23:29 +00:00
|
|
|
return nil, err
|
2020-03-11 15:54:09 +00:00
|
|
|
}
|
|
|
|
}
|
2020-04-09 17:23:29 +00:00
|
|
|
return cs, nil
|
2020-03-11 15:54:09 +00:00
|
|
|
}
|
2022-12-19 08:38:54 +00:00
|
|
|
func (w *ChangeSetWriter) GetStorageChanges() (*historyv22.ChangeSet, error) {
|
|
|
|
cs := historyv22.NewStorageChangeSet()
|
2020-03-11 15:54:09 +00:00
|
|
|
for key, val := range w.storageChanges {
|
|
|
|
if err := cs.Add([]byte(key), val); err != nil {
|
2020-04-09 17:23:29 +00:00
|
|
|
return nil, err
|
2020-03-11 15:54:09 +00:00
|
|
|
}
|
|
|
|
}
|
2020-04-09 17:23:29 +00:00
|
|
|
return cs, nil
|
2020-03-11 15:54:09 +00:00
|
|
|
}
|
|
|
|
|
2020-05-06 08:58:12 +00:00
|
|
|
func accountsEqual(a1, a2 *accounts.Account) bool {
|
|
|
|
if a1.Nonce != a2.Nonce {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
if !a1.Initialised {
|
|
|
|
if a2.Initialised {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
} else if !a2.Initialised {
|
|
|
|
return false
|
|
|
|
} else if a1.Balance.Cmp(&a2.Balance) != 0 {
|
|
|
|
return false
|
2023-12-12 10:03:41 +00:00
|
|
|
} else if a1.Incarnation != a2.Incarnation {
|
|
|
|
return false
|
2020-05-06 08:58:12 +00:00
|
|
|
}
|
2020-07-01 14:56:56 +00:00
|
|
|
if a1.IsEmptyCodeHash() {
|
|
|
|
if !a2.IsEmptyCodeHash() {
|
2020-05-06 08:58:12 +00:00
|
|
|
return false
|
|
|
|
}
|
2020-07-01 14:56:56 +00:00
|
|
|
} else if a2.IsEmptyCodeHash() {
|
2020-05-06 08:58:12 +00:00
|
|
|
return false
|
|
|
|
} else if a1.CodeHash != a2.CodeHash {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2023-01-13 18:12:18 +00:00
|
|
|
func (w *ChangeSetWriter) UpdateAccountData(address libcommon.Address, original, account *accounts.Account) error {
|
2022-06-04 15:54:22 +00:00
|
|
|
//fmt.Printf("balance,%x,%d\n", address, &account.Balance)
|
2020-03-11 15:54:09 +00:00
|
|
|
if !accountsEqual(original, account) || w.storageChanged[address] {
|
2020-04-15 09:33:22 +00:00
|
|
|
w.accountChanges[address] = originalAccountData(original, true /*omitHashes*/)
|
2020-03-11 15:54:09 +00:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-01-13 18:12:18 +00:00
|
|
|
func (w *ChangeSetWriter) UpdateAccountCode(address libcommon.Address, incarnation uint64, codeHash libcommon.Hash, code []byte) error {
|
2022-06-04 15:54:22 +00:00
|
|
|
//fmt.Printf("code,%x,%x\n", address, code)
|
2020-03-11 15:54:09 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-01-13 18:12:18 +00:00
|
|
|
func (w *ChangeSetWriter) DeleteAccount(address libcommon.Address, original *accounts.Account) error {
|
2022-06-04 15:54:22 +00:00
|
|
|
//fmt.Printf("delete,%x\n", address)
|
|
|
|
if original == nil || !original.Initialised {
|
|
|
|
return nil
|
|
|
|
}
|
2020-03-26 21:52:22 +00:00
|
|
|
w.accountChanges[address] = originalAccountData(original, false)
|
2020-03-11 15:54:09 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-01-13 18:12:18 +00:00
|
|
|
func (w *ChangeSetWriter) WriteAccountStorage(address libcommon.Address, incarnation uint64, key *libcommon.Hash, original, value *uint256.Int) error {
|
2022-06-04 15:54:22 +00:00
|
|
|
//fmt.Printf("storage,%x,%x,%x\n", address, *key, value.Bytes())
|
2020-03-11 15:54:09 +00:00
|
|
|
if *original == *value {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-05-16 05:21:29 +00:00
|
|
|
compositeKey := dbutils.PlainGenerateCompositeStorageKey(address.Bytes(), incarnation, key.Bytes())
|
2020-03-11 15:54:09 +00:00
|
|
|
|
2020-05-25 11:12:25 +00:00
|
|
|
w.storageChanges[string(compositeKey)] = original.Bytes()
|
2020-03-11 15:54:09 +00:00
|
|
|
w.storageChanged[address] = true
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-01-13 18:12:18 +00:00
|
|
|
func (w *ChangeSetWriter) CreateContract(address libcommon.Address) error {
|
2020-05-02 18:00:42 +00:00
|
|
|
return nil
|
2020-03-11 15:54:09 +00:00
|
|
|
}
|
|
|
|
|
2020-12-08 09:44:29 +00:00
|
|
|
func (w *ChangeSetWriter) WriteChangeSets() error {
|
|
|
|
accountChanges, err := w.GetAccountChanges()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-12-19 08:38:54 +00:00
|
|
|
if err = historyv22.Mapper[kv.AccountChangeSet].Encode(w.blockNumber, accountChanges, func(k, v []byte) error {
|
2021-07-28 02:47:38 +00:00
|
|
|
if err = w.db.AppendDup(kv.AccountChangeSet, k, v); err != nil {
|
2021-06-19 20:29:02 +00:00
|
|
|
return err
|
2020-12-08 09:44:29 +00:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
storageChanges, err := w.GetStorageChanges()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if storageChanges.Len() == 0 {
|
|
|
|
return nil
|
|
|
|
}
|
2022-12-19 08:38:54 +00:00
|
|
|
if err = historyv22.Mapper[kv.StorageChangeSet].Encode(w.blockNumber, storageChanges, func(k, v []byte) error {
|
2021-07-28 02:47:38 +00:00
|
|
|
if err = w.db.AppendDup(kv.StorageChangeSet, k, v); err != nil {
|
2021-06-19 20:29:02 +00:00
|
|
|
return err
|
2020-12-08 09:44:29 +00:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *ChangeSetWriter) WriteHistory() error {
|
|
|
|
accountChanges, err := w.GetAccountChanges()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-06-11 14:12:05 +00:00
|
|
|
err = writeIndex(w.blockNumber, accountChanges, kv.E2AccountsHistory, w.db)
|
2020-12-08 09:44:29 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
storageChanges, err := w.GetStorageChanges()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-06-11 14:12:05 +00:00
|
|
|
err = writeIndex(w.blockNumber, storageChanges, kv.E2StorageHistory, w.db)
|
2020-12-08 09:44:29 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-03-11 15:54:09 +00:00
|
|
|
func (w *ChangeSetWriter) PrintChangedAccounts() {
|
|
|
|
fmt.Println("Account Changes")
|
|
|
|
for k := range w.accountChanges {
|
2023-01-13 18:12:18 +00:00
|
|
|
fmt.Println(hexutility.Encode(k.Bytes()))
|
2020-03-11 15:54:09 +00:00
|
|
|
}
|
|
|
|
fmt.Println("------------------------------------------")
|
|
|
|
}
|