Skip to content

Commit

Permalink
Merge pull request #1089 from Concordium/fix-accountmap-init
Browse files Browse the repository at this point in the history
Share Account Map Database
  • Loading branch information
td202 authored Nov 23, 2023
2 parents 21a06cb + 222c1a2 commit 24cebc6
Show file tree
Hide file tree
Showing 16 changed files with 67 additions and 48 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Unreleased changes

- Fix an bug that caused the node to crash on Windows when processing a protocol update.

## 6.2.2

- The transaction table is only used for tracking next available account nonce
Expand Down
5 changes: 2 additions & 3 deletions concordium-consensus/src/Concordium/External.hs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ import Concordium.GlobalState.Persistent.TreeState (InitException (..))
import Concordium.MultiVersion (
Callbacks (..),
CatchUpConfiguration (..),
DiskStateConfig (..),
MVR (..),
MultiVersionConfiguration (..),
MultiVersionRunner (..),
Expand Down Expand Up @@ -459,7 +458,7 @@ startConsensus
appDataPath <- peekCStringLen (appDataC, fromIntegral appDataLenC)
-- Do globalstate migration if necessary
migrateGlobalState appDataPath logM
let mvcStateConfig = DiskStateConfig appDataPath
mvcStateConfig <- MV.makeDiskStateConfig appDataPath
let mvcFinalizationConfig =
BufferedFinalization
( FinalizationInstance
Expand Down Expand Up @@ -607,7 +606,7 @@ startConsensusPassive
appDataPath <- peekCStringLen (appDataC, fromIntegral appDataLenC)
-- Do globalstate migration if necessary
migrateGlobalState appDataPath logM
let mvcStateConfig = DiskStateConfig appDataPath
mvcStateConfig <- MV.makeDiskStateConfig appDataPath
let mvcFinalizationConfig = NoFinalization
-- Callbacks
regenesisRef <- makeRegenesisRef regenesisFree regenesisPtr
Expand Down
10 changes: 5 additions & 5 deletions concordium-consensus/src/Concordium/GlobalState.hs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ data GlobalStateConfig = GlobalStateConfig
dtdbTreeStateDirectory :: !FilePath,
-- | Path to the block state database.
dtdbBlockStateFile :: !FilePath,
-- | Path to the account map database.
dtdAccountMapDirectory :: !FilePath
-- | Account map.
gscAccountMap :: !LMDBAccountMap.DatabaseHandlers
}

-- | Exceptions that can occur when initialising the global state.
Expand Down Expand Up @@ -71,15 +71,15 @@ type GSState pv = SkovPersistentData pv
initialiseExistingGlobalState :: forall pv. (IsProtocolVersion pv) => SProtocolVersion pv -> GlobalStateConfig -> LogIO (Maybe (GSContext pv, GSState pv))
initialiseExistingGlobalState _ GlobalStateConfig{..} = do
-- check if all the necessary database files exist
existingDB <- checkExistingDatabase dtdbTreeStateDirectory dtdbBlockStateFile dtdAccountMapDirectory
existingDB <- checkExistingDatabase dtdbTreeStateDirectory dtdbBlockStateFile
if existingDB
then do
logm <- ask
liftIO $ do
pbscAccountCache <- newAccountCache (rpAccountsCacheSize dtdbRuntimeParameters)
pbscModuleCache <- Modules.newModuleCache (rpModulesCacheSize dtdbRuntimeParameters)
pbscBlobStore <- loadBlobStore dtdbBlockStateFile
pbscAccountMap <- liftIO $ LMDBAccountMap.openDatabase dtdAccountMapDirectory
let pbscAccountMap = gscAccountMap
let pbsc = PersistentBlockStateContext{..}
skovData <-
runLoggerT (loadSkovPersistentData dtdbRuntimeParameters dtdbTreeStateDirectory pbsc) logm
Expand All @@ -95,7 +95,7 @@ initializePersistentBlockStateContext GlobalStateConfig{..} = do
pbscBlobStore <- createBlobStore dtdbBlockStateFile
pbscAccountCache <- newAccountCache (rpAccountsCacheSize dtdbRuntimeParameters)
pbscModuleCache <- Modules.newModuleCache (rpModulesCacheSize dtdbRuntimeParameters)
pbscAccountMap <- LMDBAccountMap.openDatabase dtdAccountMapDirectory
let pbscAccountMap = gscAccountMap
return PersistentBlockStateContext{..}

-- | Migrate an existing global state. This is only intended to be used on a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3775,8 +3775,7 @@ cacheState hpbs = do
rels <- cache bspReleaseSchedule
red <- cache bspRewardDetails
_ <-
storePBS
(hpbsPointers hpbs)
storePBS (hpbsPointers hpbs) $!
BlockStatePointers
{ bspAccounts = accts,
bspInstances = insts,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -328,15 +328,11 @@ checkExistingDatabase ::
FilePath ->
-- | Block state file
FilePath ->
-- | Account map path
FilePath ->
m Bool
checkExistingDatabase treeStateDir blockStateFile accountMapDir = do
checkExistingDatabase treeStateDir blockStateFile = do
let treeStateFile = treeStateDir </> "data.mdb"
let accountMapFile = accountMapDir </> "data.mdb"
bsPathEx <- liftIO $ doesPathExist blockStateFile
tsPathEx <- liftIO $ doesPathExist treeStateFile
amPathEx <- liftIO $ doesPathExist accountMapFile

-- Check whether a path is a normal file that is readable and writable
let checkRWFile :: FilePath -> InitException -> m ()
Expand All @@ -362,11 +358,9 @@ checkExistingDatabase treeStateDir blockStateFile accountMapDir = do
-- check whether it is a normal file and whether we have the right permissions
checkRWFile blockStateFile BlockStatePermissionError
checkRWFile treeStateFile TreeStatePermissionError
when amPathEx $ checkRWFile accountMapFile AccountMapPermissionError
logEvent TreeState LLTrace "Existing database found."
logEvent TreeState LLTrace $ "TreeState filepath: " ++ show treeStateFile
logEvent TreeState LLTrace $ "BlockState filepath: " ++ show blockStateFile
logEvent TreeState LLTrace $ if amPathEx then "AccountMap filepath: " ++ show accountMapFile else "AccountMap not found"
return True
| bsPathEx -> do
logEvent GlobalState LLWarning "Block state file exists, but tree state database does not. Deleting the block state file."
Expand Down
8 changes: 4 additions & 4 deletions concordium-consensus/src/Concordium/KonsensusV1/SkovMonad.hs
Original file line number Diff line number Diff line change
Expand Up @@ -344,8 +344,8 @@ data GlobalStateConfig = GlobalStateConfig
gscTreeStateDirectory :: !FilePath,
-- | Path to the block state file.
gscBlockStateFile :: !FilePath,
-- | Path to the account map directory
gscAccountMapDirectory :: !FilePath
-- | Account map.
gscAccountMap :: !LMDBAccountMap.DatabaseHandlers
}

-- | Context used by the 'InitMonad'.
Expand Down Expand Up @@ -498,7 +498,7 @@ initialiseExistingSkovV1 ::
LogIO (Maybe (ExistingSkov pv m))
initialiseExistingSkovV1 bakerCtx handlerCtx unliftSkov gsc@GlobalStateConfig{..} = do
logEvent Skov LLDebug "Attempting to use existing global state."
existingDB <- checkExistingDatabase gscTreeStateDirectory gscBlockStateFile gscAccountMapDirectory
existingDB <- checkExistingDatabase gscTreeStateDirectory gscBlockStateFile
if existingDB
then do
pbsc <- newPersistentBlockStateContext False gsc
Expand Down Expand Up @@ -762,5 +762,5 @@ newPersistentBlockStateContext initialize GlobalStateConfig{..} = liftIO $ do
pbscBlobStore <- if initialize then createBlobStore gscBlockStateFile else loadBlobStore gscBlockStateFile
pbscAccountCache <- newAccountCache $ rpAccountsCacheSize gscRuntimeParameters
pbscModuleCache <- Modules.newModuleCache $ rpModulesCacheSize gscRuntimeParameters
pbscAccountMap <- LMDBAccountMap.openDatabase gscAccountMapDirectory
let pbscAccountMap = gscAccountMap
return PersistentBlockStateContext{..}
27 changes: 17 additions & 10 deletions concordium-consensus/src/Concordium/MultiVersion.hs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import Concordium.Afgjort.Finalize
import Concordium.Afgjort.Finalize.Types
import Concordium.Birk.Bake
import Concordium.GlobalState
import qualified Concordium.GlobalState.AccountMap.LMDB as LMDBAccountMap
import Concordium.GlobalState.Block
import Concordium.GlobalState.BlockPointer (BlockPointer (..), BlockPointerData (..))
import Concordium.GlobalState.Finalization
Expand Down Expand Up @@ -166,11 +167,19 @@ instance

-- | Configuration for the global state that uses disk storage
-- for both tree state and block state.
newtype DiskStateConfig = DiskStateConfig
data DiskStateConfig = DiskStateConfig
{ -- | Root directory for the global state.
stateBasePath :: FilePath
stateBasePath :: !FilePath,
-- | Account map.
globalAccountMap :: !LMDBAccountMap.DatabaseHandlers
}

-- | Create a 'DiskStateConfig', opening the shared account map database in the process.
makeDiskStateConfig :: FilePath -> IO DiskStateConfig
makeDiskStateConfig stateBasePath = do
globalAccountMap <- LMDBAccountMap.openDatabase (stateBasePath </> "accountmap")
return DiskStateConfig{..}

-- | Configuration information for a multi-version runner.
-- The type parameter defines the finalization configuration, and should be an instance of
-- 'FinalizationConfig'.
Expand All @@ -188,15 +197,13 @@ globalStateConfig ::
DiskStateConfig ->
RuntimeParameters ->
GenesisIndex ->
-- | Absolute height of the genesis block.
AbsoluteBlockHeight ->
GlobalStateConfig
globalStateConfig DiskStateConfig{..} rtp gi _ =
globalStateConfig DiskStateConfig{..} rtp gi =
( GlobalStateConfig
{ dtdbRuntimeParameters = rtp,
dtdbTreeStateDirectory = stateBasePath </> ("treestate-" ++ show gi),
dtdbBlockStateFile = stateBasePath </> ("blockstate-" ++ show gi) <.> "dat",
dtdAccountMapDirectory = stateBasePath </> "accountmap"
gscAccountMap = globalAccountMap
}
)

Expand All @@ -211,7 +218,7 @@ globalStateConfigV1 DiskStateConfig{..} rtp gi =
{ gscRuntimeParameters = rtp,
gscTreeStateDirectory = stateBasePath </> ("treestate-" ++ show gi),
gscBlockStateFile = stateBasePath </> ("blockstate-" ++ show gi) <.> "dat",
gscAccountMapDirectory = stateBasePath </> "accountmap"
gscAccountMap = globalAccountMap
}
)

