Skip to content

Commit 34c7234

Browse files
committed
erigon store account
1 parent 9d87eaa commit 34c7234

10 files changed

+620
-26
lines changed

action/protocol/execution/evm/evmstatedbadapter_erigon.go

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package evm
22

33
import (
4+
"context"
45
"time"
56

67
erigonchain "github.com/erigontech/erigon-lib/chain"
@@ -14,6 +15,7 @@ import (
1415

1516
"github.com/iotexproject/go-pkgs/hash"
1617

18+
"github.com/iotexproject/iotex-core/v2/action/protocol"
1719
"github.com/iotexproject/iotex-core/v2/blockchain/genesis"
1820
"github.com/iotexproject/iotex-core/v2/pkg/log"
1921
"github.com/iotexproject/iotex-core/v2/state"
@@ -222,6 +224,11 @@ func NewErigonRules(rules *params.Rules) *erigonchain.Rules {
222224
}
223225

224226
// NewChainConfig creates a new chain config
225-
func NewChainConfig(g genesis.Blockchain, height uint64, id uint32, getBlockTime func(uint64) (*time.Time, error)) (*params.ChainConfig, error) {
226-
return getChainConfig(g, height, id, getBlockTime)
227+
func NewChainConfig(ctx context.Context) (*params.ChainConfig, error) {
228+
blkCtx := protocol.MustGetBlockCtx(ctx)
229+
g := genesis.MustExtractGenesisContext(ctx)
230+
bcCtx := protocol.MustGetBlockchainCtx(ctx)
231+
return getChainConfig(g.Blockchain, blkCtx.BlockHeight, bcCtx.EvmNetworkID, func(height uint64) (*time.Time, error) {
232+
return blockHeightToTime(ctx, height)
233+
})
227234
}

blockchain/config.go

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ type (
3838
ContractStakingIndexDBPath string `yaml:"contractStakingIndexDBPath"`
3939
BlobStoreDBPath string `yaml:"blobStoreDBPath"`
4040
BlobStoreRetentionDays uint32 `yaml:"blobStoreRetentionDays"`
41+
HistoryIndexPath string `yaml:"historyIndexPath"`
4142
ID uint32 `yaml:"id"`
4243
EVMNetworkID uint32 `yaml:"evmNetworkID"`
4344
Address string `yaml:"address"`

state/factory/statedb.go

+75-4
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ type (
5454
protocolView *protocol.Views
5555
skipBlockValidationOnPut bool
5656
ps *patchStore
57+
erigonDB *erigonDB
5758
}
5859
)
5960

@@ -118,6 +119,10 @@ func NewStateDB(cfg Config, dao db.KVStore, opts ...StateDBOption) (Factory, err
118119
log.L().Error("Failed to generate prometheus timer factory.", zap.Error(err))
119120
}
120121
sdb.timerFactory = timerFactory
122+
if len(cfg.Chain.HistoryIndexPath) > 0 {
123+
sdb.erigonDB = newErigonDB(cfg.Chain.HistoryIndexPath)
124+
}
125+
121126
return &sdb, nil
122127
}
123128

@@ -126,6 +131,11 @@ func (sdb *stateDB) Start(ctx context.Context) error {
126131
if err := sdb.dao.Start(ctx); err != nil {
127132
return err
128133
}
134+
if sdb.erigonDB != nil {
135+
if err := sdb.erigonDB.Start(ctx); err != nil {
136+
return err
137+
}
138+
}
129139
// check factory height
130140
h, err := sdb.dao.getHeight()
131141
switch errors.Cause(err) {
@@ -166,6 +176,9 @@ func (sdb *stateDB) Stop(ctx context.Context) error {
166176
sdb.mutex.Lock()
167177
defer sdb.mutex.Unlock()
168178
sdb.workingsets.Clear()
179+
if sdb.erigonDB != nil {
180+
sdb.erigonDB.Stop(ctx)
181+
}
169182
return sdb.dao.Stop(ctx)
170183
}
171184

@@ -223,6 +236,35 @@ func (sdb *stateDB) createWorkingSetStore(ctx context.Context, height uint64, kv
223236
return newStateDBWorkingSetStore(flusher, g.IsNewfoundland(height)), nil
224237
}
225238

239+
func (sdb *stateDB) newWorkingSetWithErigonOutput(ctx context.Context, height uint64) (*workingSet, error) {
240+
ws, err := sdb.newWorkingSet(ctx, height)
241+
if err != nil {
242+
return nil, err
243+
}
244+
e, err := sdb.erigonDB.newErigonStore(ctx, height)
245+
if err != nil {
246+
return nil, err
247+
}
248+
ws.store = newWorkingSetStoreWithSecondary(
249+
ws.store.(*stateDBWorkingSetStore),
250+
e,
251+
)
252+
return ws, nil
253+
}
254+
255+
func (sdb *stateDB) newWorkingSetWithErigonDryrun(ctx context.Context, height uint64) (*workingSet, error) {
256+
ws, err := sdb.newWorkingSet(ctx, height)
257+
if err != nil {
258+
return nil, err
259+
}
260+
e, err := sdb.erigonDB.newErigonStoreDryrun(ctx, height+1)
261+
if err != nil {
262+
return nil, err
263+
}
264+
ws.store = newErigonWorkingSetStoreForSimulate(ws.store.(*stateDBWorkingSetStore), e)
265+
return ws, nil
266+
}
267+
226268
func (sdb *stateDB) Register(p protocol.Protocol) error {
227269
return p.Register(sdb.registry)
228270
}
@@ -274,7 +316,11 @@ func (sdb *stateDB) Mint(
274316
case currHeight+1 > expectedBlockHeight:
275317
return nil, errors.Wrapf(ErrNotSupported, "cannot create block at height %d, current height is %d", expectedBlockHeight, sdb.currentChainHeight)
276318
default:
277-
ws, err = sdb.newWorkingSet(ctx, currHeight+1)
319+
if sdb.erigonDB != nil {
320+
ws, err = sdb.newWorkingSetWithErigonOutput(ctx, currHeight+1)
321+
} else {
322+
ws, err = sdb.newWorkingSet(ctx, currHeight+1)
323+
}
278324
}
279325
if err != nil {
280326
return nil, err
@@ -315,7 +361,15 @@ func (sdb *stateDB) WorkingSet(ctx context.Context) (protocol.StateManager, erro
315361
}
316362

317363
func (sdb *stateDB) WorkingSetAtHeight(ctx context.Context, height uint64, preacts ...*action.SealedEnvelope) (protocol.StateManager, error) {
318-
ws, err := sdb.newReadOnlyWorkingSet(ctx, height)
364+
var (
365+
ws *workingSet
366+
err error
367+
)
368+
if sdb.erigonDB != nil {
369+
ws, err = sdb.newWorkingSetWithErigonDryrun(ctx, height)
370+
} else {
371+
ws, err = sdb.newReadOnlyWorkingSet(ctx, height)
372+
}
319373
if err != nil {
320374
return nil, errors.Wrap(err, "failed to obtain working set from state db")
321375
}
@@ -353,6 +407,7 @@ func (sdb *stateDB) PutBlock(ctx context.Context, blk *block.Block) error {
353407
}
354408
if err != nil {
355409
log.L().Error("Failed to update state.", zap.Error(err))
410+
ws.Close()
356411
return err
357412
}
358413
}
@@ -461,7 +516,15 @@ func (sdb *stateDB) state(h uint64, ns string, addr []byte, s interface{}) error
461516
}
462517

463518
func (sdb *stateDB) createGenesisStates(ctx context.Context) error {
464-
ws, err := sdb.newWorkingSet(ctx, 0)
519+
var (
520+
ws *workingSet
521+
err error
522+
)
523+
if sdb.erigonDB != nil {
524+
ws, err = sdb.newWorkingSetWithErigonOutput(ctx, 0)
525+
} else {
526+
ws, err = sdb.newWorkingSet(ctx, 0)
527+
}
465528
if err != nil {
466529
return err
467530
}
@@ -488,6 +551,14 @@ func (sdb *stateDB) getFromWorkingSets(ctx context.Context, key hash.Hash256) (*
488551
sdb.mutex.RLock()
489552
currHeight := sdb.currentChainHeight
490553
sdb.mutex.RUnlock()
491-
tx, err := sdb.newWorkingSet(ctx, currHeight+1)
554+
var (
555+
tx *workingSet
556+
err error
557+
)
558+
if sdb.erigonDB != nil {
559+
tx, err = sdb.newWorkingSetWithErigonOutput(ctx, currHeight+1)
560+
} else {
561+
tx, err = sdb.newWorkingSet(ctx, currHeight+1)
562+
}
492563
return tx, false, err
493564
}

state/factory/workingset.go

+33-7
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"sort"
1212
"time"
1313

14+
erigonstate "github.com/erigontech/erigon/core/state"
1415
"github.com/ethereum/go-ethereum/common"
1516
"github.com/ethereum/go-ethereum/params"
1617
"github.com/iotexproject/go-pkgs/hash"
@@ -176,7 +177,7 @@ func (ws *workingSet) runAction(
176177
if err != nil {
177178
return nil, errors.Wrapf(err, "Failed to get hash")
178179
}
179-
defer ws.ResetSnapshots()
180+
defer ws.finalizeTx(ctx)
180181
if err := ws.freshAccountConversion(ctx, &actCtx); err != nil {
181182
return nil, err
182183
}
@@ -248,18 +249,25 @@ func (ws *workingSet) checkContract(ctx context.Context, to *common.Address) (bo
248249
return sender.IsContract(), false, false, nil
249250
}
250251

251-
func (ws *workingSet) finalize() error {
252+
func (ws *workingSet) finalize(ctx context.Context) error {
252253
if ws.finalized {
253254
return errors.New("Cannot finalize a working set twice")
254255
}
255-
if err := ws.store.Finalize(ws.height); err != nil {
256+
if err := ws.store.Finalize(ctx); err != nil {
256257
return err
257258
}
258259
ws.finalized = true
259260

260261
return nil
261262
}
262263

264+
func (ws *workingSet) finalizeTx(ctx context.Context) {
265+
if err := ws.store.FinalizeTx(ctx); err != nil {
266+
log.L().Panic("failed to finalize tx", zap.Error(err))
267+
}
268+
ws.ResetSnapshots()
269+
}
270+
263271
func (ws *workingSet) Snapshot() int {
264272
return ws.store.Snapshot()
265273
}
@@ -296,7 +304,7 @@ func (ws *workingSet) Commit(ctx context.Context) error {
296304
if err := protocolPreCommit(ctx, ws); err != nil {
297305
return err
298306
}
299-
if err := ws.store.Commit(); err != nil {
307+
if err := ws.store.Commit(ctx); err != nil {
300308
return err
301309
}
302310
if err := protocolCommit(ctx, ws); err != nil {
@@ -389,7 +397,7 @@ func (ws *workingSet) CreateGenesisStates(ctx context.Context) error {
389397
}
390398
}
391399

392-
return ws.finalize()
400+
return ws.finalize(ctx)
393401
}
394402

395403
func (ws *workingSet) validateNonce(ctx context.Context, blk *block.Block) error {
@@ -512,7 +520,7 @@ func (ws *workingSet) processWithCorrectOrder(ctx context.Context, actions []*ac
512520
updateReceiptIndex(receipts)
513521
}
514522
ws.receipts = receipts
515-
return ws.finalize()
523+
return ws.finalize(ctx)
516524
}
517525

518526
func (ws *workingSet) generateSystemActions(ctx context.Context) ([]action.Envelope, error) {
@@ -703,7 +711,7 @@ func (ws *workingSet) pickAndRunActions(
703711
}
704712
ws.receipts = receipts
705713

706-
return executedActions, ws.finalize()
714+
return executedActions, ws.finalize(ctx)
707715
}
708716

709717
func updateReceiptIndex(receipts []*action.Receipt) {
@@ -829,3 +837,21 @@ func (ws *workingSet) NewWorkingSet(ctx context.Context) (*workingSet, error) {
829837
}
830838
return newWorkingSet(ws.height+1, views, store, ws.workingSetStoreFactory), nil
831839
}
840+
841+
func (ws *workingSet) Close() {
842+
ws.store.Close()
843+
}
844+
845+
func (ws *workingSet) Erigon() (*erigonstate.IntraBlockState, bool) {
846+
switch st := ws.store.(type) {
847+
case *workingSetStoreWithSecondary:
848+
if wss, ok := st.writerSecondary.(*erigonWorkingSetStore); ok {
849+
return wss.intraBlockState, true
850+
}
851+
return nil, false
852+
case *erigonWorkingSetStoreForSimulate:
853+
return st.erigonStore.intraBlockState, true
854+
default:
855+
return nil, false
856+
}
857+
}

state/factory/workingsetstore.go

+14-4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/iotexproject/go-pkgs/hash"
1313
"github.com/pkg/errors"
1414

15+
"github.com/iotexproject/iotex-core/v2/action/protocol"
1516
"github.com/iotexproject/iotex-core/v2/db"
1617
"github.com/iotexproject/iotex-core/v2/db/batch"
1718
"github.com/iotexproject/iotex-core/v2/pkg/util/byteutil"
@@ -21,13 +22,15 @@ import (
2122
type (
2223
workingSetStore interface {
2324
db.KVStore
24-
Commit() error
25+
Commit(context.Context) error
2526
States(string, [][]byte) ([][]byte, [][]byte, error)
2627
Digest() hash.Hash256
27-
Finalize(uint64) error
28+
Finalize(context.Context) error
29+
FinalizeTx(context.Context) error
2830
Snapshot() int
2931
RevertSnapshot(int) error
3032
ResetSnapshots()
33+
Close()
3134
}
3235

3336
stateDBWorkingSetStore struct {
@@ -90,7 +93,7 @@ func (store *stateDBWorkingSetStore) Digest() hash.Hash256 {
9093
return hash.Hash256b(store.flusher.SerializeQueue())
9194
}
9295

93-
func (store *stateDBWorkingSetStore) Commit() error {
96+
func (store *stateDBWorkingSetStore) Commit(_ context.Context) error {
9497
store.lock.Lock()
9598
defer store.lock.Unlock()
9699
if store.committed {
@@ -143,7 +146,8 @@ func (store *stateDBWorkingSetStore) States(ns string, keys [][]byte) ([][]byte,
143146
return readStates(store.flusher.BaseKVStore(), ns, keys)
144147
}
145148

146-
func (store *stateDBWorkingSetStore) Finalize(height uint64) error {
149+
func (store *stateDBWorkingSetStore) Finalize(ctx context.Context) error {
150+
height := protocol.MustGetBlockCtx(ctx).BlockHeight
147151
// Persist current chain Height
148152
store.flusher.KVStoreWithBuffer().MustPut(
149153
AccountKVNamespace,
@@ -152,3 +156,9 @@ func (store *stateDBWorkingSetStore) Finalize(height uint64) error {
152156
)
153157
return nil
154158
}
159+
160+
func (store *stateDBWorkingSetStore) FinalizeTx(_ context.Context) error {
161+
return nil
162+
}
163+
164+
func (store *stateDBWorkingSetStore) Close() {}

0 commit comments

Comments
 (0)