github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/cmd/fbchaind/mpt/common.go (about) 1 package mpt 2 3 import ( 4 "fmt" 5 "path/filepath" 6 7 iavlstore "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/store/iavl" 8 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/store/mpt" 9 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/store/rootmulti" 10 "github.com/fibonacci-chain/fbc/libs/iavl" 11 dbm "github.com/fibonacci-chain/fbc/libs/tm-db" 12 13 ethcmn "github.com/ethereum/go-ethereum/common" 14 ethstate "github.com/ethereum/go-ethereum/core/state" 15 "github.com/ethereum/go-ethereum/ethdb" 16 "github.com/fibonacci-chain/fbc/app" 17 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/server" 18 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 19 authtypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/types" 20 tmdb "github.com/fibonacci-chain/fbc/libs/tm-db" 21 evmtypes "github.com/fibonacci-chain/fbc/x/evm/types" 22 ) 23 24 const ( 25 applicationDB = "application" 26 27 accStoreKey = authtypes.StoreKey 28 evmStoreKey = evmtypes.StoreKey 29 legacyStoreKey = "evmlegacy" 30 31 iavlAccKey = "s/k:acc/" 32 iavlEvmKey = "s/k:evm/" 33 iavlEvmLegacyKey = "s/k:evmlegacy/" 34 KeyParams = "s/k:params/" 35 ) 36 37 func panicError(err error) { 38 if err != nil { 39 panic(err) 40 } 41 } 42 43 // checkValidKey checks if the key is equal to authtypes.StoreKey or evmtypes.StoreKey 44 func checkValidKey(key string) error { 45 if key != accStoreKey && key != evmStoreKey && key != legacyStoreKey { 46 return fmt.Errorf("invalid key %s", key) 47 } 48 return nil 49 } 50 51 /* 52 * Common functions about cosmos-sdk 53 */ 54 // newMigrationApp generates a new app with the given key and application.db 55 func newMigrationApp(ctx *server.Context) *app.FBChainApp { 56 appDb := openApplicationDb(ctx.Config.RootDir) 57 return app.NewFBChainApp( 58 ctx.Logger, 59 appDb, 60 nil, 61 true, 62 map[int64]bool{}, 63 0, 64 ) 65 } 66 67 func openApplicationDb(rootdir string) tmdb.DB { 68 dataDir := filepath.Join(rootdir, "data") 69 appDb, err := sdk.NewDB(applicationDB, dataDir) 70 if err != nil { 71 panic("fail to open application db: " + err.Error()) 72 } 73 return appDb 74 } 75 76 /* 77 * Common functions about mpt 78 */ 79 // getStorageTrie returns the trie of the given address and stateRoot 80 func getStorageTrie(db ethstate.Database, addrHash, stateRoot ethcmn.Hash) ethstate.Trie { 81 tr, err := db.OpenStorageTrie(addrHash, stateRoot) 82 panicError(err) 83 return tr 84 } 85 86 // pushData2Database commit the data to the database 87 func pushData2Database(db ethstate.Database, trie ethstate.Trie, height int64, isEvm bool) { 88 var storageRoot ethcmn.Hash 89 root, err := trie.Commit(func(_ [][]byte, _ []byte, leaf []byte, parent ethcmn.Hash) error { 90 storageRoot.SetBytes(leaf) 91 if storageRoot != mpt.EmptyRootHash { 92 db.TrieDB().Reference(storageRoot, parent) 93 } 94 return nil 95 }) 96 panicError(err) 97 98 err = db.TrieDB().Commit(root, false, nil) 99 panicError(err) 100 101 setMptRootHash(db, uint64(height), root, isEvm) 102 } 103 104 // setMptRootHash sets the mapping from block height to root mpt hash 105 func setMptRootHash(db ethstate.Database, height uint64, hash ethcmn.Hash, isEvm bool) { 106 heightBytes := sdk.Uint64ToBigEndian(height) 107 if isEvm { 108 db.TrieDB().DiskDB().Put(mpt.KeyPrefixEvmLatestStoredHeight, heightBytes) 109 db.TrieDB().DiskDB().Put(append(mpt.KeyPrefixEvmRootMptHash, heightBytes...), hash.Bytes()) 110 } else { 111 db.TrieDB().DiskDB().Put(mpt.KeyPrefixAccLatestStoredHeight, heightBytes) 112 db.TrieDB().DiskDB().Put(append(mpt.KeyPrefixAccRootMptHash, heightBytes...), hash.Bytes()) 113 } 114 } 115 116 func writeDataToRawdb(batch ethdb.Batch) { 117 if err := batch.Write(); err != nil { 118 panic(err) 119 } 120 batch.Reset() 121 } 122 123 func getUpgradedTree(db dbm.DB, prefix []byte, usePreLatest bool) *iavl.MutableTree { 124 rs := rootmulti.NewStore(db) 125 latestVersion := rs.GetLatestVersion() 126 if latestVersion == 0 { 127 return nil 128 } 129 130 db = dbm.NewPrefixDB(db, prefix) 131 132 tree, err := iavl.NewMutableTree(db, iavlstore.IavlCacheSize) 133 if err != nil { 134 panic("Fail to get tree: " + err.Error()) 135 } 136 137 if usePreLatest { 138 latestVersion -= 1 139 } 140 141 if latestVersion <= 0 { 142 panic(fmt.Sprintf("invalid version to load: %d", latestVersion)) 143 } 144 145 _, err = tree.LoadVersion(latestVersion) 146 if err != nil { 147 panic("fail to load target version tree: " + err.Error()) 148 } 149 150 return tree 151 }