Expand Down Expand Up @@ -639,7 +646,6 @@ newGenesis (PVGenesisData (gd :: GenesisData pv)) genesisHeight = case consensus
mvcStateConfig
mvcRuntimeParameters
vc0Index
genesisHeight
)
mvcFinalizationConfig
UpdateHandler
Expand Down Expand Up @@ -741,7 +747,6 @@ checkForProtocolUpdateV0 = liftSkov body
(mvcStateConfig mvConfiguration)
(mvcRuntimeParameters mvConfiguration)
vc0Index
vc0GenesisHeight
)
(mvcFinalizationConfig mvConfiguration)
UpdateHandler
Expand Down Expand Up @@ -1173,7 +1178,6 @@ startupSkov genesis = do
mvcStateConfig
mvcRuntimeParameters
genIndex
genHeight
)
mvcFinalizationConfig
UpdateHandler
Expand Down Expand Up @@ -1431,7 +1435,10 @@ shutdownMultiVersionRunner MultiVersionRunner{..} = mask_ $ do
-- Acquire the write lock. This prevents further updates, as they will block.
takeMVar mvWriteLock
versions <- readIORef mvVersions
-- Shut down the consensus databases.
runLoggerT (forM_ versions evcShutdown) mvLog
-- Shut down the global account map.
LMDBAccountMap.closeDatabase (globalAccountMap (mvcStateConfig mvConfiguration))

