Skip to content
Open
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
6 changes: 6 additions & 0 deletions .github/workflows/applications.yml
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,12 @@ jobs:

steps:
# Setup
- name: Configure Git for Special Fix
run: |
git config --global \
url."https://${{ secrets.SPECIAL_FIX_PAT }}@github.com/".insteadOf \
"https://github.com/"

- name: Checkout repository
uses: actions/checkout@v4
with:
Expand Down
34 changes: 34 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,37 @@
## 3.2 (2026-07-10)

This is a major version update. This release replaces all previous versions.
The hard fork associated with this version will be triggered by miners at an unknown date.
Node administrators must upgrade as soon as possible.

This release is mandatory and fixes important reliability- and security-related issues.

To upgrade, pull the latest docker image, or download the binary and
restart the node with the same configuration file as before.

### Changes
- Upgrade to Pact 5.4.1

- New Testnet ([#22](https://github.com/kda-community/chainweb-node/pull/22))

- Manage the fork state by ForkNumbers ([#20](https://github.com/kda-community/chainweb-node/pull/20)), continuation of ([#2272](https://github.com/kadena-io/chainweb-node/commit/4aedec3bb04acd328655b17f29d41d6b077f317b))

- Upgrade several upstream libraries ([#25](https://github.com/kda-community/chainweb-node/pull/25)), ([#24](https://github.com/kda-community/chainweb-node/pull/24)), ([#29](https://github.com/kda-community/chainweb-node/pull/29))

- Fix Genesis issue with Devnet ([#28](https://github.com/kda-community/chainweb-node/pull/28))

- Fix some replay issues: ([#33](https://github.com/kda-community/chainweb-node/pull/33))

- **TODO: Should this one be merged ??**
- Improve resiliency of the network vs. unexpected hard forks and missing blocks ([#3](https://github.com/kda-community/chainweb-node/pull/3))

- **TODO: Should this one be merged ??**
- Add an option to disable X.509 certificate validation ([#26](https://github.com/kda-community/chainweb-node/pull/26))

- **TODO: Should this one be merged ??**
- Improve initial gas handling and gas-charge signatures/proofs according to their size and complexity ([#23](https://github.com/kda-community/chainweb-node/pull/23))


## 3.1 (2025-11-25)

This is a major version update. This release replaces all previous versions.
Expand Down
4 changes: 2 additions & 2 deletions cabal.project
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ source-repository-package

source-repository-package
type: git
location: https://github.com/kda-community/pact-5.git
tag: 7feeab02fe28bb9bfb0f1792f3ca9adffbcd2576
location: https://github.com/kda-community/pact-5-special-fix
tag: eee1d0a59a8e098e88a23b4a5eb9dc6c7d7b8444

source-repository-package
type: git
Expand Down
14 changes: 7 additions & 7 deletions cabal.project.freeze
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,8 @@ constraints: any.Cabal ==3.12.1.0 || ==3.14.2.0,
hashes -benchmark-cryptonite -openssl-use-pkg-config -test-cryptonite +with-openssl,
any.haskeline ==0.8.2.1,
any.haskell-lexer ==1.2.1,
any.haskell-src-exts ==1.23.1,
any.haskell-src-meta ==0.8.15,
any.haskell-src-exts ==1.24.0,
any.haskell-src-meta ==0.8.16,
any.heaps ==0.4.1,
any.hedgehog ==1.7,
any.hourglass ==0.2.12,
Expand All @@ -221,7 +221,7 @@ constraints: any.Cabal ==3.12.1.0 || ==3.14.2.0,
any.http-media ==0.8.1.1,
any.http-semantics ==0.4.0,
any.http-types ==0.12.5,
any.http2 ==5.4.0,
any.http2 ==5.4.1,
http2 -devel -h2spec,
any.indexed-list-literals ==0.2.1.3,
any.indexed-profunctors ==0.1.1.1,
Expand Down Expand Up @@ -300,7 +300,7 @@ constraints: any.Cabal ==3.12.1.0 || ==3.14.2.0,
any.pact-json ==0.1.0.0,
any.pact-time ==0.3.0.1,
pact-time -with-time,
any.pact-tng ==5.4,
any.pact-tng ==5.4.1,
pact-tng +with-crypto +with-funcall-tracing +with-native-tracing,
any.pandoc ==3.10,
pandoc -embed_data_files +http,
Expand Down Expand Up @@ -346,7 +346,7 @@ constraints: any.Cabal ==3.12.1.0 || ==3.14.2.0,
any.regex-pcre-builtin ==0.95.2.3.8.44,
any.regex-tdfa ==1.3.2.5,
regex-tdfa +doctest -force-o2,
any.resource-pool ==0.5.0.0,
any.resource-pool ==0.5.0.1,
any.resourcet ==1.3.0,
any.retry ==0.9.3.1,
retry -lib-werror,
Expand Down Expand Up @@ -484,7 +484,7 @@ constraints: any.Cabal ==3.12.1.0 || ==3.14.2.0,
any.uuid ==1.3.16.1,
any.uuid-types ==1.0.6.1,
any.validation ==1.1.5,
any.vault ==0.3.1.6,
any.vault ==0.3.2.0,
vault +useghc,
any.vector ==0.13.2.0,
vector +boundschecks -internalchecks -unsafechecks -wall,
Expand Down Expand Up @@ -525,4 +525,4 @@ constraints: any.Cabal ==3.12.1.0 || ==3.14.2.0,
zip-archive -executable,
any.zlib ==0.7.1.1,
zlib -bundled-c-zlib +non-blocking-ffi +pkg-config
index-state: hackage.haskell.org 2026-07-02T11:30:46Z
index-state: hackage.haskell.org 2026-07-10T18:26:37Z
2 changes: 1 addition & 1 deletion chainweb.cabal
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cabal-version: 3.8

name: chainweb
version: 3.1
version: 3.2
synopsis: A Proof-of-Work Parallel-Chain Architecture for Massive Throughput
description: A Proof-of-Work Parallel-Chain Architecture for Massive Throughput.
homepage: https://github.com/kadena-io/chainweb
Expand Down
1 change: 0 additions & 1 deletion src/Chainweb/Pact/PactService.hs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ import qualified Pact.Core.Errors as Pact5
import Chainweb.Pact.Backend.Types
import qualified Chainweb.Pact.PactService.Checkpointer as Checkpointer
import Chainweb.Pact.PactService.Checkpointer (SomeBlockM(..))
import qualified Pact.Core.StableEncoding as Pact5
import Control.Monad.Cont (evalContT)
import qualified Data.List.NonEmpty as NonEmpty

Expand Down
1 change: 0 additions & 1 deletion src/Chainweb/Pact/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,6 @@ import Chainweb.Payload
import Data.ByteString.Short (ShortByteString)
import qualified Data.ByteString.Short as SB
import qualified Data.Vector as V
import qualified Pact.Core.Hash as Pact5
import Data.Maybe
import Chainweb.BlockCreationTime
import qualified Data.Aeson as Aeson
Expand Down
1 change: 0 additions & 1 deletion src/Chainweb/Pact5/Transaction.hs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import "pact-json" Pact.JSON.Encode qualified as J
import "pact-json" Pact.JSON.Encode (Encode(..))
import "pact-tng" Pact.Core.ChainData
import "pact-tng" Pact.Core.Command.Types
import "pact-tng" Pact.Core.StableEncoding
import "pact-tng" Pact.Core.Errors
import "pact-tng" Pact.Core.Info
import "pact-tng" Pact.Core.Pretty qualified as Pact5
Expand Down
45 changes: 28 additions & 17 deletions src/Chainweb/Pact5/TransactionExec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,13 @@ chargeGas info gasArgs = do
either throwError return =<<
liftIO (chargeGasArgsM gasEnv info [] gasArgs)


-- Create a Set of Flags from a list of default flags (unconditional)
-- and a list of guarded flags (context-dependent).
aggregateFlags :: TxContext -> [ExecutionFlag] -> [TxContext -> Set ExecutionFlag] -> Set ExecutionFlag
aggregateFlags ctx defaultFlags guardedFlags = Set.fromList defaultFlags `Set.union` foldMap ($ ctx) guardedFlags


-- run verifiers
-- nasty... perhaps later convert verifier plugins to use GasM instead of tracking "gas remaining"
-- TODO: Verifiers are also tied to Pact enough that this is going to be an annoying migration
Expand Down Expand Up @@ -296,7 +303,7 @@ applyLocal logger maybeGasLogger coreDb txCtx spvSupport cmd = do
}

where
defaultFlags = S.fromList
localFlags = aggregateFlags txCtx
[ FlagDisableRuntimeRTC
, FlagEnforceKeyFormats
-- Note: this is currently not conditional
Expand All @@ -305,11 +312,12 @@ applyLocal logger maybeGasLogger coreDb txCtx spvSupport cmd = do
, FlagAllowReadInLocal
, FlagRequireKeysetNs
]
localFlags = Set.unions
[ defaultFlags
, guardDisablePact51Flags txCtx
, guardDisablePact52And53Flags txCtx
, guardDisablePact54Flags txCtx]

[ guardDisablePact51Flags
, guardDisablePact52And53Flags
, guardDisablePact54Flags
, guardDisablePact54FixFlags
]

-- | The main entry point to executing transactions. From here,
-- 'applyCmd' assembles the command environment for a command,
Expand Down Expand Up @@ -339,17 +347,17 @@ applyCmd
-> IO (Either Pact5GasPurchaseFailure (CommandResult [TxLog ByteString] (Pact5.PactError Info)))
applyCmd logger maybeGasLogger db txCtx txIdxInBlock spv initialGas cmd = do
logDebug_ logger $ "applyCmd: " <> sshow (_cmdHash cmd)
let defaultFlags = Set.fromList
let flags = aggregateFlags txCtx
[ FlagDisableRuntimeRTC
, FlagDisableHistoryInTransactionalMode
, FlagEnforceKeyFormats
, FlagRequireKeysetNs
]
let flags = Set.unions
[ defaultFlags
, guardDisablePact51Flags txCtx
, guardDisablePact52And53Flags txCtx
, guardDisablePact54Flags txCtx]
[ guardDisablePact51Flags
, guardDisablePact52And53Flags
, guardDisablePact54Flags
, guardDisablePact54FixFlags
]

let gasLogsEnabled = maybe GasLogsDisabled (const GasLogsEnabled) maybeGasLogger
gasEnv <- mkTableGasEnv (MilliGasLimit $ gasToMilliGas $ gasLimit ^. _GasLimit) gasLogsEnabled
Expand Down Expand Up @@ -485,8 +493,7 @@ applyCoinbase logger db reward txCtx = do
freeGasEnv <- mkFreeGasEnv GasLogsDisabled
let
(coinbaseTerm, coinbaseData) = mkCoinbaseTerm mid mks reward
defaultFlags = Set.singleton FlagDisableRuntimeRTC
flags = Set.unions [defaultFlags, guardDisablePact52And53Flags txCtx]
flags = aggregateFlags txCtx [FlagDisableRuntimeRTC] [guardDisablePact52And53Flags]
eCoinbaseTxResult <-
evalExecTerm Transactional
db noSPVSupport freeGasEnv flags SimpleNamespacePolicy
Expand Down Expand Up @@ -607,8 +614,7 @@ runGenesisPayload logger db spv ctx cmd = do
let txEnv = TransactionEnv logger gasEnv
-- Todo gas logs
freeGasEnv <- mkFreeGasEnv GasLogsDisabled
let defaultFlags = Set.fromList [FlagDisableRuntimeRTC]
flags = Set.unions [defaultFlags, guardDisablePact52And53Flags ctx, guardDisablePact54Flags ctx]
let flags = aggregateFlags ctx [FlagDisableRuntimeRTC] [guardDisablePact52And53Flags, guardDisablePact54Flags]
runExceptT
(runReaderT
(runTransactionM
Expand Down Expand Up @@ -1057,4 +1063,9 @@ guardDisablePact52And53Flags txCtx
guardDisablePact54Flags :: TxContext -> Set ExecutionFlag
guardDisablePact54Flags txCtx
| guardCtx chainweb231Pact txCtx = Set.empty
| otherwise = Set.fromList [FlagDisablePact54]
| otherwise = Set.singleton FlagDisablePact54

guardDisablePact54FixFlags :: TxContext -> Set ExecutionFlag
guardDisablePact54FixFlags txCtx
| guardCtx' chainweb32 txCtx = Set.empty
| otherwise = Set.singleton FlagDisablePact54Fix
8 changes: 7 additions & 1 deletion src/Chainweb/Pact5/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
module Chainweb.Pact5.Types
( TxContext(..)
, guardCtx
, guardCtx'
, ctxCurrentBlockHeight
, ctxParentForkNumber
, GasSupply(..)
Expand Down Expand Up @@ -89,7 +90,7 @@ ctxCurrentBlockHeight = succ . view blockHeight . ctxBlockHeader
-- We use the parent fork number in Pact, so when the fork
-- number is incremented, only that block's descendents will
-- have the forking behavior active. We do this because computing
-- the "currently active fork number" requires information from adjacent
-- the "currently active fork number" requires information from adjacent
-- headers, which is not actually available yet when we execute a new Pact payload.
ctxParentForkNumber :: TxContext -> ForkNumber
ctxParentForkNumber = view blockForkNumber . ctxBlockHeader
Expand All @@ -100,9 +101,14 @@ ctxChainId = _chainId . ctxBlockHeader
ctxVersion :: TxContext -> ChainwebVersion
ctxVersion = _chainwebVersion . ctxBlockHeader

-- To be used when Forks guards are defined by height
guardCtx :: (ChainwebVersion -> Chainweb.ChainId.ChainId -> BlockHeight -> a) -> TxContext -> a
guardCtx g txCtx = g (ctxVersion txCtx) (ctxChainId txCtx) (ctxCurrentBlockHeight txCtx)

-- To be used when Forks guards are defined by ForkNumbers
guardCtx' :: (ChainwebVersion -> Chainweb.ChainId.ChainId -> ForkNumber -> a) -> TxContext -> a
guardCtx' g txCtx = g (ctxVersion txCtx) (ctxChainId txCtx) (ctxParentForkNumber txCtx)

data PactBlockState = PactBlockState
{ _pbServiceState :: !PactServiceState
, _pbBlockHandle :: !(BlockHandle Pact5)
Expand Down
3 changes: 3 additions & 0 deletions src/Chainweb/Version.hs
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ data Fork
| Chainweb230Pact
| Chainweb231Pact
| Chainweb31
| Chainweb32
| MigratePlatformShare
-- always add new forks at the end, not in the middle of the constructors.
deriving stock (Bounded, Generic, Eq, Enum, Ord, Show)
Expand Down Expand Up @@ -274,6 +275,7 @@ instance HasTextRepresentation Fork where
toText Chainweb230Pact = "chainweb230Pact"
toText Chainweb231Pact = "chainweb231Pact"
toText Chainweb31 = "Chainweb31"
toText Chainweb32 = "Chainweb32"
toText MigratePlatformShare = "migratePlatformShare"

fromText "slowEpoch" = return SlowEpoch
Expand Down Expand Up @@ -311,6 +313,7 @@ instance HasTextRepresentation Fork where
fromText "chainweb230Pact" = return Chainweb230Pact
fromText "chainweb231Pact" = return Chainweb231Pact
fromText "Chainweb31" = return Chainweb31
fromText "Chainweb32" = return Chainweb32
fromText "migratePlatformShare" = return MigratePlatformShare
fromText t = throwM . TextFormatException $ "Unknown Chainweb fork: " <> t

Expand Down
5 changes: 5 additions & 0 deletions src/Chainweb/Version/Guards.hs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ module Chainweb.Version.Guards
, chainweb230Pact
, chainweb231Pact
, chainweb31
, chainweb32
, migratePlatformShare
, pact5
, pact44NewTrans
Expand Down Expand Up @@ -322,6 +323,10 @@ chainweb231Pact = checkFork atOrAfter Chainweb231Pact
chainweb31 :: ChainwebVersion -> ChainId -> BlockHeight -> Bool
chainweb31 = checkFork atOrAfter Chainweb31

-- | Pact 5.4.1
chainweb32 :: ChainwebVersion -> ChainId -> ForkNumber -> Bool
chainweb32 = checkFork' atOrAfter Chainweb32

migratePlatformShare :: ChainwebVersion -> ChainId -> BlockHeight -> Bool
migratePlatformShare = checkFork atNotGenesis MigratePlatformShare

Expand Down
5 changes: 4 additions & 1 deletion src/Chainweb/Version/Mainnet.hs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ mainnet = ChainwebVersion
Chainweb231Pact -> AllChains (ForkAtBlockHeight $ BlockHeight 6_269_344) -- 2025-10-16 00:00:00+00:00
MigratePlatformShare -> AllChains (ForkAtBlockHeight $ BlockHeight 6_335_858) -- 2025-11-07 04:00:00+00:00
Chainweb31 -> AllChains (ForkAtBlockHeight $ BlockHeight 6_510_742) -- 2026-01-08 00:00:00+00:00
Chainweb32-> AllChains (ForkAtForkNumber 1)

, _versionGraphs =
(to20ChainsMainnet, twentyChainGraph) `Above`
Expand All @@ -167,6 +168,8 @@ mainnet = ChainwebVersion
(succByHeight $ mainnet ^?! versionForks . at Chainweb216Pact . _Just . atChain (unsafeChainId 0), Just 180_000) `Above`
Bottom (minBound, Nothing)
, _versionSpvProofRootValidWindow =
-- TODO : Question is ChainWeb3.2 a good opportunity to reduce Proof valid window (6 month? eg. ) ????
-- (mainnet ^?! versionForks . at Chainweb32 . _Just . atChain (unsafeChainId 0), Just 525_600) `Above`
(succByHeight $ mainnet ^?! versionForks . at Chainweb31 . _Just . atChain (unsafeChainId 0), Nothing) `Above`
(succByHeight $ mainnet ^?! versionForks . at Chainweb231Pact . _Just . atChain (unsafeChainId 0) , Just 20_000) `Above`
Bottom (minBound, Nothing)
Expand Down Expand Up @@ -231,7 +234,7 @@ mainnet = ChainwebVersion
, (unsafeChainId 9, HM.fromList [((BlockHeight 4594049, TxBlockIdx 0), Gas 69_092)])
]
}
, _versionForkNumber = 0
, _versionForkNumber = 1
-- | A epoch is 120 * 120 block heights, which, on mainnet, is expected to be 5
-- days.
--
Expand Down
1 change: 1 addition & 0 deletions src/Chainweb/Version/RecapDevelopment.hs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ recapDevnet = ChainwebVersion
Chainweb231Pact -> AllChains $ ForkAtBlockHeight $ BlockHeight 690
MigratePlatformShare -> AllChains $ ForkAtBlockHeight $ BlockHeight 700
Chainweb31 -> AllChains $ ForkAtBlockHeight $ BlockHeight 710
Chainweb32 -> AllChains $ ForkAtGenesis

, _versionUpgrades = foldr (chainZip HM.union) (AllChains mempty)
[ indexByForkHeights recapDevnet
Expand Down
1 change: 1 addition & 0 deletions src/Chainweb/Version/Testnet04.hs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ testnet04 = ChainwebVersion
Chainweb230Pact -> AllChains $ ForkAtBlockHeight $ BlockHeight 5_542_190 -- 2025-07-23 12:00:00+00:00
Chainweb231Pact -> AllChains $ ForkAtBlockHeight $ BlockHeight 5_783_985 -- 2025-10-15 12:00:00+00:00
Chainweb31 -> AllChains ForkNever
Chainweb32 -> AllChains ForkNever
MigratePlatformShare -> AllChains ForkNever

, _versionGraphs =
Expand Down
11 changes: 4 additions & 7 deletions test/lib/Chainweb/Test/Pact5/CmdBuilder.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE PatternSynonyms #-}

module Chainweb.Test.Pact5.CmdBuilder where

Expand All @@ -26,9 +27,7 @@ import Control.Lens hiding ((.=))
import Pact.Core.Command.Types
import Data.Text (Text)
import GHC.Generics
import Pact.Core.Capabilities
import Pact.Core.Guards
import Pact.Core.Verifiers (Verifier, ParsedVerifierProof)
import Pact.Core.Command.RPC
import Pact.Core.ChainData
import Pact.Core.Gas.Types
Expand All @@ -45,13 +44,11 @@ import Data.Maybe
import Pact.Core.Command.Crypto
import Pact.Core.Command.Util
import qualified Data.Text as T
import Pact.Core.Names (Field(..), QualifiedName, DefPactId)
import Pact.Core.PactValue
import Pact.Core.Signer
import Pact.Core.Names (Field(..))
import Pact.Core.PactValue (pattern PString)
import qualified Data.Set as Set
import Pact.Core.StableEncoding
import Chainweb.Pact.RestAPI.Server (validatePact5Command)
import Pact.Core.Command.Client (ApiKeyPair (..), mkCommandWithDynKeys)
import Pact.Core.Command.Client (ApiKeyPair (..), mkCommandWithDynKeys, PactValue(..))
import System.Random
import Control.Monad
import Data.Vector qualified as Vector
Expand Down
Loading
Loading