Skip to content

Commit caec51f

Browse files
sirlensalotStuart Popejoy
andauthored
Correct mempool tx persistence, check tx details in validate (#1348)
Co-authored-by: Stuart Popejoy <slpopejoy@users.noreply.github.com>
1 parent 5e32d03 commit caec51f

File tree

12 files changed

+78
-45
lines changed

12 files changed

+78
-45
lines changed

.github/workflows/applications.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ jobs:
572572
with:
573573
registry: ghcr.io
574574
username: kadena-build
575-
password: ${{ secrets.PKG_MANAGEMENT }}
575+
password: ${{ secrets.GITHUB_TOKEN }}
576576

577577
- name: Build and push
578578
id: docker_build

bench/Chainweb/Pact/Backend/ForkingBench.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ safeCapitalize = maybe [] (uncurry (:) . bimap toUpper (Prelude.map toLower)) .
474474

475475
validateCommand :: Command Text -> Either String ChainwebTransaction
476476
validateCommand cmdText = case verifyCommand cmdBS of
477-
ProcSucc cmd -> Right (mkPayloadWithText <$> cmd)
477+
ProcSucc cmd -> Right (mkPayloadWithTextOld <$> cmd)
478478
ProcFail err -> Left err
479479
where
480480
cmdBS :: Command ByteString

chainweb.cabal

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
cabal-version: 2.4
22

33
name: chainweb
4-
version: 2.12
4+
version: 2.12.1
55
synopsis: A Proof-of-Work Parallel-Chain Architecture for Massive Throughput
66
description: A Proof-of-Work Parallel-Chain Architecture for Massive Throughput.
77
homepage: https://github.com/kadena-io/chainweb
@@ -770,4 +770,3 @@ benchmark bench
770770
, streaming-commons >= 0.2
771771
, unordered-containers == 0.2.15.0
772772
, yet-another-logger >= 0.4
773-

src/Chainweb/Mempool/Mempool.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,8 @@ data InsertError = InsertErrorDuplicate
223223
| InsertErrorBuyGas Text
224224
| InsertErrorCompilationFailed Text
225225
| InsertErrorOther Text
226+
| InsertErrorInvalidHash
227+
| InsertErrorInvalidSigs
226228
deriving (Generic, Eq, NFData)
227229

228230
instance Show InsertError
@@ -240,6 +242,8 @@ instance Show InsertError
240242
show (InsertErrorBuyGas msg) = "Attempt to buy gas failed with: " <> T.unpack msg
241243
show (InsertErrorCompilationFailed msg) = "Transaction compilation failed: " <> T.unpack msg
242244
show (InsertErrorOther m) = "insert error: " <> T.unpack m
245+
show InsertErrorInvalidHash = "Invalid transaction hash"
246+
show InsertErrorInvalidSigs = "Invalid transaction sigs"
243247

244248
instance Exception InsertError
245249

src/Chainweb/Pact/PactService/ExecBlock.hs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,9 @@ validateChainwebTxs v cid cp txValidationTime bh txs doBuyGas
196196
where
197197
go = V.mapM validations initTxList >>= doBuyGas
198198

199-
validations t = runValid checkUnique t
199+
validations t =
200+
runValid checkUnique t
201+
>>= runValid checkTx
200202
>>= runValid checkTimes
201203
>>= runValid (return . checkCompile)
202204

@@ -213,6 +215,31 @@ validateChainwebTxs v cid cp txValidationTime bh txs doBuyGas
213215
| timingsCheck txValidationTime $ fmap payloadObj t = return $ Right t
214216
| otherwise = return $ Left InsertErrorInvalidTime
215217

218+
checkTx :: ChainwebTransaction -> IO (Either InsertError ChainwebTransaction)
219+
checkTx t
220+
| doCheckTx v bh =
221+
case P.verifyHash (P._cmdHash t) (SB.fromShort $ payloadBytes $ P._cmdPayload t) of
222+
Left _ -> pure $ Left InsertErrorInvalidHash
223+
Right _ -> case validateSigs t of
224+
Left _ -> pure $ Left InsertErrorInvalidSigs
225+
Right _ -> pure $ Right t
226+
| otherwise = pure $ Right t
227+
228+
validateSigs :: ChainwebTransaction -> Either () ()
229+
validateSigs t
230+
| length signers /= length sigs = Left ()
231+
| otherwise = case traverse validateSig $ zip signers sigs of
232+
Left _ -> Left ()
233+
Right _ -> Right ()
234+
where
235+
hsh = P._cmdHash t
236+
sigs = P._cmdSigs t
237+
signers = P._pSigners $ payloadObj $ P._cmdPayload t
238+
validateSig (signer,sig)
239+
| P.verifyUserSig hsh sig signer = Right ()
240+
| otherwise = Left ()
241+
242+
216243
initTxList :: ValidateTxs
217244
initTxList = V.map Right txs
218245

src/Chainweb/Pact/RestAPI/Server.hs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ import Chainweb.SPV.CreateProof
107107
import Chainweb.SPV.EventProof
108108
import Chainweb.SPV.OutputProof
109109
import Chainweb.SPV.PayloadProof
110-
import Chainweb.Transaction (ChainwebTransaction, mkPayloadWithText)
110+
import Chainweb.Transaction
111111
import qualified Chainweb.TreeDB as TreeDB
112112
import Chainweb.Utils
113113
import Chainweb.Version
@@ -620,12 +620,13 @@ toPactTx (Transaction b) = decodeStrict' b
620620

621621
validateCommand :: Command Text -> Either String ChainwebTransaction
622622
validateCommand cmdText = case verifyCommand cmdBS of
623-
ProcSucc cmd -> Right (mkPayloadWithText <$> cmd)
623+
ProcSucc cmd -> Right (mkPayloadWithText cmdBS <$> cmd)
624624
ProcFail err -> Left err
625625
where
626626
cmdBS :: Command ByteString
627627
cmdBS = encodeUtf8 <$> cmdText
628628

629+
629630
-- | Validate the length of the request key's underlying hash.
630631
--
631632
validateRequestKey :: RequestKey -> Handler ()

src/Chainweb/Transaction.hs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ module Chainweb.Transaction
1818
, timeToLiveOf
1919
, creationTimeOf
2020
, mkPayloadWithText
21+
, mkPayloadWithTextOld
2122
, payloadBytes
2223
, payloadObj
2324
) where
@@ -62,10 +63,15 @@ payloadObj :: PayloadWithText -> Payload PublicMeta ParsedCode
6263
payloadObj = _payloadObj
6364

