From f8668da9052f5ab5773bb7176e26c04df9130415 Mon Sep 17 00:00:00 2001 From: ledgerwatch <akhounov@gmail.com> Date: Wed, 23 Mar 2022 16:00:06 +0000 Subject: [PATCH] [erigon2] Bring back MDBX as storage for recent data (#3756) * fixes * Update * Update to erigon-lib main Co-authored-by: Alex Sharp <alexsharp@Alexs-MacBook-Pro.local> Co-authored-by: Alexey Sharp <alexeysharp@Alexeys-iMac.local> --- cmd/state/commands/erigon2.go | 97 +++++++++++++++++++++++++++++------ go.mod | 2 +- go.sum | 17 +++--- 3 files changed, 92 insertions(+), 24 deletions(-) diff --git a/cmd/state/commands/erigon2.go b/cmd/state/commands/erigon2.go index 81145d8a45..afd9fd9cb4 100644 --- a/cmd/state/commands/erigon2.go +++ b/cmd/state/commands/erigon2.go @@ -18,6 +18,8 @@ import ( "github.com/holiman/uint256" "github.com/ledgerwatch/erigon-lib/aggregator" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/kv" + "github.com/ledgerwatch/erigon-lib/kv/mdbx" kv2 "github.com/ledgerwatch/erigon-lib/kv/mdbx" "github.com/ledgerwatch/log/v3" "github.com/spf13/cobra" @@ -39,9 +41,10 @@ import ( ) const ( - aggregationStep = 15625 /* this is 500'000 / 32 */ - unwindLimit = 90000 /* how it is in geth */ - logInterval = 30 * time.Second // time period to print aggregation stat to log + aggregationStep = 15625 /* this is 500'000 / 32 */ + unwindLimit = 90000 /* how it is in geth */ + logInterval = 30 * time.Second // time period to print aggregation stat to log + dirtySpaceThreshold = 2 * 1024 * 1024 * 1024 /* threshold of dirty space in MDBX transaction that triggers a commit */ ) var ( @@ -99,6 +102,21 @@ func Erigon2(genesis *core.Genesis, chainConfig *params.ChainConfig, logger log. return err1 } defer historyTx.Rollback() + stateDbPath := path.Join(datadir, "statedb") + if block == 0 { + if _, err = os.Stat(stateDbPath); err != nil { + if !errors.Is(err, os.ErrNotExist) { + return err + } + } else if err = os.RemoveAll(stateDbPath); err != nil { + return err + } + } + db, err2 := kv2.NewMDBX(logger).Path(stateDbPath).WriteMap().Open() + if err2 != nil { + return err2 + } + defer db.Close() aggPath := filepath.Join(datadir, "aggregator") if block == 0 { @@ -114,21 +132,30 @@ func Erigon2(genesis *core.Genesis, chainConfig *params.ChainConfig, logger log. } } - agg, err3 := aggregator.NewAggregator(aggPath, unwindLimit, aggregationStep, changesets, commitments, 100_000_000) + var rwTx kv.RwTx + defer func() { + if rwTx != nil { + rwTx.Rollback() + } + }() + if rwTx, err = db.BeginRw(ctx); err != nil { + return err + } + agg, err3 := aggregator.NewAggregator(aggPath, unwindLimit, aggregationStep, changesets, commitments, 100_000_000, rwTx) if err3 != nil { return fmt.Errorf("create aggregator: %w", err3) } defer agg.Close() interrupt := false - w := agg.MakeStateWriter(false /* beforeOn */) + w := agg.MakeStateWriter(changesets /* beforeOn */) var rootHash []byte if block == 0 { genBlock, genesisIbs, err4 := genesis.ToBlock() if err4 != nil { return err4 } - if err = w.Reset(0); err != nil { + if err = w.Reset(0, rwTx); err != nil { return err } if err = genesisIbs.CommitBlock(params.Rules{}, &WriterWrapper{w: w}); err != nil { @@ -211,11 +238,11 @@ func Erigon2(genesis *core.Genesis, chainConfig *params.ChainConfig, logger log. log.Info("history: block is nil", "block", blockNum) break } - if err = w.Reset(blockNum); err != nil { + if err = w.Reset(blockNum, rwTx); err != nil { return err } - r := agg.MakeStateReader(blockNum) + r := agg.MakeStateReader(blockNum, rwTx) readWrapper := &ReaderWrapper{r: r, blockNum: blockNum} writeWrapper := &WriterWrapper{w: w, blockNum: blockNum} getHeader := func(hash common.Hash, number uint64) *types.Header { @@ -258,6 +285,28 @@ func Erigon2(genesis *core.Genesis, chainConfig *params.ChainConfig, logger log. if err = w.Aggregate(trace); err != nil { return err } + // Commit transaction only when interrupted or just before computing commitment (so it can be re-done) + commit := interrupt + if !commit && (blockNum+1)%uint64(commitmentFrequency) == 0 { + var spaceDirty uint64 + if spaceDirty, _, err = rwTx.(*mdbx.MdbxTx).SpaceDirty(); err != nil { + return fmt.Errorf("retrieving spaceDirty: %w", err) + } + if spaceDirty >= dirtySpaceThreshold { + log.Info("Initiated tx commit", "block", blockNum, "space dirty", libcommon.ByteCount(spaceDirty)) + commit = true + } + } + if commit { + if err = rwTx.Commit(); err != nil { + return err + } + if !interrupt { + if rwTx, err = db.BeginRw(ctx); err != nil { + return err + } + } + } } aStats := agg.Stats() @@ -388,7 +437,10 @@ func bytesToUint64(buf []byte) (x uint64) { } func (rw *ReaderWrapper) ReadAccountData(address common.Address) (*accounts.Account, error) { - enc := rw.r.ReadAccountData(address.Bytes(), false /* trace */) + enc, err := rw.r.ReadAccountData(address.Bytes(), false /* trace */) + if err != nil { + return nil, err + } if len(enc) == 0 { return nil, nil } @@ -424,19 +476,22 @@ func (rw *ReaderWrapper) ReadAccountData(address common.Address) (*accounts.Acco func (rw *ReaderWrapper) ReadAccountStorage(address common.Address, incarnation uint64, key *common.Hash) ([]byte, error) { trace := false - enc := rw.r.ReadAccountStorage(address.Bytes(), key.Bytes(), trace) + enc, err := rw.r.ReadAccountStorage(address.Bytes(), key.Bytes(), trace) + if err != nil { + return nil, err + } if enc == nil { return nil, nil } - return enc.Bytes(), nil + return enc, nil } func (rw *ReaderWrapper) ReadAccountCode(address common.Address, incarnation uint64, codeHash common.Hash) ([]byte, error) { - return rw.r.ReadAccountCode(address.Bytes(), false /* trace */), nil + return rw.r.ReadAccountCode(address.Bytes(), false /* trace */) } func (rw *ReaderWrapper) ReadAccountCodeSize(address common.Address, incarnation uint64, codeHash common.Hash) (int, error) { - return rw.r.ReadAccountCodeSize(address.Bytes(), false /* trace */), nil + return rw.r.ReadAccountCodeSize(address.Bytes(), false /* trace */) } func (rw *ReaderWrapper) ReadAccountIncarnation(address common.Address) (uint64, error) { @@ -506,17 +561,23 @@ func (ww *WriterWrapper) UpdateAccountData(address common.Address, original, acc inc >>= 8 } } - ww.w.UpdateAccountData(address.Bytes(), value, false /* trace */) + if err := ww.w.UpdateAccountData(address.Bytes(), value, false /* trace */); err != nil { + return err + } return nil } func (ww *WriterWrapper) UpdateAccountCode(address common.Address, incarnation uint64, codeHash common.Hash, code []byte) error { - ww.w.UpdateAccountCode(address.Bytes(), code, false /* trace */) + if err := ww.w.UpdateAccountCode(address.Bytes(), code, false /* trace */); err != nil { + return err + } return nil } func (ww *WriterWrapper) DeleteAccount(address common.Address, original *accounts.Account) error { - ww.w.DeleteAccount(address.Bytes(), false /* trace */) + if err := ww.w.DeleteAccount(address.Bytes(), false /* trace */); err != nil { + return err + } return nil } @@ -525,7 +586,9 @@ func (ww *WriterWrapper) WriteAccountStorage(address common.Address, incarnation if trace { fmt.Printf("block %d, WriteAccountStorage %x %x, original %s, value %s\n", ww.blockNum, address, *key, original, value) } - ww.w.WriteAccountStorage(address.Bytes(), key.Bytes(), value, trace) + if err := ww.w.WriteAccountStorage(address.Bytes(), key.Bytes(), value.Bytes(), trace); err != nil { + return err + } return nil } diff --git a/go.mod b/go.mod index a7f1a63055..4c35f2e14b 100644 --- a/go.mod +++ b/go.mod @@ -41,7 +41,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20220321064242-9e5a50069c63 + github.com/ledgerwatch/erigon-lib v0.0.0-20220323143513-4e8d577d1d00 github.com/ledgerwatch/log/v3 v3.4.1 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/magiconair/properties v1.8.6 // indirect diff --git a/go.sum b/go.sum index 9ec9c4468e..2a7eb0970e 100644 --- a/go.sum +++ b/go.sum @@ -617,8 +617,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20220321064242-9e5a50069c63 h1:Zhcn8xjLXQiU0IjVKVa0ntek1mqNau+bD7Mi07qPf8g= -github.com/ledgerwatch/erigon-lib v0.0.0-20220321064242-9e5a50069c63/go.mod h1:1Ao0yXNx7956h1fm/3A8AOB2pzckvlpBvxdYvJNfgl8= +github.com/ledgerwatch/erigon-lib v0.0.0-20220323143513-4e8d577d1d00 h1:tx7hpQKZPILnt53FsZKmufNuhQqXgewYtV4czm88dvM= +github.com/ledgerwatch/erigon-lib v0.0.0-20220323143513-4e8d577d1d00/go.mod h1:OYy+SkAvkK1L0pZ9Jrt23mRya/C/jax2aGOktxj9pig= github.com/ledgerwatch/log/v3 v3.4.1 h1:/xGwlVulXnsO9Uq+tzaExc8OWmXXHU0dnLalpbnY5Bc= github.com/ledgerwatch/log/v3 v3.4.1/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= @@ -642,7 +642,7 @@ github.com/marten-seemann/qtls v0.2.3/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwm github.com/marten-seemann/qtls v0.10.0/go.mod h1:UvMd1oaYDACI99/oZUYLzMCkBXQVT0aGm99sJhbT8hs= github.com/marten-seemann/qtls-go1-15 v0.1.0/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= github.com/marten-seemann/qtls-go1-15 v0.1.1/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= -github.com/matryer/moq v0.2.5/go.mod h1:9RtPYjTnH1bSBIkpvtHkFN7nbWAnO7oRpdJkEIn6UtE= +github.com/matryer/moq v0.2.6/go.mod h1:kITsx543GOENm48TUAQyJ9+SAvFSr7iGQXPoth/VUBk= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs= @@ -1031,6 +1031,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= @@ -1083,6 +1084,7 @@ golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210813211128-0a44fdfbc16e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838 h1:71vQrMauZZhcTVK6KdYM+rklehEEwb3E+ZhaE5jrPrE= golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= @@ -1120,8 +1122,9 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/net v0.0.0-20180524181706-dfa909b99c79/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1182,6 +1185,7 @@ golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211201190559-0a0e4e1bb54c/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -1289,6 +1293,7 @@ golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211023085530-d6a326fbbf70/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211030160813-b3129d9d1021/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1365,15 +1370,15 @@ golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200815165600-90abf76919f3/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200928182047-19e03678916f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201022035929-9cf592e881e9/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -- GitLab