-- | Lift a version-0 consensus skov action to the 'MVR' monad, running it on a
-- particular 'VersionedConfigurationV0'. Note that this does not
Expand Down
9 changes: 5 additions & 4 deletions concordium-consensus/test-runners/app/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -297,10 +297,11 @@ callbacks myPeerId peersRef monitorChan = Callbacks{..}
notifyUnsupportedProtocolUpdate = Nothing

-- | Construct a 'MultiVersionConfiguration' to use for each baker node.
config :: FilePath -> BakerIdentity -> MultiVersionConfiguration (BufferedFinalization ThreadTimer)
config dataPath bid = MultiVersionConfiguration{..}
config :: FilePath -> BakerIdentity -> IO (MultiVersionConfiguration (BufferedFinalization ThreadTimer))
config dataPath bid = do
mvcStateConfig <- makeDiskStateConfig dataPath
return MultiVersionConfiguration{..}
where
mvcStateConfig = DiskStateConfig dataPath
mvcFinalizationConfig =
BufferedFinalization
( FinalizationInstance
Expand Down Expand Up @@ -369,7 +370,7 @@ main = do
let s = show now ++ "-" ++ show (bakerId bid)
d = "data" </> ("db" ++ s)
createDirectoryIfMissing True d
let bconfig = config d bid
bconfig <- config d bid
logFile <- openFile ("consensus-" ++ s ++ ".log") WriteMode
let blogger src lvl msg = {- when (lvl == LLInfo) $ -} do
timestamp <- getCurrentTime
Expand Down
9 changes: 5 additions & 4 deletions concordium-consensus/test-runners/catchup/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -313,10 +313,11 @@ callbacks myPeerId peersRef monitorChan = Callbacks{..}
notifyUnsupportedProtocolUpdate = Nothing

-- | Construct a 'MultiVersionConfiguration' to use for each baker node.
config :: FilePath -> BakerIdentity -> MultiVersionConfiguration (BufferedFinalization ThreadTimer)
config dataPath bid = MultiVersionConfiguration{..}
config :: FilePath -> BakerIdentity -> IO (MultiVersionConfiguration (BufferedFinalization ThreadTimer))
config dataPath bid = do
mvcStateConfig <- makeDiskStateConfig dataPath
return MultiVersionConfiguration{..}
where
mvcStateConfig = DiskStateConfig dataPath
mvcFinalizationConfig =
BufferedFinalization
( FinalizationInstance
Expand Down Expand Up @@ -395,7 +396,7 @@ main = do
let s = show now ++ "-" ++ show (bakerId bid)
d = "data" </> ("db" ++ s)
createDirectoryIfMissing True d
let bconfig = config d bid
bconfig <- config d bid
logFile <- openFile ("consensus-" ++ s ++ ".log") WriteMode
let blogger src lvl msg = {- when (lvl == LLInfo) $ -} do
timestamp <- getCurrentTime
Expand Down
5 changes: 4 additions & 1 deletion concordium-consensus/test-runners/deterministic/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import System.Random

import Concordium.Afgjort.Finalize.Types
import Concordium.GlobalState
import qualified Concordium.GlobalState.AccountMap.LMDB as LMDBAccountMap
import Concordium.GlobalState.BakerInfo
import Concordium.GlobalState.Block
import qualified Concordium.GlobalState.BlockPointer as BS
Expand Down Expand Up @@ -69,7 +70,9 @@ type PV = 'P5
-- | Construct the global state configuration.
-- Can be customised if changing the configuration.
makeGlobalStateConfig :: RuntimeParameters -> FilePath -> FilePath -> FilePath -> IO GlobalStateConfig
makeGlobalStateConfig rt treeStateDir blockStateFile accMapDirectory = return $ GlobalStateConfig rt treeStateDir blockStateFile accMapDirectory
makeGlobalStateConfig rt treeStateDir blockStateFile accMapDirectory = do
accMap <- LMDBAccountMap.openDatabase accMapDirectory
return $ GlobalStateConfig rt treeStateDir blockStateFile accMap

{-
type TreeConfig = PairGSConfig MemoryTreeMemoryBlockConfig DiskTreeDiskBlockConfig
Expand Down
3 changes: 2 additions & 1 deletion concordium-consensus/test-runners/execute-chain/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@ main = do
hFlush logFile
let dataDir = "data" </> ("db" ++ show now)
createDirectoryIfMissing True dataDir
diskStateConfig <- makeDiskStateConfig dataDir
let config ::
MultiVersionConfiguration
(NoFinalization ThreadTimer)
config =
MultiVersionConfiguration
{ mvcStateConfig = DiskStateConfig dataDir,
{ mvcStateConfig = diskStateConfig,
mvcFinalizationConfig = NoFinalization,
mvcRuntimeParameters = defaultRuntimeParameters{rpTransactionsPurgingDelay = 0, rpAccountsCacheSize = 10000}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import Concordium.Startup
import Concordium.Types.ProtocolVersion

import Concordium.GlobalState
import qualified Concordium.GlobalState.AccountMap.LMDB as LMDBAccountMap
import Concordium.GlobalState.BakerInfo
import Concordium.GlobalState.Block
import qualified Concordium.GlobalState.DummyData as Dummy
Expand All @@ -36,8 +37,10 @@ type PV = 'P1
dummyArs :: AnonymityRevokers
dummyArs = emptyAnonymityRevokers

makeGlobalStateConfig :: FilePath -> RuntimeParameters -> GlobalStateConfig
makeGlobalStateConfig tempDir rt = GlobalStateConfig rt tempDir (tempDir </> "data" <.> "blob") (tempDir </> "accountmap")
makeGlobalStateConfig :: FilePath -> RuntimeParameters -> IO GlobalStateConfig
makeGlobalStateConfig tempDir rt = do
accountMap <- LMDBAccountMap.openDatabase (tempDir </> "accountmap")
return $ GlobalStateConfig rt tempDir (tempDir </> "data" <.> "blob") accountMap

genesis :: Word -> (GenesisData PV, [(BakerIdentity, FullBakerInfo)], Amount)
genesis nBakers =
Expand Down Expand Up @@ -80,7 +83,8 @@ setup nBakers = withTempDirectory "." "tmp-consensus-data" $ \tempDir -> do
fullBakers
genTotal
let finInstances = map (makeFinalizationInstance . fst) bakers
(gsc, gss) <- runSilentLogger (initialiseGlobalState genData $ makeGlobalStateConfig tempDir defaultRuntimeParameters)
gsConfig <- makeGlobalStateConfig tempDir defaultRuntimeParameters
(gsc, gss) <- runSilentLogger (initialiseGlobalState genData gsConfig)
active <- forM finInstances (\inst -> (initialState inst,) <$> runSilentLogger (getFinalizationState (Just inst) gsc gss))
passive <- (initialPassiveState,) <$> runSilentLogger (getFinalizationState Nothing gsc gss)
return $ passive : active
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import Concordium.Crypto.SHA256

import Concordium.Genesis.Data.P1
import Concordium.GlobalState
import qualified Concordium.GlobalState.AccountMap.LMDB as LMDBAccountMap
import Concordium.GlobalState.BakerInfo
import Concordium.GlobalState.Block
import qualified Concordium.GlobalState.BlockPointer as BS
Expand Down Expand Up @@ -367,10 +368,11 @@ createInitStates additionalFinMembers = do
}
}
createState (bid, _, _, _) = liftIO $ withTempDirectory "." "tmp-consensus-data" $ \tempDir -> do
accountMap <- LMDBAccountMap.openDatabase (tempDir </> "accountmap")
let fininst = FinalizationInstance (bakerSignKey bid) (bakerElectionKey bid) (bakerAggregationKey bid)
config =
SkovConfig
(GlobalStateConfig defaultRuntimeParameters tempDir (tempDir </> "data" <.> "blob") (tempDir </> "accountmap"))
(GlobalStateConfig defaultRuntimeParameters tempDir (tempDir </> "data" <.> "blob") accountMap)
(ActiveFinalization fininst)
NoHandler
(initCtx, initState) <- runSilentLogger (initialiseSkov gen config)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import Concordium.Types.Accounts
import Concordium.Crypto.SHA256 as Hash
import Data.FixedByteString as FBS

import qualified Concordium.GlobalState.AccountMap.LMDB as LMDBAccountMap
import qualified Concordium.GlobalState.DummyData as Dummy

-- | Protocol version
Expand Down Expand Up @@ -132,10 +133,11 @@ createInitStates dir = do
createState uni =
liftIO
. ( \(bid, _, _, _) -> do
accountMap <- LMDBAccountMap.openDatabase (dir </> uni <.> "accountmap")
let fininst = FinalizationInstance (bakerSignKey bid) (bakerElectionKey bid) (bakerAggregationKey bid)
config =
SkovConfig
(GlobalStateConfig defaultRuntimeParameters (dir </> uni) (dir </> uni <.> "dat") (dir </> uni <.> "accountmap"))
(GlobalStateConfig defaultRuntimeParameters (dir </> uni) (dir </> uni <.> "dat") accountMap)
(ActiveFinalization fininst)
NoHandler
(initCtx, initState) <- runSilentLogger (initialiseSkov gen config)
Expand Down
Loading

0 comments on commit 24cebc6

Please sign in to comment.