6465

65-
mkPayloadWithText :: Payload PublicMeta ParsedCode -> PayloadWithText
66-
mkPayloadWithText p = PayloadWithText {
67-
_payloadBytes =
68-
SB.toShort $ BL.toStrict $ Aeson.encode $ fmap _pcCode p
66+
mkPayloadWithText :: Command ByteString -> Payload PublicMeta ParsedCode -> PayloadWithText
67+
mkPayloadWithText cmd p = PayloadWithText
68+
{ _payloadBytes = SB.toShort $ _cmdPayload cmd
69+
, _payloadObj = p
70+
}
71+
72+
mkPayloadWithTextOld :: Payload PublicMeta ParsedCode -> PayloadWithText
73+
mkPayloadWithTextOld p = PayloadWithText
74+
{ _payloadBytes = SB.toShort $ BL.toStrict $ Aeson.encode $ fmap _pcCode p
6975
, _payloadObj = p
7076
}
7177

src/Chainweb/Version.hs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ module Chainweb.Version
6060
, pact420Upgrade
6161
, enforceKeysetFormats
6262
, AtOrAfter(..)
63+
, doCheckTx
6364

6465
-- ** BlockHeader Validation Guards
6566
, slowEpochGuard
@@ -905,6 +906,13 @@ enforceKeysetFormats Testnet04 = (>= 1_701_000) -- 2021-11-18T17:54:36
905906
enforceKeysetFormats Development = (>= 100)
906907
enforceKeysetFormats _ = (>= 10)
907908

909+
doCheckTx :: ChainwebVersion -> BlockHeight -> Bool
910+
doCheckTx Mainnet01 = (>= 2_349_800) -- 2022-01-23T02:53:38
911+
doCheckTx Testnet04 = (>= 1_889_000) -- 2022-01-24T04:19:24
912+
doCheckTx Development = (>= 110)
913+
doCheckTx (FastTimedCPM g) | g == petersonChainGraph = (>= 7)
914+
doCheckTx _ = const False
915+
908916
-- -------------------------------------------------------------------------- --
909917
-- Header Validation Guards
910918
--

test/Chainweb/Test/Pact/PactInProcApi.hs

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ import Test.Tasty.HUnit
4747

4848
-- internal modules
4949

50-
import Pact.Parse
51-
import Pact.Types.ChainMeta
5250
import Pact.Types.Continuation
5351
import Pact.Types.Exp
5452
import Pact.Types.Command
@@ -76,7 +74,6 @@ import Chainweb.Test.Cut.TestBlockDb
7674
import Chainweb.Test.Pact.Utils
7775
import Chainweb.Test.Utils
7876
import Chainweb.Time
79-
import Chainweb.Transaction
8077
import Chainweb.Utils
8178
import Chainweb.Version
8279
import Chainweb.Version.Utils
@@ -748,7 +745,7 @@ goldenMemPool = mempty
748745
{ mpaGetBlock = getTestBlock
749746
}
750747
where
751-
getTestBlock validate bHeight bHash parent = do
748+
getTestBlock validate bHeight bHash _parent = do
752749
moduleStr <- readFile' $ testPactFilesDir ++ "test1.pact"
753750
let txs =
754751
[ (T.pack moduleStr)
@@ -763,16 +760,7 @@ goldenMemPool = mempty
763760
, "(at 'chain-id (chain-data))"
764761
, "(at 'sender (chain-data))"
765762
]
766-
outtxs' <- mkTxs txs
767-
-- the following is done post-hash which is lame but in
768-
-- the goldens. TODO boldly overwrite goldens at some point of
769-
-- great stability
770-
let f = modifyPayloadWithText . set (pMeta . pmCreationTime)
771-
g = modifyPayloadWithText . set (pMeta . pmTTL)
772-
t = toTxCreationTime $ _bct $ _blockCreationTime parent
773-
let outtxs = flip V.map outtxs' $ \tx ->
774-
let ttl = TTLSeconds $ ParsedInteger $ 24 * 60 * 60
775-
in fmap (g ttl . f t) tx
763+
outtxs <- mkTxs txs
776764
oks <- validate bHeight bHash outtxs
777765
unless (V.and oks) $ fail $ mconcat
778766
[ "tx failed validation! input list: \n"
@@ -791,7 +779,3 @@ goldenMemPool = mempty
791779
mkCmd ("1" <> sshow n) $
792780
mkExec code $
793781
mkKeySetData "test-admin-keyset" [sender00]
794-
modifyPayloadWithText f pwt = mkPayloadWithText newPayload
795-
where
796-
oldPayload = payloadObj pwt
797-
newPayload = f oldPayload

test/Chainweb/Test/Pact/Utils.hs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
{-# LANGUAGE ScopedTypeVariables #-}
99
{-# LANGUAGE TemplateHaskell #-}
1010
{-# LANGUAGE TupleSections #-}
11+
{-# LANGUAGE TypeApplications #-}
12+
1113

1214
{-# OPTIONS_GHC -fno-warn-incomplete-uni-patterns #-}
1315
-- |
@@ -378,9 +380,11 @@ mkCmd nonce rpc = defaultCmd
378380
--
379381
buildCwCmd :: CmdBuilder -> IO ChainwebTransaction
380382
buildCwCmd cmd = buildRawCmd cmd >>= \c -> case verifyCommand c of
381-
ProcSucc r -> return $ fmap mkPayloadWithText r
383+
ProcSucc r -> return $ fmap (mkPayloadWithText c) r
382384
ProcFail e -> throwM $ userError $ "buildCmd failed: " ++ e
383385

386+
387+
384388
-- | Build unparsed, unverified command
385389
--
386390
buildTextCmd :: CmdBuilder -> IO (Command Text)

0 commit comments

Comments
 (0)