Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make restoreBlocks atomic again #3528

Merged
merged 2 commits into from
Oct 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 22 additions & 22 deletions lib/wallet/src/Cardano/Wallet.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1072,7 +1072,8 @@ rollbackBlocks ctx wid point = db & \DBLayer{..} -> do
-- | Apply the given blocks to the wallet and update the wallet state,
-- transaction history and corresponding metadata.
--
-- Concurrency: `restoreBlocks` is not atomic; we assume that
-- Concurrency: `restoreBlocks` is atomic.
-- However, in the future, we may assume that
-- it is called in a sequential fashion for each wallet.
restoreBlocks
:: forall ctx s k.
Expand All @@ -1088,20 +1089,20 @@ restoreBlocks
-> BlockData IO (Either Address RewardAccount) ChainEvents s
-> BlockHeader
-> ExceptT ErrNoSuchWallet IO ()
restoreBlocks ctx tr wid blocks nodeTip = db & \DBLayer{..} -> do
restoreBlocks ctx tr wid blocks nodeTip = db & \DBLayer{..} ->
mapExceptT atomically $ do
sp <- liftIO $ currentSlottingParameters nl
cp0 <- mapExceptT atomically $
withNoSuchWallet wid (readCheckpoint wid)
cp0 <- withNoSuchWallet wid (readCheckpoint wid)
unless (cp0 `isParentOf` firstHeader blocks) $ fail $ T.unpack $ T.unwords
[ "restoreBlocks: given chain isn't a valid continuation."
, "Wallet is at:", pretty (currentTip cp0)
, "but the given chain continues starting from:"
, pretty (firstHeader blocks)
]

-- NOTE on concurrency:
-- TODO on concurrency:
-- In light-mode, 'applyBlocks' may take some time to retrieve
-- transaction data. We avoid blocking the database by
-- transaction data. We want avoid blocking the database by
-- not wrapping this into a call to 'atomically'.
-- However, this only works if the latest database checkpoint, `cp0`,
-- does not change in the meantime.
Expand Down Expand Up @@ -1164,27 +1165,26 @@ restoreBlocks ctx tr wid blocks nodeTip = db & \DBLayer{..} -> do
| wcp <- map (snd . fromWallet) cpsKeep
]

mapExceptT atomically $ do
liftIO $ forM_ txs $ \(Tx {txCBOR=mcbor},_) ->
forM_ mcbor $ \cbor -> do
traceWith tr $ MsgStoringCBOR cbor
liftIO $ forM_ txs $ \(Tx {txCBOR=mcbor},_) ->
forM_ mcbor $ \cbor -> do
traceWith tr $ MsgStoringCBOR cbor

putTxHistory wid txs
putTxHistory wid txs

updatePendingTxForExpiry wid (view #slotNo localTip)
forM_ slotPoolDelegations $ \delegation@(slotNo, cert) -> do
liftIO $ logDelegation delegation
putDelegationCertificate wid cert slotNo
updatePendingTxForExpiry wid (view #slotNo localTip)
forM_ slotPoolDelegations $ \delegation@(slotNo, cert) -> do
liftIO $ logDelegation delegation
putDelegationCertificate wid cert slotNo

liftIO $ mapM_ logCheckpoint cpsKeep
ExceptT $ modifyDBMaybe walletsDB $
adjustNoSuchWallet wid id $ \_ -> Right ( delta, () )
liftIO $ mapM_ logCheckpoint cpsKeep
ExceptT $ modifyDBMaybe walletsDB $
adjustNoSuchWallet wid id $ \_ -> Right ( delta, () )

prune wid epochStability
prune wid epochStability

liftIO $ do
traceWith tr $ MsgDiscoveredTxs txs
traceWith tr $ MsgDiscoveredTxsContent txs
liftIO $ do
traceWith tr $ MsgDiscoveredTxs txs
traceWith tr $ MsgDiscoveredTxsContent txs
where
nl = ctx ^. networkLayer
db = ctx ^. dbLayer @IO @s @k
Expand Down
5 changes: 0 additions & 5 deletions test/e2e/spec/byron_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,6 @@

describe CardanoWallet::Byron::Addresses do
it "Can list addresses - random", :adp_2211 do
skip %(ADP-2211 - Creating Byron random address intermittently fails with
`POST /byron-wallets/{walletId}/addresses`

The test fails randomly ~15% of the time.
)
id = create_byron_wallet
addresses = BYRON.addresses.list id
expect(addresses).to be_correct_and_respond 200
Expand Down