mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-22 11:41:19 +00:00
122 lines
3.9 KiB
Go
122 lines
3.9 KiB
Go
package state
|
|
|
|
import (
|
|
"bytes"
|
|
|
|
"github.com/holiman/uint256"
|
|
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
|
"github.com/ledgerwatch/erigon-lib/kv"
|
|
libstate "github.com/ledgerwatch/erigon-lib/state"
|
|
|
|
"github.com/ledgerwatch/erigon/common"
|
|
"github.com/ledgerwatch/erigon/common/dbutils"
|
|
"github.com/ledgerwatch/erigon/core/types/accounts"
|
|
)
|
|
|
|
type StateReconWriterInc struct {
|
|
as *libstate.AggregatorStep
|
|
rs *ReconState
|
|
txNum uint64
|
|
tx kv.Tx
|
|
chainTx kv.Tx
|
|
}
|
|
|
|
func NewStateReconWriterInc(as *libstate.AggregatorStep, rs *ReconState) *StateReconWriterInc {
|
|
return &StateReconWriterInc{
|
|
as: as,
|
|
rs: rs,
|
|
}
|
|
}
|
|
|
|
func (w *StateReconWriterInc) SetTxNum(txNum uint64) {
|
|
w.txNum = txNum
|
|
}
|
|
|
|
func (w *StateReconWriterInc) SetTx(tx kv.Tx) {
|
|
w.tx = tx
|
|
}
|
|
|
|
func (w *StateReconWriterInc) SetChainTx(chainTx kv.Tx) {
|
|
w.chainTx = chainTx
|
|
}
|
|
|
|
func (w *StateReconWriterInc) UpdateAccountData(address libcommon.Address, original, account *accounts.Account) error {
|
|
addr := address.Bytes()
|
|
if ok, stateTxNum := w.as.MaxTxNumAccounts(addr); !ok || stateTxNum != w.txNum {
|
|
return nil
|
|
}
|
|
value := make([]byte, account.EncodingLengthForStorage())
|
|
if account.Incarnation > 0 {
|
|
account.Incarnation = FirstContractIncarnation
|
|
}
|
|
account.EncodeForStorage(value)
|
|
w.rs.Put(kv.PlainStateR, addr, nil, value, w.txNum)
|
|
return nil
|
|
}
|
|
|
|
func (w *StateReconWriterInc) UpdateAccountCode(address libcommon.Address, incarnation uint64, codeHash libcommon.Hash, code []byte) error {
|
|
addr, codeHashBytes := address.Bytes(), codeHash.Bytes()
|
|
if ok, stateTxNum := w.as.MaxTxNumCode(addr); !ok || stateTxNum != w.txNum {
|
|
return nil
|
|
}
|
|
if len(code) > 0 {
|
|
w.rs.Put(kv.CodeR, codeHashBytes, nil, common.CopyBytes(code), w.txNum)
|
|
w.rs.Put(kv.PlainContractR, dbutils.PlainGenerateStoragePrefix(addr, FirstContractIncarnation), nil, codeHashBytes, w.txNum)
|
|
} else {
|
|
w.rs.Delete(kv.PlainContractD, dbutils.PlainGenerateStoragePrefix(addr, FirstContractIncarnation), nil, w.txNum)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (w *StateReconWriterInc) DeleteAccount(address libcommon.Address, original *accounts.Account) error {
|
|
addr := address.Bytes()
|
|
if ok, stateTxNum := w.as.MaxTxNumAccounts(addr); ok && stateTxNum == w.txNum {
|
|
//fmt.Printf("delete account [%x]=>{} txNum: %d\n", address, w.txNum)
|
|
w.rs.Delete(kv.PlainStateD, addr, nil, w.txNum)
|
|
}
|
|
// Iterate over storage of this contract and delete it too
|
|
var c kv.Cursor
|
|
var err error
|
|
if c, err = w.chainTx.Cursor(kv.PlainState); err != nil {
|
|
return err
|
|
}
|
|
defer c.Close()
|
|
var k []byte
|
|
for k, _, err = c.Seek(addr); err == nil && bytes.HasPrefix(k, addr); k, _, err = c.Next() {
|
|
//fmt.Printf("delete account storage [%x] [%x]=>{} txNum: %d\n", address, k[20+8:], w.txNum)
|
|
if len(k) > 20 {
|
|
w.rs.Delete(kv.PlainStateD, addr, common.CopyBytes(k[20+8:]), w.txNum)
|
|
}
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// Delete all pending storage for this contract
|
|
w.rs.RemoveAll(kv.PlainStateR, addr)
|
|
w.rs.RemoveAll(kv.PlainStateD, addr)
|
|
// Delete code
|
|
if ok, stateTxNum := w.as.MaxTxNumCode(addr); ok && stateTxNum == w.txNum {
|
|
w.rs.Delete(kv.PlainContractD, dbutils.PlainGenerateStoragePrefix(addr, FirstContractIncarnation), nil, w.txNum)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (w *StateReconWriterInc) WriteAccountStorage(address libcommon.Address, incarnation uint64, key *libcommon.Hash, original, value *uint256.Int) error {
|
|
addr, k := address.Bytes(), key.Bytes()
|
|
if ok, stateTxNum := w.as.MaxTxNumStorage(addr, k); !ok || stateTxNum != w.txNum {
|
|
return nil
|
|
}
|
|
if value.IsZero() {
|
|
w.rs.Delete(kv.PlainStateD, addr, k, w.txNum)
|
|
//fmt.Printf("delete storage [%x] [%x] => [%x], txNum: %d\n", address, *key, value.Bytes(), w.txNum)
|
|
} else {
|
|
//fmt.Printf("storage [%x] [%x] => [%x], txNum: %d\n", address, *key, value.Bytes(), w.txNum)
|
|
w.rs.Put(kv.PlainStateR, addr, k, value.Bytes(), w.txNum)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (w *StateReconWriterInc) CreateContract(address libcommon.Address) error {
|
|
return nil
|
|
}
|