diff --git a/.circleci/config.yml b/.circleci/config.yml
index b1566e6b0cf..d4104686c59 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -7,12 +7,12 @@ executors:
   golang:
     docker:
       # Must match GO_VERSION_MIN in project root
-      - image: cimg/go:1.19.12
+      - image: cimg/go:1.20.7
     resource_class: medium+
   golang-2xl:
     docker:
       # Must match GO_VERSION_MIN in project root
-      - image: cimg/go:1.19.12
+      - image: cimg/go:1.20.7
     resource_class: 2xlarge
   ubuntu:
     docker:
@@ -545,12 +545,6 @@ workflows:
             - build
           suite: itest-batch_deal
           target: "./itests/batch_deal_test.go"
-      - test:
-          name: test-itest-ccupgrade
-          requires:
-            - build
-          suite: itest-ccupgrade
-          target: "./itests/ccupgrade_test.go"
       - test:
           name: test-itest-cli
           requires:
@@ -876,12 +870,6 @@ workflows:
             - build
           suite: itest-remove_verifreg_datacap
           target: "./itests/remove_verifreg_datacap_test.go"
-      - test:
-          name: test-itest-sdr_upgrade
-          requires:
-            - build
-          suite: itest-sdr_upgrade
-          target: "./itests/sdr_upgrade_test.go"
       - test:
           name: test-itest-sealing_resources
           requires:
@@ -906,12 +894,6 @@ workflows:
             - build
           suite: itest-sector_import_simple
           target: "./itests/sector_import_simple_test.go"
-      - test:
-          name: test-itest-sector_make_cc_avail
-          requires:
-            - build
-          suite: itest-sector_make_cc_avail
-          target: "./itests/sector_make_cc_avail_test.go"
       - test:
           name: test-itest-sector_miner_collateral
           requires:
@@ -930,18 +912,8 @@ workflows:
             - build
           suite: itest-sector_pledge
           target: "./itests/sector_pledge_test.go"
-      - test:
-          name: test-itest-sector_prefer_no_upgrade
-          requires:
-            - build
-          suite: itest-sector_prefer_no_upgrade
-          target: "./itests/sector_prefer_no_upgrade_test.go"
-      - test:
-          name: test-itest-sector_revert_available
-          requires:
-            - build
-          suite: itest-sector_revert_available
-          target: "./itests/sector_revert_available_test.go"
+          get-params: true
+          
       - test:
           name: test-itest-sector_terminate
           requires:
@@ -966,12 +938,6 @@ workflows:
             - build
           suite: itest-splitstore
           target: "./itests/splitstore_test.go"
-      - test:
-          name: test-itest-tape
-          requires:
-            - build
-          suite: itest-tape
-          target: "./itests/tape_test.go"
       - test:
           name: test-itest-verifreg
           requires:
@@ -1043,7 +1009,7 @@ workflows:
           requires:
             - build
           suite: utest-unit-rest
-          target: "./api/... ./blockstore/... ./build/... ./chain/... ./cli/... ./cmd/... ./conformance/... ./extern/... ./gateway/... ./journal/... ./lib/... ./markets/... ./node/... ./paychmgr/... ./storage/... ./tools/..."
+          target: "./blockstore/... ./build/... ./chain/... ./conformance/... ./gateway/... ./journal/... ./lib/... ./markets/... ./paychmgr/... ./tools/..."
           executor: golang-2xl
       - test:
           name: test-unit-storage
diff --git a/.circleci/gen.go b/.circleci/gen.go
index 5d951027a0c..93f409df250 100644
--- a/.circleci/gen.go
+++ b/.circleci/gen.go
@@ -65,6 +65,8 @@ func main() {
 			if err != nil {
 				panic(err)
 			}
+			// Redundantly flag both absolute and relative paths as excluded
+			excluded[filepath.Join(repo, s)] = struct{}{}
 			excluded[e] = struct{}{}
 		}
 	}
diff --git a/.circleci/template.yml b/.circleci/template.yml
index 33f62ee3ad8..de2cf47cc9a 100644
--- a/.circleci/template.yml
+++ b/.circleci/template.yml
@@ -7,12 +7,12 @@ executors:
   golang:
     docker:
       # Must match GO_VERSION_MIN in project root
-      - image: cimg/go:1.19.12
+      - image: cimg/go:1.20.7
     resource_class: medium+
   golang-2xl:
     docker:
       # Must match GO_VERSION_MIN in project root
-      - image: cimg/go:1.19.12
+      - image: cimg/go:1.20.7
     resource_class: 2xlarge
   ubuntu:
     docker:
@@ -545,7 +545,7 @@ workflows:
           [[- if or (eq $name "worker") (eq $name "deals_concurrent") (eq $name "wdpost_worker_config")]]
           executor: golang-2xl
           [[- end]]
-          [[- if (eq $name "wdpost")]]
+          [[- if or (eq $name "wdpost") (eq $name "sector_pledge")]]
           get-params: true
           [[end]]
       [[- end ]][[- end]]
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5045d877327..b07cb1f7bfe 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,100 @@
 # Lotus changelog
 
-# UNRELEASED
+# 1.24.0 / 2023-11-22
+
+This is the stable release for the upcoming **MANDATORY**  Filecoin network upgrade v21, codenamed Watermelon 🍉, at **epoch 3469380 - 2023-12-12T13:30:00Z**.
+
+
+The Filecoin network version 21 delivers the following FIPs:
+
+- [FIP0052: Increase Max Sector Commitment to 3.5 years](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0052.md)
+- [FIP0059: Synthetic PoRep](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0059.md)
+- [FIP0071: Deterministic State Access (IPLD Reachability)](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0071.md)
+- [FIP0072: Improved event syscall API](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0072.md) 
+- [FIP0073: Remove beneficiary from the self_destruct syscall](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0073.md)
+- [FIP0075: Improvements to FVM randomness syscalls](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0075.md)
+
+
+Full list of the other protocol improvements we are delivering can be found [here](https://github.com/filecoin-project/core-devs/blob/master/Network%20Upgrades/v21.md).
+
+## ☢️ Upgrade Warnings ☢️
+
+This feature release requires a minimum Go version of v1.20.7 or higher to successfully build Lotus. Go version 1.21.x is not supported yet.
+
+## v12 Builtin Actor Bundles
+
+[Builtin actor v12.0.0](https://github.com/filecoin-project/builtin-actors/releases/tag/v12.0.0) is used for supporting this upgrade.
+Make sure that your lotus actor bundle matches the v12 actors manifest by running the following cli after upgrading:
+
+```
+./lotus state actor-cids --network-version 21
+Network Version: 21
+Actor Version: 12
+Manifest CID: bafy2bzaceapkgfggvxyllnmuogtwasmsv5qi2qzhc2aybockd6kag2g5lzaio
+
+Actor             CID  
+datacap           bafk2bzacebpiwb2ml4qbnnaayxumtk43ryhc63exdgnhivy3hwgmzemawsmpq
+paymentchannel    bafk2bzacectv4cm47bnhga5febf3lo3fq47g72kmmp2xd5s6tcxz7hiqdywa4
+storagemarket     bafk2bzacedylkg5am446lcuih4voyzdn4yjeqfsxfzh5b6mcuhx4mok5ph5c4
+storagepower      bafk2bzacecsij5tpfzjpfuckxvccv2p3bdqjklkrfyyoei6lx5dyj5j4fvjm6
+cron              bafk2bzacechxjkfe2cehx4s7skj3wzfpzf7zolds64khrrrs66bhazsemktls
+eam               bafk2bzaceb3elj4hfbbjp7g5bptc7su7mptszl4nlqfedilxvstjo5ungm6oe
+ethaccount        bafk2bzaceb4gkau2vgsijcxpfuq33bd7w3efr2rrhxrwiacjmns2ntdiamswq
+reward            bafk2bzacealqnxn5lwzwexd6reav4dppypquklx2ujlnvaxiqk2tzstyvkp5u
+verifiedregistry  bafk2bzacedudgflxc75c77c6zkmfyq4u2xuk7k6xw6dfdccarjrvxx453b77q
+evm               bafk2bzacecmnyfiwb52tkbwmm2dsd7ysi3nvuxl3lmspy7pl26wxj4zj7w4wi
+placeholder       bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro
+storageminer      bafk2bzacedo75pabe4i2l3hvhtsjmijrcytd2y76xwe573uku25fi7sugqld6
+system            bafk2bzacebfqrja2hip7esf4eafxjmu6xcogoqu5xxtgdg7xa5szgvvdguchu
+account           bafk2bzaceboftg75mdiba7xbo2i3uvgtca4brhnr3u5ptihonixgpnrvhpxoa
+init              bafk2bzacebllyegx5r6lggf6ymyetbp7amacwpuxakhtjvjtvoy2bfkzk3vms
+```
+
+## Migration  
+
+We are expecting a heavier than normal state migration for this upgrade due to the amount of state changes introduced for miner sector info. (This is a similar migration as the Shark upgrade, however, we have introduced a couple of migration performance optimizations since then for a smoother upgrade experience.)
+
+All node operators, including storage providers, should be aware that ONE pre-migration is being scheduled 180 epochs before the upgrade, around 2023-12-12T12:00:00Z. It will take around 20-30 minutes for the pre-migration and less than 30 seconds for the final migration, depending on the amount of historical state in the node blockstore and the hardware specs the node is running on. During this time, expect slower block validation times, increased CPU and memory usage, and longer delays for API queries (during our testing, it topped out about 205 RAM(htop) on a 1TiB box).
+
+We recommend node operators (who haven't enabled splitstore `discard` mode) that do not care about historical chain states, to prune the chain blockstore by syncing from a snapshot 1-2 days before the upgrade.
+
+Note to full archival node operators: you may expect it takes some time  for the node to complete the final migration, during this period your node will fall out of sync and your chain service may have some disruption. However, you can expect the node to catch up soon after the migration completes. You can test out the migration by running the following on your node in offline mode:
+
+1. `lotus chain head | head -n1`
+2. Stop Lotus daemon
+3. `./lotus-shed migrate-state --repo=[path-to-your-lotus-repo] 21 [output-of-step-1]`
+
+You can check out the [tutorial for benchmarking the network migration here.](https://lotus.filecoin.io/kb/test-migration/)
+
+
+## BREAKING CHANGE
+
+There is a new protocol limit on how many partition could be submited in one PoSt - if you have any customized tooling for batching PoSts, please update accordingly. 
+- feat: limit PoSted partitions to 3 ([filecoin-project/lotus#11327](https://github.com/filecoin-project/lotus/pull/11327))
+
+## New features
+- Implement and support [FIP0052: Increase Max Sector Commitment to 3.5 years](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0052.md)
+   - fix: docs: Update SectorLifetime to be in line with FIP-0052 ([filecoin-project/lotus#11314](https://github.com/filecoin-project/lotus/pull/11314))
+- Implement and support [FIP0059: Synthetic PoRep](https://github.com/filecoin-project/FIPs/blob/master/FIPS/fip-0059.md) - Check out the [Lotus documentation for Synthetic PoRep](https://lotus.filecoin.io/storage-providers/advanced-configurations/sealing/#synthetic-porep).
+   - feat: implement Synthetic PoRep ([filecoin-project/lotus#11258](https://github.com/filecoin-project/lotus/pull/11258))
+   - chore: config: Update todo in UseSyntheticPoRep ([filecoin-project/lotus#11297](https://github.com/filecoin-project/lotus/pull/11297))
+   
+## Improvements
+- Backport: feat: sealing: Switch to calling PreCommitSectorBatch2 ([filecoin-project/lotus#11215](https://github.com/filecoin-project/lotus/pull/11215))
+- updated the boostrap nodes 
+
+## Dependencies
+- github.com/filecoin-project/go-amt-ipld/v4 (v4.0.0 -> v4.2.0)
+- chore: deps: update FFI, FVM, and actors ([filecoin-project/lotus#11310](https://github.com/filecoin-project/lotus/pull/11310))
+- chore: deps: update to final actors ([filecoin-project/lotus#11330](https://github.com/filecoin-project/lotus/pull/11440))
+- chore: deps: update to go-state-types v0.12.8 ([filecoin-project/lotus#11339](https://github.com/filecoin-project/lotus/pull/11437))
+- chore: deps: update libp2p to v0.30.0 #11434
+
+
+## Snapshots 
+
+The [Forest team](https://filecoinproject.slack.com/archives/C029LPZ5N73) at Chainsafe has launched a brand new lightweight snapshot service that is backed up by forest nodes! This is a great alternative service along with the fil-infra one, and it is compatible with lotus! We recommend lotus users to check it out [here](https://docs.filecoin.io/networks/mainnet#resources)! 
+
 
 # v1.23.3 / 2023-08-01
 
@@ -27,7 +121,7 @@ This feature release requires a **minimum Go version of v1.19.12 or higher to su
   - feat: sealing: flag to run data_cid untied from addpiece ([filecoin-project/lotus#10797](https://github.com/filecoin-project/lotus/pull/10797))
   - feat: Lotus Gateway: add MpoolPending, ChainGetBlock and MinerGetBaseInfo ([filecoin-project/lotus#10929](https://github.com/filecoin-project/lotus/pull/10929))
 
-## Improvements
+## Improvements && Bug Fixe
   - chore: update ffi & fvm ([filecoin-project/lotus#11040](https://github.com/filecoin-project/lotus/pull/11040))
   - feat: Make sure we don't store duplidate actor events caused to reorgs in events.db ([filecoin-project/lotus#11015](https://github.com/filecoin-project/lotus/pull/11015))
   - sealing: Use only non-assigned deals when selecting snap sectors ([filecoin-project/lotus#11002](https://github.com/filecoin-project/lotus/pull/11002))
@@ -105,6 +199,10 @@ This feature release requires a **minimum Go version of v1.19.12 or higher to su
   - fix: cli: Change arg wording in change-beneficiary cmd ([filecoin-project/lotus#10823](https://github.com/filecoin-project/lotus/pull/10823))
   - refactor: streamline error handling in CheckPendingMessages (#10818) ([filecoin-project/lotus#10818](https://github.com/filecoin-project/lotus/pull/10818))
   - feat: Add tmp indices to events table while performing migration to V2
+  - fix: sync: iterate over returned messages directly #11373
+  - fix: api: compute the effective gas cost with the correct base-fee #11357
+  - fix: check invariants: v12 check #11371
+  - fix: api: compute gasUsedRatio based on max gas in the tipset #11354
 
 # v1.23.2 / 2023-06-28
 
diff --git a/Dockerfile b/Dockerfile
index 99625eea103..00930fb0f19 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,5 @@
 #####################################
-FROM golang:1.19.12-bullseye AS lotus-builder
+FROM golang:1.20.7-bullseye AS lotus-builder
 MAINTAINER Lotus Development Team
 
 RUN apt-get update && apt-get install -y ca-certificates build-essential clang ocl-icd-opencl-dev ocl-icd-libopencl1 jq libhwloc-dev
diff --git a/GO_VERSION_MIN b/GO_VERSION_MIN
index e54f3135a7d..8909929f6e7 100644
--- a/GO_VERSION_MIN
+++ b/GO_VERSION_MIN
@@ -1 +1 @@
-1.19.12
+1.20.7
diff --git a/api/api_full.go b/api/api_full.go
index 591799b4883..e5f88936ace 100644
--- a/api/api_full.go
+++ b/api/api_full.go
@@ -21,7 +21,6 @@ import (
 	"github.com/filecoin-project/go-state-types/big"
 	"github.com/filecoin-project/go-state-types/builtin/v8/paych"
 	"github.com/filecoin-project/go-state-types/builtin/v9/market"
-	"github.com/filecoin-project/go-state-types/builtin/v9/miner"
 	verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
 	"github.com/filecoin-project/go-state-types/crypto"
 	"github.com/filecoin-project/go-state-types/dline"
@@ -29,7 +28,7 @@ import (
 
 	apitypes "github.com/filecoin-project/lotus/api/types"
 	"github.com/filecoin-project/lotus/chain/actors/builtin"
-	lminer "github.com/filecoin-project/lotus/chain/actors/builtin/miner"
+	"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
 	"github.com/filecoin-project/lotus/chain/actors/builtin/power"
 	"github.com/filecoin-project/lotus/chain/types"
 	"github.com/filecoin-project/lotus/chain/types/ethtypes"
@@ -499,9 +498,9 @@ type FullNode interface {
 	// expiration epoch
 	StateSectorGetInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorOnChainInfo, error) //perm:read
 	// StateSectorExpiration returns epoch at which given sector will expire
-	StateSectorExpiration(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*lminer.SectorExpiration, error) //perm:read
+	StateSectorExpiration(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorExpiration, error) //perm:read
 	// StateSectorPartition finds deadline/partition with the specified sector
-	StateSectorPartition(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok types.TipSetKey) (*lminer.SectorLocation, error) //perm:read
+	StateSectorPartition(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok types.TipSetKey) (*miner.SectorLocation, error) //perm:read
 	// StateSearchMsg looks back up to limit epochs in the chain for a message, and returns its receipt and the tipset where it was executed
 	//
 	// NOTE: If a replacing message is found on chain, this method will return
@@ -641,6 +640,11 @@ type FullNode interface {
 	// StateGetRandomnessFromBeacon is used to sample the beacon for randomness.
 	StateGetRandomnessFromBeacon(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte, tsk types.TipSetKey) (abi.Randomness, error) //perm:read
 
+	// StateGetRandomnessDigestFromTickets. is used to sample the chain for randomness.
+	StateGetRandomnessDigestFromTickets(ctx context.Context, randEpoch abi.ChainEpoch, tsk types.TipSetKey) (abi.Randomness, error) //perm:read
+	// StateGetRandomnessDigestFromBeacon is used to sample the beacon for randomness.
+	StateGetRandomnessDigestFromBeacon(ctx context.Context, randEpoch abi.ChainEpoch, tsk types.TipSetKey) (abi.Randomness, error) //perm:read
+
 	// StateGetBeaconEntry returns the beacon entry for the given filecoin epoch. If
 	// the entry has not yet been produced, the call will block until the entry
 	// becomes available
diff --git a/api/api_gateway.go b/api/api_gateway.go
index f6740e1e067..3f7bc21cc1d 100644
--- a/api/api_gateway.go
+++ b/api/api_gateway.go
@@ -9,10 +9,10 @@ import (
 	"github.com/filecoin-project/go-address"
 	"github.com/filecoin-project/go-jsonrpc"
 	"github.com/filecoin-project/go-state-types/abi"
-	"github.com/filecoin-project/go-state-types/builtin/v9/miner"
 	"github.com/filecoin-project/go-state-types/dline"
 
 	apitypes "github.com/filecoin-project/lotus/api/types"
+	"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
 	"github.com/filecoin-project/lotus/chain/types"
 	"github.com/filecoin-project/lotus/chain/types/ethtypes"
 	"github.com/filecoin-project/lotus/node/modules/dtypes"
diff --git a/api/api_storage.go b/api/api_storage.go
index a9e632998da..d5b3d5c1d67 100644
--- a/api/api_storage.go
+++ b/api/api_storage.go
@@ -19,10 +19,10 @@ import (
 	"github.com/filecoin-project/go-state-types/abi"
 	"github.com/filecoin-project/go-state-types/big"
 	"github.com/filecoin-project/go-state-types/builtin/v9/market"
-	"github.com/filecoin-project/go-state-types/builtin/v9/miner"
 	abinetwork "github.com/filecoin-project/go-state-types/network"
 
 	builtinactors "github.com/filecoin-project/lotus/chain/actors/builtin"
+	"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
 	"github.com/filecoin-project/lotus/chain/types"
 	"github.com/filecoin-project/lotus/storage/pipeline/sealiface"
 	"github.com/filecoin-project/lotus/storage/sealer/fsutil"
@@ -461,10 +461,15 @@ type SectorOffset struct {
 
 // DealInfo is a tuple of deal identity and its schedule
 type PieceDealInfo struct {
+	// "Old" builtin-market deal info
 	PublishCid   *cid.Cid
 	DealID       abi.DealID
 	DealProposal *market.DealProposal
+
+	// Common deal info
 	DealSchedule DealSchedule
+
+	// Best-effort deal asks
 	KeepUnsealed bool
 }
 
diff --git a/api/cbor_gen.go b/api/cbor_gen.go
index 80392b2127b..fd2cb30b496 100644
--- a/api/cbor_gen.go
+++ b/api/cbor_gen.go
@@ -42,7 +42,7 @@ func (t *PaymentInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Channel"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Channel")); err != nil {
+	if _, err := cw.WriteString(string("Channel")); err != nil {
 		return err
 	}
 
@@ -58,7 +58,7 @@ func (t *PaymentInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Vouchers"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Vouchers")); err != nil {
+	if _, err := cw.WriteString(string("Vouchers")); err != nil {
 		return err
 	}
 
@@ -83,7 +83,7 @@ func (t *PaymentInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("WaitSentinel"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("WaitSentinel")); err != nil {
+	if _, err := cw.WriteString(string("WaitSentinel")); err != nil {
 		return err
 	}
 
@@ -163,13 +163,32 @@ func (t *PaymentInfo) UnmarshalCBOR(r io.Reader) (err error) {
 			}
 
 			for i := 0; i < int(extra); i++ {
+				{
+					var maj byte
+					var extra uint64
+					var err error
+					_ = maj
+					_ = extra
+					_ = err
+
+					{
+
+						b, err := cr.ReadByte()
+						if err != nil {
+							return err
+						}
+						if b != cbg.CborNull[0] {
+							if err := cr.UnreadByte(); err != nil {
+								return err
+							}
+							t.Vouchers[i] = new(paych.SignedVoucher)
+							if err := t.Vouchers[i].UnmarshalCBOR(cr); err != nil {
+								return xerrors.Errorf("unmarshaling t.Vouchers[i] pointer: %w", err)
+							}
+						}
 
-				var v paych.SignedVoucher
-				if err := v.UnmarshalCBOR(cr); err != nil {
-					return err
+					}
 				}
-
-				t.Vouchers[i] = &v
 			}
 
 			// t.WaitSentinel (cid.Cid) (struct)
@@ -214,7 +233,7 @@ func (t *SealedRef) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Size"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Size")); err != nil {
+	if _, err := cw.WriteString(string("Size")); err != nil {
 		return err
 	}
 
@@ -230,7 +249,7 @@ func (t *SealedRef) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Offset"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Offset")); err != nil {
+	if _, err := cw.WriteString(string("Offset")); err != nil {
 		return err
 	}
 
@@ -246,7 +265,7 @@ func (t *SealedRef) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("SectorID"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("SectorID")); err != nil {
+	if _, err := cw.WriteString(string("SectorID")); err != nil {
 		return err
 	}
 
@@ -369,7 +388,7 @@ func (t *SealedRefs) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Refs"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Refs")); err != nil {
+	if _, err := cw.WriteString(string("Refs")); err != nil {
 		return err
 	}
 
@@ -447,13 +466,22 @@ func (t *SealedRefs) UnmarshalCBOR(r io.Reader) (err error) {
 			}
 
 			for i := 0; i < int(extra); i++ {
+				{
+					var maj byte
+					var extra uint64
+					var err error
+					_ = maj
+					_ = extra
+					_ = err
 
-				var v SealedRef
-				if err := v.UnmarshalCBOR(cr); err != nil {
-					return err
-				}
+					{
+
+						if err := t.Refs[i].UnmarshalCBOR(cr); err != nil {
+							return xerrors.Errorf("unmarshaling t.Refs[i]: %w", err)
+						}
 
-				t.Refs[i] = v
+					}
+				}
 			}
 
 		default:
@@ -484,7 +512,7 @@ func (t *SealTicket) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Epoch"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Epoch")); err != nil {
+	if _, err := cw.WriteString(string("Epoch")); err != nil {
 		return err
 	}
 
@@ -506,7 +534,7 @@ func (t *SealTicket) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Value"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Value")); err != nil {
+	if _, err := cw.WriteString(string("Value")); err != nil {
 		return err
 	}
 
@@ -639,7 +667,7 @@ func (t *SealSeed) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Epoch"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Epoch")); err != nil {
+	if _, err := cw.WriteString(string("Epoch")); err != nil {
 		return err
 	}
 
@@ -661,7 +689,7 @@ func (t *SealSeed) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Value"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Value")); err != nil {
+	if _, err := cw.WriteString(string("Value")); err != nil {
 		return err
 	}
 
@@ -794,7 +822,7 @@ func (t *PieceDealInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("DealID"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("DealID")); err != nil {
+	if _, err := cw.WriteString(string("DealID")); err != nil {
 		return err
 	}
 
@@ -810,7 +838,7 @@ func (t *PieceDealInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("PublishCid"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("PublishCid")); err != nil {
+	if _, err := cw.WriteString(string("PublishCid")); err != nil {
 		return err
 	}
 
@@ -832,7 +860,7 @@ func (t *PieceDealInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("DealProposal"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("DealProposal")); err != nil {
+	if _, err := cw.WriteString(string("DealProposal")); err != nil {
 		return err
 	}
 
@@ -848,7 +876,7 @@ func (t *PieceDealInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("DealSchedule"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("DealSchedule")); err != nil {
+	if _, err := cw.WriteString(string("DealSchedule")); err != nil {
 		return err
 	}
 
@@ -864,7 +892,7 @@ func (t *PieceDealInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("KeepUnsealed"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("KeepUnsealed")); err != nil {
+	if _, err := cw.WriteString(string("KeepUnsealed")); err != nil {
 		return err
 	}
 
@@ -1027,7 +1055,7 @@ func (t *SectorPiece) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Piece"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Piece")); err != nil {
+	if _, err := cw.WriteString(string("Piece")); err != nil {
 		return err
 	}
 
@@ -1043,7 +1071,7 @@ func (t *SectorPiece) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("DealInfo"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("DealInfo")); err != nil {
+	if _, err := cw.WriteString(string("DealInfo")); err != nil {
 		return err
 	}
 
@@ -1150,7 +1178,7 @@ func (t *DealSchedule) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("EndEpoch"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("EndEpoch")); err != nil {
+	if _, err := cw.WriteString(string("EndEpoch")); err != nil {
 		return err
 	}
 
@@ -1172,7 +1200,7 @@ func (t *DealSchedule) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("StartEpoch"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("StartEpoch")); err != nil {
+	if _, err := cw.WriteString(string("StartEpoch")); err != nil {
 		return err
 	}
 
diff --git a/api/mocks/mock_full.go b/api/mocks/mock_full.go
index a1e9c123015..d2f2e528e49 100644
--- a/api/mocks/mock_full.go
+++ b/api/mocks/mock_full.go
@@ -3263,6 +3263,36 @@ func (mr *MockFullNodeMockRecorder) StateGetNetworkParams(arg0 interface{}) *gom
 	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateGetNetworkParams", reflect.TypeOf((*MockFullNode)(nil).StateGetNetworkParams), arg0)
 }
 
+// StateGetRandomnessDigestFromBeacon mocks base method.
+func (m *MockFullNode) StateGetRandomnessDigestFromBeacon(arg0 context.Context, arg1 abi.ChainEpoch, arg2 types.TipSetKey) (abi.Randomness, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "StateGetRandomnessDigestFromBeacon", arg0, arg1, arg2)
+	ret0, _ := ret[0].(abi.Randomness)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// StateGetRandomnessDigestFromBeacon indicates an expected call of StateGetRandomnessDigestFromBeacon.
+func (mr *MockFullNodeMockRecorder) StateGetRandomnessDigestFromBeacon(arg0, arg1, arg2 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateGetRandomnessDigestFromBeacon", reflect.TypeOf((*MockFullNode)(nil).StateGetRandomnessDigestFromBeacon), arg0, arg1, arg2)
+}
+
+// StateGetRandomnessDigestFromTickets mocks base method.
+func (m *MockFullNode) StateGetRandomnessDigestFromTickets(arg0 context.Context, arg1 abi.ChainEpoch, arg2 types.TipSetKey) (abi.Randomness, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "StateGetRandomnessDigestFromTickets", arg0, arg1, arg2)
+	ret0, _ := ret[0].(abi.Randomness)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// StateGetRandomnessDigestFromTickets indicates an expected call of StateGetRandomnessDigestFromTickets.
+func (mr *MockFullNodeMockRecorder) StateGetRandomnessDigestFromTickets(arg0, arg1, arg2 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateGetRandomnessDigestFromTickets", reflect.TypeOf((*MockFullNode)(nil).StateGetRandomnessDigestFromTickets), arg0, arg1, arg2)
+}
+
 // StateGetRandomnessFromBeacon mocks base method.
 func (m *MockFullNode) StateGetRandomnessFromBeacon(arg0 context.Context, arg1 crypto.DomainSeparationTag, arg2 abi.ChainEpoch, arg3 []byte, arg4 types.TipSetKey) (abi.Randomness, error) {
 	m.ctrl.T.Helper()
diff --git a/api/proxy_gen.go b/api/proxy_gen.go
index ce4ec3d1e34..79bf0a73811 100644
--- a/api/proxy_gen.go
+++ b/api/proxy_gen.go
@@ -26,7 +26,6 @@ import (
 	"github.com/filecoin-project/go-jsonrpc/auth"
 	"github.com/filecoin-project/go-state-types/abi"
 	"github.com/filecoin-project/go-state-types/builtin/v8/paych"
-	"github.com/filecoin-project/go-state-types/builtin/v9/miner"
 	verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
 	"github.com/filecoin-project/go-state-types/crypto"
 	"github.com/filecoin-project/go-state-types/dline"
@@ -35,7 +34,7 @@ import (
 
 	apitypes "github.com/filecoin-project/lotus/api/types"
 	builtinactors "github.com/filecoin-project/lotus/chain/actors/builtin"
-	lminer "github.com/filecoin-project/lotus/chain/actors/builtin/miner"
+	"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
 	"github.com/filecoin-project/lotus/chain/types"
 	"github.com/filecoin-project/lotus/chain/types/ethtypes"
 	"github.com/filecoin-project/lotus/journal/alerting"
@@ -494,6 +493,10 @@ type FullNodeMethods struct {
 
 	StateGetNetworkParams func(p0 context.Context) (*NetworkParams, error) `perm:"read"`
 
+	StateGetRandomnessDigestFromBeacon func(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (abi.Randomness, error) `perm:"read"`
+
+	StateGetRandomnessDigestFromTickets func(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (abi.Randomness, error) `perm:"read"`
+
 	StateGetRandomnessFromBeacon func(p0 context.Context, p1 crypto.DomainSeparationTag, p2 abi.ChainEpoch, p3 []byte, p4 types.TipSetKey) (abi.Randomness, error) `perm:"read"`
 
 	StateGetRandomnessFromTickets func(p0 context.Context, p1 crypto.DomainSeparationTag, p2 abi.ChainEpoch, p3 []byte, p4 types.TipSetKey) (abi.Randomness, error) `perm:"read"`
@@ -556,11 +559,11 @@ type FullNodeMethods struct {
 
 	StateSearchMsg func(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) `perm:"read"`
 
-	StateSectorExpiration func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*lminer.SectorExpiration, error) `perm:"read"`
+	StateSectorExpiration func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorExpiration, error) `perm:"read"`
 
 	StateSectorGetInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) `perm:"read"`
 
-	StateSectorPartition func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*lminer.SectorLocation, error) `perm:"read"`
+	StateSectorPartition func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorLocation, error) `perm:"read"`
 
 	StateSectorPreCommitInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorPreCommitOnChainInfo, error) `perm:"read"`
 
@@ -3422,6 +3425,28 @@ func (s *FullNodeStub) StateGetNetworkParams(p0 context.Context) (*NetworkParams
 	return nil, ErrNotSupported
 }
 
+func (s *FullNodeStruct) StateGetRandomnessDigestFromBeacon(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (abi.Randomness, error) {
+	if s.Internal.StateGetRandomnessDigestFromBeacon == nil {
+		return *new(abi.Randomness), ErrNotSupported
+	}
+	return s.Internal.StateGetRandomnessDigestFromBeacon(p0, p1, p2)
+}
+
+func (s *FullNodeStub) StateGetRandomnessDigestFromBeacon(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (abi.Randomness, error) {
+	return *new(abi.Randomness), ErrNotSupported
+}
+
+func (s *FullNodeStruct) StateGetRandomnessDigestFromTickets(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (abi.Randomness, error) {
+	if s.Internal.StateGetRandomnessDigestFromTickets == nil {
+		return *new(abi.Randomness), ErrNotSupported
+	}
+	return s.Internal.StateGetRandomnessDigestFromTickets(p0, p1, p2)
+}
+
+func (s *FullNodeStub) StateGetRandomnessDigestFromTickets(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (abi.Randomness, error) {
+	return *new(abi.Randomness), ErrNotSupported
+}
+
 func (s *FullNodeStruct) StateGetRandomnessFromBeacon(p0 context.Context, p1 crypto.DomainSeparationTag, p2 abi.ChainEpoch, p3 []byte, p4 types.TipSetKey) (abi.Randomness, error) {
 	if s.Internal.StateGetRandomnessFromBeacon == nil {
 		return *new(abi.Randomness), ErrNotSupported
@@ -3763,14 +3788,14 @@ func (s *FullNodeStub) StateSearchMsg(p0 context.Context, p1 types.TipSetKey, p2
 	return nil, ErrNotSupported
 }
 
-func (s *FullNodeStruct) StateSectorExpiration(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*lminer.SectorExpiration, error) {
+func (s *FullNodeStruct) StateSectorExpiration(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorExpiration, error) {
 	if s.Internal.StateSectorExpiration == nil {
 		return nil, ErrNotSupported
 	}
 	return s.Internal.StateSectorExpiration(p0, p1, p2, p3)
 }
 
-func (s *FullNodeStub) StateSectorExpiration(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*lminer.SectorExpiration, error) {
+func (s *FullNodeStub) StateSectorExpiration(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorExpiration, error) {
 	return nil, ErrNotSupported
 }
 
@@ -3785,14 +3810,14 @@ func (s *FullNodeStub) StateSectorGetInfo(p0 context.Context, p1 address.Address
 	return nil, ErrNotSupported
 }
 
-func (s *FullNodeStruct) StateSectorPartition(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*lminer.SectorLocation, error) {
+func (s *FullNodeStruct) StateSectorPartition(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorLocation, error) {
 	if s.Internal.StateSectorPartition == nil {
 		return nil, ErrNotSupported
 	}
 	return s.Internal.StateSectorPartition(p0, p1, p2, p3)
 }
 
-func (s *FullNodeStub) StateSectorPartition(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*lminer.SectorLocation, error) {
+func (s *FullNodeStub) StateSectorPartition(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorLocation, error) {
 	return nil, ErrNotSupported
 }
 
diff --git a/api/types.go b/api/types.go
index 8db5120a85e..6e98a4de44b 100644
--- a/api/types.go
+++ b/api/types.go
@@ -19,8 +19,8 @@ import (
 	datatransfer "github.com/filecoin-project/go-data-transfer/v2"
 	"github.com/filecoin-project/go-fil-markets/retrievalmarket"
 	"github.com/filecoin-project/go-state-types/abi"
-	"github.com/filecoin-project/go-state-types/builtin/v9/miner"
 
+	"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
 	"github.com/filecoin-project/lotus/chain/types"
 	"github.com/filecoin-project/lotus/node/modules/dtypes"
 )
@@ -339,6 +339,7 @@ type ForkUpgradeParams struct {
 	UpgradeHyggeHeight       abi.ChainEpoch
 	UpgradeLightningHeight   abi.ChainEpoch
 	UpgradeThunderHeight     abi.ChainEpoch
+	UpgradeWatermelonHeight  abi.ChainEpoch
 }
 
 type NonceMapType map[address.Address]uint64
diff --git a/api/v0api/full.go b/api/v0api/full.go
index 322f7244954..d92d5a95c8e 100644
--- a/api/v0api/full.go
+++ b/api/v0api/full.go
@@ -15,7 +15,6 @@ import (
 	"github.com/filecoin-project/go-fil-markets/storagemarket"
 	"github.com/filecoin-project/go-state-types/abi"
 	"github.com/filecoin-project/go-state-types/builtin/v8/paych"
-	"github.com/filecoin-project/go-state-types/builtin/v9/miner"
 	verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
 	"github.com/filecoin-project/go-state-types/crypto"
 	"github.com/filecoin-project/go-state-types/dline"
@@ -23,7 +22,7 @@ import (
 
 	"github.com/filecoin-project/lotus/api"
 	apitypes "github.com/filecoin-project/lotus/api/types"
-	lminer "github.com/filecoin-project/lotus/chain/actors/builtin/miner"
+	"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
 	"github.com/filecoin-project/lotus/chain/types"
 	marketevents "github.com/filecoin-project/lotus/markets/loggers"
 	"github.com/filecoin-project/lotus/node/modules/dtypes"
@@ -450,9 +449,9 @@ type FullNode interface {
 	// expiration epoch
 	StateSectorGetInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorOnChainInfo, error) //perm:read
 	// StateSectorExpiration returns epoch at which given sector will expire
-	StateSectorExpiration(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*lminer.SectorExpiration, error) //perm:read
+	StateSectorExpiration(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorExpiration, error) //perm:read
 	// StateSectorPartition finds deadline/partition with the specified sector
-	StateSectorPartition(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok types.TipSetKey) (*lminer.SectorLocation, error) //perm:read
+	StateSectorPartition(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok types.TipSetKey) (*miner.SectorLocation, error) //perm:read
 	// StateSearchMsg searches for a message in the chain, and returns its receipt and the tipset where it was executed
 	//
 	// NOTE: If a replacing message is found on chain, this method will return
diff --git a/api/v0api/gateway.go b/api/v0api/gateway.go
index 9f6c54fa9fc..60885a1b710 100644
--- a/api/v0api/gateway.go
+++ b/api/v0api/gateway.go
@@ -8,11 +8,11 @@ import (
 
 	"github.com/filecoin-project/go-address"
 	"github.com/filecoin-project/go-state-types/abi"
-	"github.com/filecoin-project/go-state-types/builtin/v9/miner"
 	"github.com/filecoin-project/go-state-types/dline"
 	abinetwork "github.com/filecoin-project/go-state-types/network"
 
 	"github.com/filecoin-project/lotus/api"
+	"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
 	"github.com/filecoin-project/lotus/chain/types"
 	"github.com/filecoin-project/lotus/node/modules/dtypes"
 )
diff --git a/api/v0api/proxy_gen.go b/api/v0api/proxy_gen.go
index 29f6f67736c..f2f3973c12e 100644
--- a/api/v0api/proxy_gen.go
+++ b/api/v0api/proxy_gen.go
@@ -17,7 +17,6 @@ import (
 	"github.com/filecoin-project/go-fil-markets/storagemarket"
 	"github.com/filecoin-project/go-state-types/abi"
 	"github.com/filecoin-project/go-state-types/builtin/v8/paych"
-	"github.com/filecoin-project/go-state-types/builtin/v9/miner"
 	verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
 	"github.com/filecoin-project/go-state-types/crypto"
 	"github.com/filecoin-project/go-state-types/dline"
@@ -25,7 +24,7 @@ import (
 
 	"github.com/filecoin-project/lotus/api"
 	apitypes "github.com/filecoin-project/lotus/api/types"
-	lminer "github.com/filecoin-project/lotus/chain/actors/builtin/miner"
+	"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
 	"github.com/filecoin-project/lotus/chain/types"
 	marketevents "github.com/filecoin-project/lotus/markets/loggers"
 	"github.com/filecoin-project/lotus/node/modules/dtypes"
@@ -355,11 +354,11 @@ type FullNodeMethods struct {
 
 	StateSearchMsgLimited func(p0 context.Context, p1 cid.Cid, p2 abi.ChainEpoch) (*api.MsgLookup, error) `perm:"read"`
 
-	StateSectorExpiration func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*lminer.SectorExpiration, error) `perm:"read"`
+	StateSectorExpiration func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorExpiration, error) `perm:"read"`
 
 	StateSectorGetInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) `perm:"read"`
 
-	StateSectorPartition func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*lminer.SectorLocation, error) `perm:"read"`
+	StateSectorPartition func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorLocation, error) `perm:"read"`
 
 	StateSectorPreCommitInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) `perm:"read"`
 
@@ -2235,14 +2234,14 @@ func (s *FullNodeStub) StateSearchMsgLimited(p0 context.Context, p1 cid.Cid, p2
 	return nil, ErrNotSupported
 }
 
-func (s *FullNodeStruct) StateSectorExpiration(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*lminer.SectorExpiration, error) {
+func (s *FullNodeStruct) StateSectorExpiration(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorExpiration, error) {
 	if s.Internal.StateSectorExpiration == nil {
 		return nil, ErrNotSupported
 	}
 	return s.Internal.StateSectorExpiration(p0, p1, p2, p3)
 }
 
-func (s *FullNodeStub) StateSectorExpiration(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*lminer.SectorExpiration, error) {
+func (s *FullNodeStub) StateSectorExpiration(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorExpiration, error) {
 	return nil, ErrNotSupported
 }
 
@@ -2257,14 +2256,14 @@ func (s *FullNodeStub) StateSectorGetInfo(p0 context.Context, p1 address.Address
 	return nil, ErrNotSupported
 }
 
-func (s *FullNodeStruct) StateSectorPartition(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*lminer.SectorLocation, error) {
+func (s *FullNodeStruct) StateSectorPartition(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorLocation, error) {
 	if s.Internal.StateSectorPartition == nil {
 		return nil, ErrNotSupported
 	}
 	return s.Internal.StateSectorPartition(p0, p1, p2, p3)
 }
 
-func (s *FullNodeStub) StateSectorPartition(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*lminer.SectorLocation, error) {
+func (s *FullNodeStub) StateSectorPartition(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorLocation, error) {
 	return nil, ErrNotSupported
 }
 
diff --git a/api/v0api/v1_wrapper.go b/api/v0api/v1_wrapper.go
index f58b0420f32..265674e718f 100644
--- a/api/v0api/v1_wrapper.go
+++ b/api/v0api/v1_wrapper.go
@@ -12,11 +12,11 @@ import (
 	"github.com/filecoin-project/go-fil-markets/storagemarket"
 	"github.com/filecoin-project/go-state-types/abi"
 	"github.com/filecoin-project/go-state-types/big"
-	"github.com/filecoin-project/go-state-types/builtin/v9/miner"
 	"github.com/filecoin-project/go-state-types/crypto"
 
 	"github.com/filecoin-project/lotus/api"
 	"github.com/filecoin-project/lotus/api/v1api"
+	"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
 	"github.com/filecoin-project/lotus/chain/types"
 	marketevents "github.com/filecoin-project/lotus/markets/loggers"
 )
diff --git a/blockstore/cbor_gen.go b/blockstore/cbor_gen.go
index b8ebdb474bc..221f136762d 100644
--- a/blockstore/cbor_gen.go
+++ b/blockstore/cbor_gen.go
@@ -52,9 +52,11 @@ func (t *NetRpcReq) MarshalCBOR(w io.Writer) error {
 		return err
 	}
 	for _, v := range t.Cid {
-		if err := cbg.WriteCid(w, v); err != nil {
-			return xerrors.Errorf("failed writing cid field t.Cid: %w", err)
+
+		if err := cbg.WriteCid(cw, v); err != nil {
+			return xerrors.Errorf("failed to write cid field v: %w", err)
 		}
+
 	}
 
 	// t.Data ([][]uint8) (slice)
@@ -151,12 +153,25 @@ func (t *NetRpcReq) UnmarshalCBOR(r io.Reader) (err error) {
 	}
 
 	for i := 0; i < int(extra); i++ {
+		{
+			var maj byte
+			var extra uint64
+			var err error
+			_ = maj
+			_ = extra
+			_ = err
 
-		c, err := cbg.ReadCid(cr)
-		if err != nil {
-			return xerrors.Errorf("reading cid field t.Cid failed: %w", err)
+			{
+
+				c, err := cbg.ReadCid(cr)
+				if err != nil {
+					return xerrors.Errorf("failed to read cid field t.Cid[i]: %w", err)
+				}
+
+				t.Cid[i] = c
+
+			}
 		}
-		t.Cid[i] = c
 	}
 
 	// t.Data ([][]uint8) (slice)
@@ -183,6 +198,9 @@ func (t *NetRpcReq) UnmarshalCBOR(r io.Reader) (err error) {
 			var maj byte
 			var extra uint64
 			var err error
+			_ = maj
+			_ = extra
+			_ = err
 
 			maj, extra, err = cr.ReadHeader()
 			if err != nil {
@@ -350,7 +368,7 @@ func (t *NetRpcErr) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Msg))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string(t.Msg)); err != nil {
+	if _, err := cw.WriteString(string(t.Msg)); err != nil {
 		return err
 	}
 
diff --git a/build/actors/v12.tar.zst b/build/actors/v12.tar.zst
new file mode 100644
index 00000000000..981a17c97d2
Binary files /dev/null and b/build/actors/v12.tar.zst differ
diff --git a/build/bootstrap/butterflynet.pi b/build/bootstrap/butterflynet.pi
index c7e9b2e9249..88ff5069f3e 100644
--- a/build/bootstrap/butterflynet.pi
+++ b/build/bootstrap/butterflynet.pi
@@ -1,2 +1,2 @@
-/dns4/bootstrap-0.butterfly.fildev.network/tcp/1347/p2p/12D3KooWD5mtdmjHQ1Puj9Md7SEfoa7kWMpwqUhAKsyYsBP56LQC
-/dns4/bootstrap-1.butterfly.fildev.network/tcp/1347/p2p/12D3KooWEoYPkm6o87ES6AppFY7d7WHJUQg7XVPRAyQZjEU31efQ
+/dns4/bootstrap-0.butterfly.fildev.network/tcp/1347/p2p/12D3KooWNwAkUtWuLtKCyyFP2vBzmpTHSrQao7KQx7Xfa8YvSg1N
+/dns4/bootstrap-1.butterfly.fildev.network/tcp/1347/p2p/12D3KooWPn8BDeNcctAcAGuxxiic8uMw2pAi3G5vgdFtfgRs5zBu
diff --git a/build/bootstrap/calibnet.pi b/build/bootstrap/calibnet.pi
index 4ac1d1e3a15..4586d93b1a7 100644
--- a/build/bootstrap/calibnet.pi
+++ b/build/bootstrap/calibnet.pi
@@ -2,3 +2,4 @@
 /dns4/bootstrap-1.calibration.fildev.network/tcp/1347/p2p/12D3KooWDTayrBojBn9jWNNUih4nNQQBGJD7Zo3gQCKgBkUsS6dp
 /dns4/bootstrap-2.calibration.fildev.network/tcp/1347/p2p/12D3KooWNRxTHUn8bf7jz1KEUPMc2dMgGfa4f8ZJTsquVSn3vHCG
 /dns4/bootstrap-3.calibration.fildev.network/tcp/1347/p2p/12D3KooWFWUqE9jgXvcKHWieYs9nhyp6NF4ftwLGAHm4sCv73jjK
+/dns4/calibration.node.glif.io/tcp/1237/p2p/12D3KooWQPYouEAsUQKzvFUA9sQ8tz4rfpqtTzh2eL6USd9bwg7x
diff --git a/build/bootstrap/mainnet.pi b/build/bootstrap/mainnet.pi
index 3e09b3d1425..f053d4e296c 100644
--- a/build/bootstrap/mainnet.pi
+++ b/build/bootstrap/mainnet.pi
@@ -13,4 +13,5 @@
 /dns4/node.glif.io/tcp/1235/p2p/12D3KooWBF8cpp65hp2u9LK5mh19x67ftAam84z9LsfaquTDSBpt
 /dns4/bootstrap-0.ipfsmain.cn/tcp/34721/p2p/12D3KooWQnwEGNqcM2nAcPtRR9rAX8Hrg4k9kJLCHoTR5chJfz6d
 /dns4/bootstrap-1.ipfsmain.cn/tcp/34723/p2p/12D3KooWMKxMkD5DMpSWsW7dBddKxKT7L2GgbNuckz9otxvkvByP
-/dns4/bootstarp-0.1475.io/tcp/61256/p2p/12D3KooWRzCVDwHUkgdK7eRgnoXbjDAELhxPErjHzbRLguSV1aRt
\ No newline at end of file
+/dns4/bootstarp-0.1475.io/tcp/61256/p2p/12D3KooWRzCVDwHUkgdK7eRgnoXbjDAELhxPErjHzbRLguSV1aRt
+/dns4/bootstrap-venus.mainnet.filincubator.com/tcp/8888/p2p/QmQu8C6deXwKvJP2D8B6QGyhngc3ZiDnFzEHBDx8yeBXST
diff --git a/build/builtin_actors.go b/build/builtin_actors.go
index 50aecde40af..4d4f86d225f 100644
--- a/build/builtin_actors.go
+++ b/build/builtin_actors.go
@@ -42,6 +42,13 @@ func init() {
 	if err := loadManifests(NetworkBundle); err != nil {
 		panic(err)
 	}
+
+	// The following code cid existed temporarily on the calibnet testnet, as a "buggy" storage miner actor implementation.
+	// We include them in our builtin bundle, but intentionally omit from metadata.
+	if NetworkBundle == "calibrationnet" {
+		actors.AddActorMeta("storageminer", cid.MustParse("bafk2bzacecnh2ouohmonvebq7uughh4h3ppmg4cjsk74dzxlbbtlcij4xbzxq"), actorstypes.Version12)
+		actors.AddActorMeta("storageminer", cid.MustParse("bafk2bzaced7emkbbnrewv5uvrokxpf5tlm4jslu2jsv77ofw2yqdglg657uie"), actorstypes.Version12)
+	}
 }
 
 // UseNetworkBundle switches to a different network bundle, by name.
@@ -183,6 +190,13 @@ func readEmbeddedBuiltinActorsMetadata(bundle string) ([]*BuiltinActorsMetadata,
 		if err != nil {
 			return nil, xerrors.Errorf("error loading builtin actors bundle: %w", err)
 		}
+
+		// The following manifest cids existed temporarily on the calibnet testnet
+		// We include them in our builtin bundle, but intentionally omit from metadata
+		if root == cid.MustParse("bafy2bzacedrunxfqta5skb7q7x32lnp4efz2oq7fn226ffm7fu5iqs62jkmvs") ||
+			root == cid.MustParse("bafy2bzacebl4w5ptfvuw6746w7ev562idkbf5ppq72e6zub22435ws2rukzru") {
+			continue
+		}
 		bundles = append(bundles, &BuiltinActorsMetadata{
 			Network:     name,
 			Version:     actorstypes.Version(version),
@@ -232,7 +246,7 @@ func readBundleManifest(r io.Reader) (cid.Cid, map[string]cid.Cid, error) {
 }
 
 // GetEmbeddedBuiltinActorsBundle returns the builtin-actors bundle for the given actors version.
-func GetEmbeddedBuiltinActorsBundle(version actorstypes.Version) ([]byte, bool) {
+func GetEmbeddedBuiltinActorsBundle(version actorstypes.Version, networkBundleName string) ([]byte, bool) {
 	fi, err := embeddedBuiltinActorReleases.Open(fmt.Sprintf("actors/v%d.tar.zst", version))
 	if err != nil {
 		return nil, false
@@ -243,7 +257,7 @@ func GetEmbeddedBuiltinActorsBundle(version actorstypes.Version) ([]byte, bool)
 	defer uncompressed.Close() //nolint
 
 	tarReader := tar.NewReader(uncompressed)
-	targetFileName := fmt.Sprintf("builtin-actors-%s.car", NetworkBundle)
+	targetFileName := fmt.Sprintf("builtin-actors-%s.car", networkBundleName)
 	for {
 		header, err := tarReader.Next()
 		switch err {
diff --git a/build/builtin_actors_gen.go b/build/builtin_actors_gen.go
index 13f595b6e2f..11c70f9eca5 100644
--- a/build/builtin_actors_gen.go
+++ b/build/builtin_actors_gen.go
@@ -72,10 +72,10 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
 		"verifiedregistry": MustParseCid("bafk2bzaceavue3zekq4wmvttck2vgxlcensrsgh5niu5qhna2owejycorftcc"),
 	},
 }, {
-	Network:      "butterflynet",
-	Version:      11,
-	BundleGitTag: "v11.0.0",
-	ManifestCid:  MustParseCid("bafy2bzaceaiy4dsxxus5xp5n5i4tjzkb7sc54mjz7qnk2efhgmsrobjesxnza"),
+	Network: "butterflynet",
+	Version: 11,
+
+	ManifestCid: MustParseCid("bafy2bzaceaiy4dsxxus5xp5n5i4tjzkb7sc54mjz7qnk2efhgmsrobjesxnza"),
 	Actors: map[string]cid.Cid{
 		"account":          MustParseCid("bafk2bzacecfdqb7p3jakhaa3cqnzpt7hxmhghrbxvafsylqno3febx55fnidw"),
 		"cron":             MustParseCid("bafk2bzaceavmqu2qihgbe3xdaotgypuzvdpiifnm7ll6rolks2u4lac6voosk"),
@@ -94,6 +94,29 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
 		"system":           MustParseCid("bafk2bzacedtuh7cht3fud7fb4avl4g2zbz57lc4ohiaufpaex6dkmdokn5rgo"),
 		"verifiedregistry": MustParseCid("bafk2bzaceb37hxeuoo5rgf6ansrdl2ykm5v5zp6kireubn4orcopr67jbxv6k"),
 	},
+}, {
+	Network:      "butterflynet",
+	Version:      12,
+	BundleGitTag: "v12.0.0",
+	ManifestCid:  MustParseCid("bafy2bzacectxvbk77ntedhztd6sszp2btrtvsmy7lp2ypnrk6yl74zb34t2cq"),
+	Actors: map[string]cid.Cid{
+		"account":          MustParseCid("bafk2bzacebp7anjdtg2sohyt6lromx4xs7nujtwdfcsffnptphaayabx7ysxs"),
+		"cron":             MustParseCid("bafk2bzacecu2y3awtemmglpkroiglulc2fj3gpdn6eazdqr6avcautiaighrg"),
+		"datacap":          MustParseCid("bafk2bzacebbh5aynu3v3fluqqrcdsphleodoig42xkid2ccwdnff3avhbdop4"),
+		"eam":              MustParseCid("bafk2bzacebzwt4v4hqoltiblhliwrnttxpr2dggbu3wsrvq4pwzisp7idu5w4"),
+		"ethaccount":       MustParseCid("bafk2bzaceb5f6vgjkl7ic6ry5sjspqm2iij6qlcdovwi3haodb7wn37pgebii"),
+		"evm":              MustParseCid("bafk2bzacebygt6zh6p52rkg2ugehm4k5yuu6f56i2pu6ywrmjez4n4zsje4p4"),
+		"init":             MustParseCid("bafk2bzaceagyf3pwsthod7klfi25ow2zf2i5isfrrgr5ua3lvkgfojalrdbhw"),
+		"multisig":         MustParseCid("bafk2bzacedgfo5mw2zqjwi37lah27sfxj4cw2abylgtxf3ucep4dyhgnppmqe"),
+		"paymentchannel":   MustParseCid("bafk2bzacebm37tgu52cgzmiln6iip6etfmq73fd3qqz2j5gxlhtvachs7kw4c"),
+		"placeholder":      MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"),
+		"reward":           MustParseCid("bafk2bzacedebvitdsztwebi44t5es4ls3p3hor252igzawr3s6uznmbvzh2ou"),
+		"storagemarket":    MustParseCid("bafk2bzaceb2tdeqtt2eqpzeb3gezuchb7g7uzbd52bgvcdt6bg3ckq7oisb74"),
+		"storageminer":     MustParseCid("bafk2bzaceb62clldtod2jimnri5k2koxttf6vqtlsvkjhnwduzs7sgsoakglw"),
+		"storagepower":     MustParseCid("bafk2bzacedxvlj5xmhytdjrjqyonz37duvxb2ioyzk75c27yypkqalxuh3xh6"),
+		"system":           MustParseCid("bafk2bzacec3vwj2chzaram3iqupkbfiein5h2l5qiltlrngbju2vg5umelclm"),
+		"verifiedregistry": MustParseCid("bafk2bzacedv2irkql7nil3w5v3ohqq3e54w62pxeoppjmaktzokolaaoh5ksu"),
+	},
 }, {
 	Network: "calibrationnet",
 	Version: 8,
@@ -155,10 +178,10 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
 		"verifiedregistry": MustParseCid("bafk2bzacec67wuchq64k7kgrujguukjvdlsl24pgighqdx5vgjhyk6bycrwnc"),
 	},
 }, {
-	Network:      "calibrationnet",
-	Version:      11,
-	BundleGitTag: "v11.0.0-rc2",
-	ManifestCid:  MustParseCid("bafy2bzacedhuowetjy2h4cxnijz2l64h4mzpk5m256oywp4evarpono3cjhco"),
+	Network: "calibrationnet",
+	Version: 11,
+
+	ManifestCid: MustParseCid("bafy2bzacedhuowetjy2h4cxnijz2l64h4mzpk5m256oywp4evarpono3cjhco"),
 	Actors: map[string]cid.Cid{
 		"account":          MustParseCid("bafk2bzacebor5mnjnsav34cmm5pcd3dy4wubbv4wtcrvba7depy3sct7ie4sy"),
 		"cron":             MustParseCid("bafk2bzacebetehhedh55alfn4rcx2mhjhvuiustxlhtxc3drkemnpttws5eqw"),
@@ -177,6 +200,29 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
 		"system":           MustParseCid("bafk2bzacedqvik2n3phnj3cni3h2k5mtvz43nyq7mdmv7k7euejysvajywdug"),
 		"verifiedregistry": MustParseCid("bafk2bzaceceoo5jlom2zweh7kpye2vkj33wgqnkjshlsw2neemqkfg5g2rmvg"),
 	},
+}, {
+	Network:      "calibrationnet",
+	Version:      12,
+	BundleGitTag: "v12.0.0",
+	ManifestCid:  MustParseCid("bafy2bzacednzb3pkrfnbfhmoqtb3bc6dgvxszpqklf3qcc7qzcage4ewzxsca"),
+	Actors: map[string]cid.Cid{
+		"account":          MustParseCid("bafk2bzacechwwxdqvggkdylm37zldjsra2ivkdzwp7fee56bzxbzs544wv6u6"),
+		"cron":             MustParseCid("bafk2bzacec4gdxxkqwxqqodsv6ug5dmdbqdfqwyqfek3yhxc2wweh5psxaeq6"),
+		"datacap":          MustParseCid("bafk2bzacecq5ppfskxgv3iea3jarsix6jdduuhwsn4fbvngtbmzelzmlygorm"),
+		"eam":              MustParseCid("bafk2bzacecb6cnwftvavpph4p34zs4psuy5xvbrhf7vszkva4npw6mw3c42xe"),
+		"ethaccount":       MustParseCid("bafk2bzaceajmc3y3sedsqymfla3dzzqzmbu5kmr2iskm26ga2u34ll5fpztfw"),
+		"evm":              MustParseCid("bafk2bzaced4sozr7m6rzcgpobzeiupghthfw6afumysu3oz6bxxirv74uo3vw"),
+		"init":             MustParseCid("bafk2bzaceaewh7b6zl2egclm7fqzx2lsqr57i75lb6cj43ndoa4mal3k5ld3m"),
+		"multisig":         MustParseCid("bafk2bzacednkwcpw5yzxjceoaliajgupzj6iqxe7ks2ll3unspbprbo5f2now"),
+		"paymentchannel":   MustParseCid("bafk2bzacebaxhk4itfiuvbftg7kz5zxugqnvdgerobitjq4vl6q4orcwk6wqg"),
+		"placeholder":      MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"),
+		"reward":           MustParseCid("bafk2bzacedra77pcglf7vdca2itcaa4vd6xrxynxmgfgdjdxqxfwqyhtoxehy"),
+		"storagemarket":    MustParseCid("bafk2bzacea7g46y7xxu2zjq2h75x6mmx3utz2uxnlvnwi6tzpsvulna3bmiva"),
+		"storageminer":     MustParseCid("bafk2bzaceb7qzqsi5uyxe4o5iuasi47l2hnznvmqr2eu4pl3qscvarjqlnuxo"),
+		"storagepower":     MustParseCid("bafk2bzacedd3ka44k7d46ckbinjhv3diyuu2epgbyvhqqyjkc64qlrg3wlgzi"),
+		"system":           MustParseCid("bafk2bzacecioupndtcnyw6iq2hbrxag3aufvczlv5nobnfbkbywqzcyfaa376"),
+		"verifiedregistry": MustParseCid("bafk2bzaceavldupmf7bimeeacs67z5xdfdlfca6p7sn6bev3mt5ggepfqvhqo"),
+	},
 }, {
 	Network: "caterpillarnet",
 	Version: 8,
@@ -247,10 +293,10 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
 		"verifiedregistry": MustParseCid("bafk2bzacecdhw6x7dfrxfysmn6tdbn2ny464omgqppxhjuawxauscidppd7pc"),
 	},
 }, {
-	Network:      "caterpillarnet",
-	Version:      11,
-	BundleGitTag: "v11.0.0",
-	ManifestCid:  MustParseCid("bafy2bzacebexc2jgzwr5ngn6jdnkwdqwwmcapajuypdgvopoe6bnvp4yxm4o2"),
+	Network: "caterpillarnet",
+	Version: 11,
+
+	ManifestCid: MustParseCid("bafy2bzacebexc2jgzwr5ngn6jdnkwdqwwmcapajuypdgvopoe6bnvp4yxm4o2"),
 	Actors: map[string]cid.Cid{
 		"account":          MustParseCid("bafk2bzaceanjiq5m3feytue5m7hhxfkob2ofg2greoct5tr77reuhrjglo66g"),
 		"cron":             MustParseCid("bafk2bzaceavgd5qj6n744tukhdrvxejygzs3jnlizmcvjsdnxkgiimrd5jrys"),
@@ -269,6 +315,29 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
 		"system":           MustParseCid("bafk2bzacebxfzeom3d7ahcz2n2nlwp7ncv767bdbbrisugks4l6v7lcu2tmyg"),
 		"verifiedregistry": MustParseCid("bafk2bzacedaws3or3twy45ltcxucgvqijsje4x675ph6vup2w35smlfneamno"),
 	},
+}, {
+	Network:      "caterpillarnet",
+	Version:      12,
+	BundleGitTag: "v12.0.0",
+	ManifestCid:  MustParseCid("bafy2bzacebxiub6qsy67asvl5cx33x5vjbuqinalmf3xtnbmokxmmklzdkvei"),
+	Actors: map[string]cid.Cid{
+		"account":          MustParseCid("bafk2bzacecereuhejfvodut5357cai4lmhsyr7uenhcxvmw6jpmhe6auuly32"),
+		"cron":             MustParseCid("bafk2bzacebo2whgy6jla4jsf5j4ovlqm2e4eepedlpw5wadas33yxmunis4b4"),
+		"datacap":          MustParseCid("bafk2bzacecjjncl7ftgj4mrzxxfxld74pt3pyfrxmcru7a5auab25b3aoixm6"),
+		"eam":              MustParseCid("bafk2bzacebyvawfzoxy7k4yxrj5nd3amg4rcopmnslxdwpzumfhsz5ezk4sws"),
+		"ethaccount":       MustParseCid("bafk2bzaceaccs76uc6osvb2iy6w2pumqei3wdjtxq7rgtsotobncmqoi7kzcg"),
+		"evm":              MustParseCid("bafk2bzaceawxgjzjkhbqwj36wzxeqbtngdh6y2tp4wsi27k7tbg2ujhw5rsjg"),
+		"init":             MustParseCid("bafk2bzacedws5od7o6ktqyo2hudmipxuubsv2lwxz45xxjn2zguze72t6zoik"),
+		"multisig":         MustParseCid("bafk2bzacecb4wk6n4lrmml3tssn6cszd4dc7ttux3kzjatrawhg4o6ovrng6w"),
+		"paymentchannel":   MustParseCid("bafk2bzacea3eb556mkjvosfbqfbyfg6dgu52rfnuctwzjy3b2bh2azredxzbo"),
+		"placeholder":      MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"),
+		"reward":           MustParseCid("bafk2bzaceb2x5zgkrho373l3ippp6krs7brugssg6hj2tib22xmqjzdm2o25a"),
+		"storagemarket":    MustParseCid("bafk2bzaced5j6drzmsebpxbf2dtptrc5tyidlbftdljqxavxqb57s2qpbvdek"),
+		"storageminer":     MustParseCid("bafk2bzaceckgusfenkczxolfczvnygnuhxbou5to2skwwngbkihla7hgdv4yy"),
+		"storagepower":     MustParseCid("bafk2bzaceagp6ilkltsltwii66nz6a4zen4qtfk7rdkvdv3gzq7fbv4ivox3u"),
+		"system":           MustParseCid("bafk2bzacedye5j5uxox7knb6zlnhseaadztyav76mjbyk5qslhhbpiy5cdtt2"),
+		"verifiedregistry": MustParseCid("bafk2bzacecduww5pirr7dvaijjijw4gf6ygf7vipgxh4scvv6vseo46gueb46"),
+	},
 }, {
 	Network: "devnet",
 	Version: 8,
@@ -330,10 +399,10 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
 		"verifiedregistry": MustParseCid("bafk2bzaced2mkyqobpgna5jevosym3adv2bvraggigyz2jgn5cxymirxj4x3i"),
 	},
 }, {
-	Network:      "devnet",
-	Version:      11,
-	BundleGitTag: "v11.0.0",
-	ManifestCid:  MustParseCid("bafy2bzaceay35go4xbjb45km6o46e5bib3bi46panhovcbedrynzwmm3drr4i"),
+	Network: "devnet",
+	Version: 11,
+
+	ManifestCid: MustParseCid("bafy2bzaceay35go4xbjb45km6o46e5bib3bi46panhovcbedrynzwmm3drr4i"),
 	Actors: map[string]cid.Cid{
 		"account":          MustParseCid("bafk2bzacecf2pprkbdlpm4e2xz3ufunxtgrgyh2ie3stuqiyhibsvdze7kvri"),
 		"cron":             MustParseCid("bafk2bzaceasr5d2skowvzv5mzsyak6waqrgc46ewj6rzbapkfi5woom6n6bwa"),
@@ -352,6 +421,29 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
 		"system":           MustParseCid("bafk2bzacedpyoncjbl4oxkjm5e77ngvpy2xfajjc4myfsv2vltvzxioattlu2"),
 		"verifiedregistry": MustParseCid("bafk2bzacebdqi5tr5pjnem5nylg2zbqcugvi7oxi35bhnrfudx4y4ufhlit2k"),
 	},
+}, {
+	Network:      "devnet",
+	Version:      12,
+	BundleGitTag: "v12.0.0",
+	ManifestCid:  MustParseCid("bafy2bzaceasjdukhhyjbegpli247vbf5h64f7uvxhhebdihuqsj2mwisdwa6o"),
+	Actors: map[string]cid.Cid{
+		"account":          MustParseCid("bafk2bzacedki4apynvdxxuoigmqkgaktgy2erjftoxqxqaklnelgveyaqknfu"),
+		"cron":             MustParseCid("bafk2bzacebjpczf7qtcisy3zdp3sqoohxe75tgupmdo5dr26vh7orzrsjn3b2"),
+		"datacap":          MustParseCid("bafk2bzacecz4esatk7gizdc7yvl6soigkelhix7izbc75q6eqtb7gjzavpcqc"),
+		"eam":              MustParseCid("bafk2bzacebhtpd5mxfyovi7fgsfj62nhtmh4t5guob4sgq73ymgsk7473ltig"),
+		"ethaccount":       MustParseCid("bafk2bzacebvdbbw5ag4qnxd7cif5mtakrw4wzv63diwl7awta5plaidfay4vg"),
+		"evm":              MustParseCid("bafk2bzacebb7vrhprnshn52bzfmypjdpcrcfecapk232a6gapk3kghu2mp67q"),
+		"init":             MustParseCid("bafk2bzaceaw4iouukgqxmwukfpt3sakdvsu75ftjvw47swnwtdftz5oszbt4w"),
+		"multisig":         MustParseCid("bafk2bzaceahyjwf6re4mnuwhopglo3qzh6aboluboncpijm7vuiz3u4bkazho"),
+		"paymentchannel":   MustParseCid("bafk2bzaceaupjw3djghaqw3g3hd4tw7uuas3njkszgzx2fhmgqh5eh4e6q2by"),
+		"placeholder":      MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"),
+		"reward":           MustParseCid("bafk2bzacebzso6xkjxdscbpncw7el2d4hap6lfkgwqzrbc76lzp33vkwk6obc"),
+		"storagemarket":    MustParseCid("bafk2bzacebzg74vyk3gzbhnz4zviwvxblyar574mtd6ayognmsvlkriejmunu"),
+		"storageminer":     MustParseCid("bafk2bzacecs262232b3awcrilyzpdketeayyqzzwgoavtxilgjvayrz55ovk4"),
+		"storagepower":     MustParseCid("bafk2bzacebbtj2m2ajawfuzxqz5nmdep7xevjo2qfjqa5tx3vr5m6qojolya4"),
+		"system":           MustParseCid("bafk2bzacecnau5wddulbsvwn75tc3w75jrlvkybgrlxs4ngonqab6xq3eowvg"),
+		"verifiedregistry": MustParseCid("bafk2bzacec37mddea65nvh4htsagtryfa3sq6i67utcupslyhzbhjhoy6hopa"),
+	},
 }, {
 	Network: "hyperspace",
 	Version: 8,
@@ -436,10 +528,10 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
 		"verifiedregistry": MustParseCid("bafk2bzacedfel6edzqpe5oujno7fog4i526go4dtcs6vwrdtbpy2xq6htvcg6"),
 	},
 }, {
-	Network:      "mainnet",
-	Version:      11,
-	BundleGitTag: "v11.0.0",
-	ManifestCid:  MustParseCid("bafy2bzacecnhaiwcrpyjvzl4uv4q3jzoif26okl3m66q3cijp3dfwlcxwztwo"),
+	Network: "mainnet",
+	Version: 11,
+
+	ManifestCid: MustParseCid("bafy2bzacecnhaiwcrpyjvzl4uv4q3jzoif26okl3m66q3cijp3dfwlcxwztwo"),
 	Actors: map[string]cid.Cid{
 		"account":          MustParseCid("bafk2bzacealnlr7st6lkwoh6wxpf2hnrlex5sknaopgmkr2tuhg7vmbfy45so"),
 		"cron":             MustParseCid("bafk2bzacebpewdvvgt6tk2o2u4rcovdgym67tadiis5usemlbejg7k3kt567o"),
@@ -458,6 +550,29 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
 		"system":           MustParseCid("bafk2bzaced7npe5mt5nh72jxr2igi2sofoa7gedt4w6kueeke7i3xxugqpjfm"),
 		"verifiedregistry": MustParseCid("bafk2bzacedej3dnr62g2je2abmyjg3xqv4otvh6e26du5fcrhvw7zgcaaez3a"),
 	},
+}, {
+	Network:      "mainnet",
+	Version:      12,
+	BundleGitTag: "v12.0.0",
+	ManifestCid:  MustParseCid("bafy2bzaceapkgfggvxyllnmuogtwasmsv5qi2qzhc2aybockd6kag2g5lzaio"),
+	Actors: map[string]cid.Cid{
+		"account":          MustParseCid("bafk2bzaceboftg75mdiba7xbo2i3uvgtca4brhnr3u5ptihonixgpnrvhpxoa"),
+		"cron":             MustParseCid("bafk2bzacechxjkfe2cehx4s7skj3wzfpzf7zolds64khrrrs66bhazsemktls"),
+		"datacap":          MustParseCid("bafk2bzacebpiwb2ml4qbnnaayxumtk43ryhc63exdgnhivy3hwgmzemawsmpq"),
+		"eam":              MustParseCid("bafk2bzaceb3elj4hfbbjp7g5bptc7su7mptszl4nlqfedilxvstjo5ungm6oe"),
+		"ethaccount":       MustParseCid("bafk2bzaceb4gkau2vgsijcxpfuq33bd7w3efr2rrhxrwiacjmns2ntdiamswq"),
+		"evm":              MustParseCid("bafk2bzacecmnyfiwb52tkbwmm2dsd7ysi3nvuxl3lmspy7pl26wxj4zj7w4wi"),
+		"init":             MustParseCid("bafk2bzacebllyegx5r6lggf6ymyetbp7amacwpuxakhtjvjtvoy2bfkzk3vms"),
+		"multisig":         MustParseCid("bafk2bzacecw5lyp3n3t67xdwrmo36h4z7afc3lobmmr6wg55w6yjzg5jhmh42"),
+		"paymentchannel":   MustParseCid("bafk2bzacectv4cm47bnhga5febf3lo3fq47g72kmmp2xd5s6tcxz7hiqdywa4"),
+		"placeholder":      MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"),
+		"reward":           MustParseCid("bafk2bzacealqnxn5lwzwexd6reav4dppypquklx2ujlnvaxiqk2tzstyvkp5u"),
+		"storagemarket":    MustParseCid("bafk2bzacedylkg5am446lcuih4voyzdn4yjeqfsxfzh5b6mcuhx4mok5ph5c4"),
+		"storageminer":     MustParseCid("bafk2bzacedo75pabe4i2l3hvhtsjmijrcytd2y76xwe573uku25fi7sugqld6"),
+		"storagepower":     MustParseCid("bafk2bzacecsij5tpfzjpfuckxvccv2p3bdqjklkrfyyoei6lx5dyj5j4fvjm6"),
+		"system":           MustParseCid("bafk2bzacebfqrja2hip7esf4eafxjmu6xcogoqu5xxtgdg7xa5szgvvdguchu"),
+		"verifiedregistry": MustParseCid("bafk2bzacedudgflxc75c77c6zkmfyq4u2xuk7k6xw6dfdccarjrvxx453b77q"),
+	},
 }, {
 	Network: "testing",
 	Version: 8,
@@ -519,10 +634,10 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
 		"verifiedregistry": MustParseCid("bafk2bzacecdmek2htsgcyoyl35glakyab66cojqo2y335njnm7krleb6yfbps"),
 	},
 }, {
-	Network:      "testing",
-	Version:      11,
-	BundleGitTag: "v11.0.0",
-	ManifestCid:  MustParseCid("bafy2bzacea2vxre32tg3xhpejrktiuzx4d3pcoe7yyazgscfibmegmchr6n42"),
+	Network: "testing",
+	Version: 11,
+
+	ManifestCid: MustParseCid("bafy2bzacea2vxre32tg3xhpejrktiuzx4d3pcoe7yyazgscfibmegmchr6n42"),
 	Actors: map[string]cid.Cid{
 		"account":          MustParseCid("bafk2bzaceccerssb3tgel6ukdghlwvs7dxsolj4fpkgn7dh7owzwapqb6ejpw"),
 		"cron":             MustParseCid("bafk2bzacebtfl6fczxnitrqqjhyefskf3asyn3gzuvqcddieoqfsaddk5fd4q"),
@@ -541,6 +656,29 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
 		"system":           MustParseCid("bafk2bzaceaatvscbnkv36ixhtt2zel4er5oskxevgumh5gegqkv7uzah36f24"),
 		"verifiedregistry": MustParseCid("bafk2bzacebp2r56wxadvfzpfbmqwfi3dlnwpmoc5u4tau2hfftbkuafkhye64"),
 	},
+}, {
+	Network:      "testing",
+	Version:      12,
+	BundleGitTag: "v12.0.0",
+	ManifestCid:  MustParseCid("bafy2bzaceaaxd6ytavsek5bi5soqo7qamezuqfyfjy42es2clpbzu3pwzcmye"),
+	Actors: map[string]cid.Cid{
+		"account":          MustParseCid("bafk2bzacea74qqkfvacykmq5emzqblh4f4nmxdkiyixxpzs7kkcfnbfa7cb6m"),
+		"cron":             MustParseCid("bafk2bzacecotbu7k6awdzfzakf7g5iaas6gswtunjnnb2xm2klqoshjgb4imy"),
+		"datacap":          MustParseCid("bafk2bzaceduhmqcyailiwdupt2ottfzh5hcrjoyeyiaipf3idk3mu7y3uz2mc"),
+		"eam":              MustParseCid("bafk2bzaceb2yzzw6dcmcmhnt3mqnm4kah66f23pc4escnto3vwa552t6ctr7i"),
+		"ethaccount":       MustParseCid("bafk2bzacebwkvvbmttkcjjlicp4ineozc52i5sc6d46pcoq6lzzs2p5i2youa"),
+		"evm":              MustParseCid("bafk2bzacedetwacs6wmoksxwjlbpp4442uav7fd3pagadejm2cph7ucym7eck"),
+		"init":             MustParseCid("bafk2bzacedhpoycn4sz7dragmbo5yqjspqriydxhplqdeguaqck2hmq5hgwqg"),
+		"multisig":         MustParseCid("bafk2bzaceacc3m23yvnpzoeekstqtr2acutfv4zvsgncorjdrsucymjohzxs4"),
+		"paymentchannel":   MustParseCid("bafk2bzaceac6i76vfexefqf6qgebkhkf2cb4g664d5nmfh2dric5spgykevd2"),
+		"placeholder":      MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"),
+		"reward":           MustParseCid("bafk2bzaceaajyncjxcrl7wbb6ukzkueyqz4uyekxpmtn4mpndkf7ksmggopzq"),
+		"storagemarket":    MustParseCid("bafk2bzaced6cexdcinwjhtfvuxgkxukiejp3goylaxtvhqfd24rs5z7g2z7dm"),
+		"storageminer":     MustParseCid("bafk2bzacecvkbsjhufq2zr2dojohukdnql3gkqzdkmtp2hxvn5kczxp3tu6ko"),
+		"storagepower":     MustParseCid("bafk2bzacedexrf5qplrrl5xzijfrthjdqwodfs5e6zj5kpztc7qnywbqdyiii"),
+		"system":           MustParseCid("bafk2bzacecp4roanbxq3bflftlkipsoqqxio5etjjnzxus5pcu7lq43fnxb34"),
+		"verifiedregistry": MustParseCid("bafk2bzaceandytrgcnuvizfi47sijbqh6c243vjtzlzumexm6kjv7s7hye45g"),
+	},
 }, {
 	Network: "testing-fake-proofs",
 	Version: 8,
@@ -602,10 +740,10 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
 		"verifiedregistry": MustParseCid("bafk2bzacecdmek2htsgcyoyl35glakyab66cojqo2y335njnm7krleb6yfbps"),
 	},
 }, {
-	Network:      "testing-fake-proofs",
-	Version:      11,
-	BundleGitTag: "v11.0.0",
-	ManifestCid:  MustParseCid("bafy2bzacecojemqglhzzhjnhgtrcbsgkyv67ziytvtbhwlr4ym4oxqofv7zui"),
+	Network: "testing-fake-proofs",
+	Version: 11,
+
+	ManifestCid: MustParseCid("bafy2bzacecojemqglhzzhjnhgtrcbsgkyv67ziytvtbhwlr4ym4oxqofv7zui"),
 	Actors: map[string]cid.Cid{
 		"account":          MustParseCid("bafk2bzaceccerssb3tgel6ukdghlwvs7dxsolj4fpkgn7dh7owzwapqb6ejpw"),
 		"cron":             MustParseCid("bafk2bzacebtfl6fczxnitrqqjhyefskf3asyn3gzuvqcddieoqfsaddk5fd4q"),
@@ -624,4 +762,27 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
 		"system":           MustParseCid("bafk2bzaceaatvscbnkv36ixhtt2zel4er5oskxevgumh5gegqkv7uzah36f24"),
 		"verifiedregistry": MustParseCid("bafk2bzacebp2r56wxadvfzpfbmqwfi3dlnwpmoc5u4tau2hfftbkuafkhye64"),
 	},
+}, {
+	Network:      "testing-fake-proofs",
+	Version:      12,
+	BundleGitTag: "v12.0.0",
+	ManifestCid:  MustParseCid("bafy2bzacecver4l5d6jiuzubhrtcxjjfdx6jnxbmyp4bselol2atgkhz3e3um"),
+	Actors: map[string]cid.Cid{
+		"account":          MustParseCid("bafk2bzacea74qqkfvacykmq5emzqblh4f4nmxdkiyixxpzs7kkcfnbfa7cb6m"),
+		"cron":             MustParseCid("bafk2bzacecotbu7k6awdzfzakf7g5iaas6gswtunjnnb2xm2klqoshjgb4imy"),
+		"datacap":          MustParseCid("bafk2bzaceduhmqcyailiwdupt2ottfzh5hcrjoyeyiaipf3idk3mu7y3uz2mc"),
+		"eam":              MustParseCid("bafk2bzaceb2yzzw6dcmcmhnt3mqnm4kah66f23pc4escnto3vwa552t6ctr7i"),
+		"ethaccount":       MustParseCid("bafk2bzacebwkvvbmttkcjjlicp4ineozc52i5sc6d46pcoq6lzzs2p5i2youa"),
+		"evm":              MustParseCid("bafk2bzacedetwacs6wmoksxwjlbpp4442uav7fd3pagadejm2cph7ucym7eck"),
+		"init":             MustParseCid("bafk2bzacedhpoycn4sz7dragmbo5yqjspqriydxhplqdeguaqck2hmq5hgwqg"),
+		"multisig":         MustParseCid("bafk2bzaceacc3m23yvnpzoeekstqtr2acutfv4zvsgncorjdrsucymjohzxs4"),
+		"paymentchannel":   MustParseCid("bafk2bzaceac6i76vfexefqf6qgebkhkf2cb4g664d5nmfh2dric5spgykevd2"),
+		"placeholder":      MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"),
+		"reward":           MustParseCid("bafk2bzaceaajyncjxcrl7wbb6ukzkueyqz4uyekxpmtn4mpndkf7ksmggopzq"),
+		"storagemarket":    MustParseCid("bafk2bzaced6cexdcinwjhtfvuxgkxukiejp3goylaxtvhqfd24rs5z7g2z7dm"),
+		"storageminer":     MustParseCid("bafk2bzacedapzgrbc2rsmuqex76ftt2b62q6opi56gh2dr2oyyzuwin62rweg"),
+		"storagepower":     MustParseCid("bafk2bzacecdwijcbbryinjtm27pdinqqkyzoskri24pwsvsadwcq2alkkjpnc"),
+		"system":           MustParseCid("bafk2bzacecp4roanbxq3bflftlkipsoqqxio5etjjnzxus5pcu7lq43fnxb34"),
+		"verifiedregistry": MustParseCid("bafk2bzaceandytrgcnuvizfi47sijbqh6c243vjtzlzumexm6kjv7s7hye45g"),
+	},
 }}
diff --git a/build/genesis/butterflynet.car b/build/genesis/butterflynet.car
index 30ec609ecb4..1ba3a8a1be3 100644
Binary files a/build/genesis/butterflynet.car and b/build/genesis/butterflynet.car differ
diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz
index 609047aae58..f66f0d586de 100644
Binary files a/build/openrpc/full.json.gz and b/build/openrpc/full.json.gz differ
diff --git a/build/openrpc/gateway.json.gz b/build/openrpc/gateway.json.gz
index 6ea54c394bd..68b9752e036 100644
Binary files a/build/openrpc/gateway.json.gz and b/build/openrpc/gateway.json.gz differ
diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz
index 8068f521a57..ec6b20dd2db 100644
Binary files a/build/openrpc/miner.json.gz and b/build/openrpc/miner.json.gz differ
diff --git a/build/openrpc/worker.json.gz b/build/openrpc/worker.json.gz
index 5e3bac1886a..009fa01fd7e 100644
Binary files a/build/openrpc/worker.json.gz and b/build/openrpc/worker.json.gz differ
diff --git a/build/params_2k.go b/build/params_2k.go
index c3199e2d63a..901706d9705 100644
--- a/build/params_2k.go
+++ b/build/params_2k.go
@@ -23,7 +23,7 @@ var NetworkBundle = "devnet"
 var BundleOverrides map[actorstypes.Version]string
 var ActorDebugging = true
 
-const GenesisNetworkVersion = network.Version18
+const GenesisNetworkVersion = network.Version20
 
 var UpgradeBreezeHeight = abi.ChainEpoch(-1)
 
@@ -61,9 +61,17 @@ var UpgradeSharkHeight = abi.ChainEpoch(-20)
 
 var UpgradeHyggeHeight = abi.ChainEpoch(-21)
 
-var UpgradeLightningHeight = abi.ChainEpoch(30)
+var UpgradeLightningHeight = abi.ChainEpoch(-22)
 
-var UpgradeThunderHeight = abi.ChainEpoch(1000)
+var UpgradeThunderHeight = abi.ChainEpoch(-23)
+
+var UpgradeWatermelonHeight = abi.ChainEpoch(200)
+
+// This fix upgrade only ran on calibrationnet
+const UpgradeWatermelonFixHeight = -100
+
+// This fix upgrade only ran on calibrationnet
+const UpgradeWatermelonFix2Height = -101
 
 var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
 	0: DrandMainnet,
@@ -120,6 +128,7 @@ func init() {
 	UpgradeHyggeHeight = getUpgradeHeight("LOTUS_HYGGE_HEIGHT", UpgradeHyggeHeight)
 	UpgradeLightningHeight = getUpgradeHeight("LOTUS_LIGHTNING_HEIGHT", UpgradeLightningHeight)
 	UpgradeThunderHeight = getUpgradeHeight("LOTUS_THUNDER_HEIGHT", UpgradeThunderHeight)
+	UpgradeWatermelonHeight = getUpgradeHeight("LOTUS_WATERMELON_HEIGHT", UpgradeWatermelonHeight)
 
 	BuildType |= Build2k
 
diff --git a/build/params_butterfly.go b/build/params_butterfly.go
index e26fb4ad194..26e716dab37 100644
--- a/build/params_butterfly.go
+++ b/build/params_butterfly.go
@@ -19,7 +19,7 @@ var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
 	0: DrandMainnet,
 }
 
-const GenesisNetworkVersion = network.Version18
+const GenesisNetworkVersion = network.Version20
 
 var NetworkBundle = "butterflynet"
 var BundleOverrides map[actorstypes.Version]string
@@ -52,10 +52,16 @@ const UpgradeOhSnapHeight = -18
 const UpgradeSkyrHeight = -19
 const UpgradeSharkHeight = -20
 const UpgradeHyggeHeight = -21
+const UpgradeLightningHeight = -22
+const UpgradeThunderHeight = -23
 
-const UpgradeLightningHeight = 50
+const UpgradeWatermelonHeight = 400
 
-const UpgradeThunderHeight = UpgradeLightningHeight + 360
+// This fix upgrade only ran on calibrationnet
+const UpgradeWatermelonFixHeight = -100
+
+// This fix upgrade only ran on calibrationnet
+const UpgradeWatermelonFix2Height = -101
 
 var SupportedProofTypes = []abi.RegisteredSealProof{
 	abi.RegisteredSealProof_StackedDrg512MiBV1,
diff --git a/build/params_calibnet.go b/build/params_calibnet.go
index e8b1c9d7ebd..d242fd677b1 100644
--- a/build/params_calibnet.go
+++ b/build/params_calibnet.go
@@ -79,6 +79,15 @@ const UpgradeLightningHeight = 489094
 // 2023-04-21T16:00:00Z
 const UpgradeThunderHeight = UpgradeLightningHeight + 3120
 
+// 2023-10-19T13:00:00Z
+const UpgradeWatermelonHeight = 1013134
+
+// 2023-11-07T13:00:00Z
+const UpgradeWatermelonFixHeight = 1070494
+
+// 2023-11-21T13:00:00Z
+const UpgradeWatermelonFix2Height = 1108174
+
 var SupportedProofTypes = []abi.RegisteredSealProof{
 	abi.RegisteredSealProof_StackedDrg32GiBV1,
 	abi.RegisteredSealProof_StackedDrg64GiBV1,
diff --git a/build/params_interop.go b/build/params_interop.go
index 04fc777f50f..da8029fe612 100644
--- a/build/params_interop.go
+++ b/build/params_interop.go
@@ -52,8 +52,15 @@ var UpgradeSkyrHeight = abi.ChainEpoch(-19)
 var UpgradeSharkHeight = abi.ChainEpoch(-20)
 var UpgradeHyggeHeight = abi.ChainEpoch(-21)
 var UpgradeLightningHeight = abi.ChainEpoch(-22)
+var UpgradeThunderHeight = abi.ChainEpoch(-23)
 
-const UpgradeThunderHeight = 50
+const UpgradeWatermelonHeight = 50
+
+// This fix upgrade only ran on calibrationnet
+const UpgradeWatermelonFixHeight = -1
+
+// This fix upgrade only ran on calibrationnet
+const UpgradeWatermelonFix2Height = -2
 
 var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
 	0: DrandMainnet,
diff --git a/build/params_mainnet.go b/build/params_mainnet.go
index 53eeb209167..6c6059693a8 100644
--- a/build/params_mainnet.go
+++ b/build/params_mainnet.go
@@ -90,10 +90,19 @@ const UpgradeSharkHeight = 2383680
 const UpgradeHyggeHeight = 2683348
 
 // 2023-04-27T13:00:00Z
-var UpgradeLightningHeight = abi.ChainEpoch(2809800)
+const UpgradeLightningHeight = 2809800
 
 // 2023-05-18T13:00:00Z
-var UpgradeThunderHeight = UpgradeLightningHeight + 2880*21
+const UpgradeThunderHeight = UpgradeLightningHeight + 2880*21
+
+// 2023-12-12T13:30:00Z
+var UpgradeWatermelonHeight = abi.ChainEpoch(3469380)
+
+// This fix upgrade only ran on calibrationnet
+const UpgradeWatermelonFixHeight = -1
+
+// This fix upgrade only ran on calibrationnet
+const UpgradeWatermelonFix2Height = -2
 
 var SupportedProofTypes = []abi.RegisteredSealProof{
 	abi.RegisteredSealProof_StackedDrg32GiBV1,
@@ -108,12 +117,8 @@ func init() {
 		SetAddressNetwork(address.Mainnet)
 	}
 
-	if os.Getenv("LOTUS_DISABLE_LIGHTNING") == "1" {
-		UpgradeLightningHeight = math.MaxInt64
-	}
-
-	if os.Getenv("LOTUS_DISABLE_THUNDER") == "1" {
-		UpgradeThunderHeight = math.MaxInt64
+	if os.Getenv("LOTUS_DISABLE_WATERMELON") == "1" {
+		UpgradeWatermelonHeight = math.MaxInt64
 	}
 
 	// NOTE: DO NOT change this unless you REALLY know what you're doing. This is not consensus critical, however,
diff --git a/build/params_shared_vals.go b/build/params_shared_vals.go
index dd7386863a6..1d15c2fe8b6 100644
--- a/build/params_shared_vals.go
+++ b/build/params_shared_vals.go
@@ -30,7 +30,7 @@ const AllowableClockDriftSecs = uint64(1)
 /* inline-gen template
 const TestNetworkVersion = network.Version{{.latestNetworkVersion}}
 /* inline-gen start */
-const TestNetworkVersion = network.Version20
+const TestNetworkVersion = network.Version21
 
 /* inline-gen end */
 
diff --git a/build/params_testground.go b/build/params_testground.go
index 278edd40b64..c7ad6381e5f 100644
--- a/build/params_testground.go
+++ b/build/params_testground.go
@@ -87,28 +87,31 @@ var (
 	UpgradeBreezeHeight      abi.ChainEpoch = -1
 	BreezeGasTampingDuration abi.ChainEpoch = 0
 
-	UpgradeSmokeHeight      abi.ChainEpoch = -1
-	UpgradeIgnitionHeight   abi.ChainEpoch = -2
-	UpgradeRefuelHeight     abi.ChainEpoch = -3
-	UpgradeTapeHeight       abi.ChainEpoch = -4
-	UpgradeAssemblyHeight   abi.ChainEpoch = 10
-	UpgradeLiftoffHeight    abi.ChainEpoch = -5
-	UpgradeKumquatHeight    abi.ChainEpoch = -6
-	UpgradeCalicoHeight     abi.ChainEpoch = -8
-	UpgradePersianHeight    abi.ChainEpoch = -9
-	UpgradeOrangeHeight     abi.ChainEpoch = -10
-	UpgradeClausHeight      abi.ChainEpoch = -11
-	UpgradeTrustHeight      abi.ChainEpoch = -12
-	UpgradeNorwegianHeight  abi.ChainEpoch = -13
-	UpgradeTurboHeight      abi.ChainEpoch = -14
-	UpgradeHyperdriveHeight abi.ChainEpoch = -15
-	UpgradeChocolateHeight  abi.ChainEpoch = -16
-	UpgradeOhSnapHeight     abi.ChainEpoch = -17
-	UpgradeSkyrHeight       abi.ChainEpoch = -18
-	UpgradeSharkHeight      abi.ChainEpoch = -19
-	UpgradeHyggeHeight      abi.ChainEpoch = -20
-	UpgradeLightningHeight  abi.ChainEpoch = -21
-	UpgradeThunderHeight    abi.ChainEpoch = -22
+	UpgradeSmokeHeight          abi.ChainEpoch = -1
+	UpgradeIgnitionHeight       abi.ChainEpoch = -2
+	UpgradeRefuelHeight         abi.ChainEpoch = -3
+	UpgradeTapeHeight           abi.ChainEpoch = -4
+	UpgradeAssemblyHeight       abi.ChainEpoch = 10
+	UpgradeLiftoffHeight        abi.ChainEpoch = -5
+	UpgradeKumquatHeight        abi.ChainEpoch = -6
+	UpgradeCalicoHeight         abi.ChainEpoch = -8
+	UpgradePersianHeight        abi.ChainEpoch = -9
+	UpgradeOrangeHeight         abi.ChainEpoch = -10
+	UpgradeClausHeight          abi.ChainEpoch = -11
+	UpgradeTrustHeight          abi.ChainEpoch = -12
+	UpgradeNorwegianHeight      abi.ChainEpoch = -13
+	UpgradeTurboHeight          abi.ChainEpoch = -14
+	UpgradeHyperdriveHeight     abi.ChainEpoch = -15
+	UpgradeChocolateHeight      abi.ChainEpoch = -16
+	UpgradeOhSnapHeight         abi.ChainEpoch = -17
+	UpgradeSkyrHeight           abi.ChainEpoch = -18
+	UpgradeSharkHeight          abi.ChainEpoch = -19
+	UpgradeHyggeHeight          abi.ChainEpoch = -20
+	UpgradeLightningHeight      abi.ChainEpoch = -21
+	UpgradeThunderHeight        abi.ChainEpoch = -22
+	UpgradeWatermelonHeight     abi.ChainEpoch = -23
+	UpgradeWatermelonFixHeight  abi.ChainEpoch = -24
+	UpgradeWatermelonFix2Height abi.ChainEpoch = -25
 
 	DrandSchedule = map[abi.ChainEpoch]DrandEnum{
 		0: DrandMainnet,
diff --git a/build/version.go b/build/version.go
index ab97f7a89e6..66bca2b2b84 100644
--- a/build/version.go
+++ b/build/version.go
@@ -37,7 +37,7 @@ func BuildTypeString() string {
 }
 
 // BuildVersion is the local build version
-const BuildVersion = "1.23.3"
+const BuildVersion = "1.24.0"
 
 func UserVersion() string {
 	if os.Getenv("LOTUS_VERSION_IGNORE_COMMIT") == "1" {
diff --git a/chain/actors/builtin/account/account.go b/chain/actors/builtin/account/account.go
index a29248d5644..dcb60f80186 100644
--- a/chain/actors/builtin/account/account.go
+++ b/chain/actors/builtin/account/account.go
@@ -6,7 +6,7 @@ import (
 
 	"github.com/filecoin-project/go-address"
 	actorstypes "github.com/filecoin-project/go-state-types/actors"
-	builtin11 "github.com/filecoin-project/go-state-types/builtin"
+	builtin12 "github.com/filecoin-project/go-state-types/builtin"
 	"github.com/filecoin-project/go-state-types/cbor"
 	"github.com/filecoin-project/go-state-types/manifest"
 	builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
@@ -22,7 +22,7 @@ import (
 	"github.com/filecoin-project/lotus/chain/types"
 )
 
-var Methods = builtin11.MethodsAccount
+var Methods = builtin12.MethodsAccount
 
 func Load(store adt.Store, act *types.Actor) (State, error) {
 	if name, av, ok := actors.GetActorMetaByCode(act.Code); ok {
@@ -44,6 +44,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) {
 		case actorstypes.Version11:
 			return load11(store, act.Head)
 
+		case actorstypes.Version12:
+			return load12(store, act.Head)
+
 		}
 	}
 
@@ -111,6 +114,9 @@ func MakeState(store adt.Store, av actorstypes.Version, addr address.Address) (S
 	case actorstypes.Version11:
 		return make11(store, addr)
 
+	case actorstypes.Version12:
+		return make12(store, addr)
+
 	}
 	return nil, xerrors.Errorf("unknown actor version %d", av)
 }
@@ -139,5 +145,6 @@ func AllCodes() []cid.Cid {
 		(&state9{}).Code(),
 		(&state10{}).Code(),
 		(&state11{}).Code(),
+		(&state12{}).Code(),
 	}
 }
diff --git a/chain/actors/builtin/account/v12.go b/chain/actors/builtin/account/v12.go
new file mode 100644
index 00000000000..af2c4186fbd
--- /dev/null
+++ b/chain/actors/builtin/account/v12.go
@@ -0,0 +1,62 @@
+package account
+
+import (
+	"fmt"
+
+	"github.com/ipfs/go-cid"
+
+	"github.com/filecoin-project/go-address"
+	actorstypes "github.com/filecoin-project/go-state-types/actors"
+	account12 "github.com/filecoin-project/go-state-types/builtin/v12/account"
+	"github.com/filecoin-project/go-state-types/manifest"
+
+	"github.com/filecoin-project/lotus/chain/actors"
+	"github.com/filecoin-project/lotus/chain/actors/adt"
+)
+
+var _ State = (*state12)(nil)
+
+func load12(store adt.Store, root cid.Cid) (State, error) {
+	out := state12{store: store}
+	err := store.Get(store.Context(), root, &out)
+	if err != nil {
+		return nil, err
+	}
+	return &out, nil
+}
+
+func make12(store adt.Store, addr address.Address) (State, error) {
+	out := state12{store: store}
+	out.State = account12.State{Address: addr}
+	return &out, nil
+}
+
+type state12 struct {
+	account12.State
+	store adt.Store
+}
+
+func (s *state12) PubkeyAddress() (address.Address, error) {
+	return s.Address, nil
+}
+
+func (s *state12) GetState() interface{} {
+	return &s.State
+}
+
+func (s *state12) ActorKey() string {
+	return manifest.AccountKey
+}
+
+func (s *state12) ActorVersion() actorstypes.Version {
+	return actorstypes.Version12
+}
+
+func (s *state12) Code() cid.Cid {
+	code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey())
+	if !ok {
+		panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion()))
+	}
+
+	return code
+}
diff --git a/chain/actors/builtin/builtin.go b/chain/actors/builtin/builtin.go
index 414a11e72e2..4516683a85c 100644
--- a/chain/actors/builtin/builtin.go
+++ b/chain/actors/builtin/builtin.go
@@ -23,6 +23,7 @@ import (
 	"github.com/filecoin-project/lotus/chain/actors"
 )
 
+var InitActorAddr = builtin.InitActorAddr
 var SystemActorAddr = builtin.SystemActorAddr
 var BurntFundsActorAddr = builtin.BurntFundsActorAddr
 var CronActorAddr = builtin.CronActorAddr
diff --git a/chain/actors/builtin/builtin.go.template b/chain/actors/builtin/builtin.go.template
index 3b737c47e29..3d08a12bfbd 100644
--- a/chain/actors/builtin/builtin.go.template
+++ b/chain/actors/builtin/builtin.go.template
@@ -23,6 +23,7 @@ import (
 	smoothingtypes "github.com/filecoin-project/go-state-types/builtin/v8/util/smoothing"
 )
 
+var InitActorAddr = builtin.InitActorAddr
 var SystemActorAddr = builtin.SystemActorAddr
 var BurntFundsActorAddr = builtin.BurntFundsActorAddr
 var CronActorAddr = builtin.CronActorAddr
diff --git a/chain/actors/builtin/cron/cron.go b/chain/actors/builtin/cron/cron.go
index c2f75869823..17b29178816 100644
--- a/chain/actors/builtin/cron/cron.go
+++ b/chain/actors/builtin/cron/cron.go
@@ -5,7 +5,7 @@ import (
 	"golang.org/x/xerrors"
 
 	actorstypes "github.com/filecoin-project/go-state-types/actors"
-	builtin11 "github.com/filecoin-project/go-state-types/builtin"
+	builtin12 "github.com/filecoin-project/go-state-types/builtin"
 	"github.com/filecoin-project/go-state-types/manifest"
 	builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
 	builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
@@ -40,6 +40,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) {
 		case actorstypes.Version11:
 			return load11(store, act.Head)
 
+		case actorstypes.Version12:
+			return load12(store, act.Head)
+
 		}
 	}
 
@@ -107,13 +110,16 @@ func MakeState(store adt.Store, av actorstypes.Version) (State, error) {
 	case actorstypes.Version11:
 		return make11(store)
 
+	case actorstypes.Version12:
+		return make12(store)
+
 	}
 	return nil, xerrors.Errorf("unknown actor version %d", av)
 }
 
 var (
-	Address = builtin11.CronActorAddr
-	Methods = builtin11.MethodsCron
+	Address = builtin12.CronActorAddr
+	Methods = builtin12.MethodsCron
 )
 
 type State interface {
@@ -137,5 +143,6 @@ func AllCodes() []cid.Cid {
 		(&state9{}).Code(),
 		(&state10{}).Code(),
 		(&state11{}).Code(),
+		(&state12{}).Code(),
 	}
 }
diff --git a/chain/actors/builtin/cron/v12.go b/chain/actors/builtin/cron/v12.go
new file mode 100644
index 00000000000..44f018d68af
--- /dev/null
+++ b/chain/actors/builtin/cron/v12.go
@@ -0,0 +1,57 @@
+package cron
+
+import (
+	"fmt"
+
+	"github.com/ipfs/go-cid"
+
+	actorstypes "github.com/filecoin-project/go-state-types/actors"
+	cron12 "github.com/filecoin-project/go-state-types/builtin/v12/cron"
+	"github.com/filecoin-project/go-state-types/manifest"
+
+	"github.com/filecoin-project/lotus/chain/actors"
+	"github.com/filecoin-project/lotus/chain/actors/adt"
+)
+
+var _ State = (*state12)(nil)
+
+func load12(store adt.Store, root cid.Cid) (State, error) {
+	out := state12{store: store}
+	err := store.Get(store.Context(), root, &out)
+	if err != nil {
+		return nil, err
+	}
+	return &out, nil
+}
+
+func make12(store adt.Store) (State, error) {
+	out := state12{store: store}
+	out.State = *cron12.ConstructState(cron12.BuiltInEntries())
+	return &out, nil
+}
+
+type state12 struct {
+	cron12.State
+	store adt.Store
+}
+
+func (s *state12) GetState() interface{} {
+	return &s.State
+}
+
+func (s *state12) ActorKey() string {
+	return manifest.CronKey
+}
+
+func (s *state12) ActorVersion() actorstypes.Version {
+	return actorstypes.Version12
+}
+
+func (s *state12) Code() cid.Cid {
+	code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey())
+	if !ok {
+		panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion()))
+	}
+
+	return code
+}
diff --git a/chain/actors/builtin/datacap/datacap.go b/chain/actors/builtin/datacap/datacap.go
index 3cf557e6c25..0c8f04bbf40 100644
--- a/chain/actors/builtin/datacap/datacap.go
+++ b/chain/actors/builtin/datacap/datacap.go
@@ -7,7 +7,7 @@ import (
 	"github.com/filecoin-project/go-address"
 	"github.com/filecoin-project/go-state-types/abi"
 	actorstypes "github.com/filecoin-project/go-state-types/actors"
-	builtin11 "github.com/filecoin-project/go-state-types/builtin"
+	builtin12 "github.com/filecoin-project/go-state-types/builtin"
 	"github.com/filecoin-project/go-state-types/cbor"
 	"github.com/filecoin-project/go-state-types/manifest"
 
@@ -17,8 +17,8 @@ import (
 )
 
 var (
-	Address = builtin11.DatacapActorAddr
-	Methods = builtin11.MethodsDatacap
+	Address = builtin12.DatacapActorAddr
+	Methods = builtin12.MethodsDatacap
 )
 
 func Load(store adt.Store, act *types.Actor) (State, error) {
@@ -38,6 +38,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) {
 		case actorstypes.Version11:
 			return load11(store, act.Head)
 
+		case actorstypes.Version12:
+			return load12(store, act.Head)
+
 		}
 	}
 
@@ -56,6 +59,9 @@ func MakeState(store adt.Store, av actorstypes.Version, governor address.Address
 	case actorstypes.Version11:
 		return make11(store, governor, bitwidth)
 
+	case actorstypes.Version12:
+		return make12(store, governor, bitwidth)
+
 	default:
 		return nil, xerrors.Errorf("datacap actor only valid for actors v9 and above, got %d", av)
 	}
@@ -79,5 +85,6 @@ func AllCodes() []cid.Cid {
 		(&state9{}).Code(),
 		(&state10{}).Code(),
 		(&state11{}).Code(),
+		(&state12{}).Code(),
 	}
 }
diff --git a/chain/actors/builtin/datacap/v12.go b/chain/actors/builtin/datacap/v12.go
new file mode 100644
index 00000000000..91563a2b69d
--- /dev/null
+++ b/chain/actors/builtin/datacap/v12.go
@@ -0,0 +1,82 @@
+package datacap
+
+import (
+	"fmt"
+
+	"github.com/ipfs/go-cid"
+
+	"github.com/filecoin-project/go-address"
+	"github.com/filecoin-project/go-state-types/abi"
+	actorstypes "github.com/filecoin-project/go-state-types/actors"
+	datacap12 "github.com/filecoin-project/go-state-types/builtin/v12/datacap"
+	adt12 "github.com/filecoin-project/go-state-types/builtin/v12/util/adt"
+	"github.com/filecoin-project/go-state-types/manifest"
+
+	"github.com/filecoin-project/lotus/chain/actors"
+	"github.com/filecoin-project/lotus/chain/actors/adt"
+)
+
+var _ State = (*state12)(nil)
+
+func load12(store adt.Store, root cid.Cid) (State, error) {
+	out := state12{store: store}
+	err := store.Get(store.Context(), root, &out)
+	if err != nil {
+		return nil, err
+	}
+	return &out, nil
+}
+
+func make12(store adt.Store, governor address.Address, bitwidth uint64) (State, error) {
+	out := state12{store: store}
+	s, err := datacap12.ConstructState(store, governor, bitwidth)
+	if err != nil {
+		return nil, err
+	}
+
+	out.State = *s
+
+	return &out, nil
+}
+
+type state12 struct {
+	datacap12.State
+	store adt.Store
+}
+
+func (s *state12) Governor() (address.Address, error) {
+	return s.State.Governor, nil
+}
+
+func (s *state12) GetState() interface{} {
+	return &s.State
+}
+
+func (s *state12) ForEachClient(cb func(addr address.Address, dcap abi.StoragePower) error) error {
+	return forEachClient(s.store, actors.Version12, s.verifiedClients, cb)
+}
+
+func (s *state12) verifiedClients() (adt.Map, error) {
+	return adt12.AsMap(s.store, s.Token.Balances, int(s.Token.HamtBitWidth))
+}
+
+func (s *state12) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) {
+	return getDataCap(s.store, actors.Version12, s.verifiedClients, addr)
+}
+
+func (s *state12) ActorKey() string {
+	return manifest.DatacapKey
+}
+
+func (s *state12) ActorVersion() actorstypes.Version {
+	return actorstypes.Version12
+}
+
+func (s *state12) Code() cid.Cid {
+	code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey())
+	if !ok {
+		panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion()))
+	}
+
+	return code
+}
diff --git a/chain/actors/builtin/evm/evm.go b/chain/actors/builtin/evm/evm.go
index 7c28295f253..98f860cac4a 100644
--- a/chain/actors/builtin/evm/evm.go
+++ b/chain/actors/builtin/evm/evm.go
@@ -5,7 +5,7 @@ import (
 	"golang.org/x/xerrors"
 
 	actorstypes "github.com/filecoin-project/go-state-types/actors"
-	builtin11 "github.com/filecoin-project/go-state-types/builtin"
+	builtin12 "github.com/filecoin-project/go-state-types/builtin"
 	"github.com/filecoin-project/go-state-types/cbor"
 	"github.com/filecoin-project/go-state-types/manifest"
 
@@ -14,7 +14,7 @@ import (
 	"github.com/filecoin-project/lotus/chain/types"
 )
 
-var Methods = builtin11.MethodsEVM
+var Methods = builtin12.MethodsEVM
 
 func Load(store adt.Store, act *types.Actor) (State, error) {
 	if name, av, ok := actors.GetActorMetaByCode(act.Code); ok {
@@ -30,6 +30,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) {
 		case actorstypes.Version11:
 			return load11(store, act.Head)
 
+		case actorstypes.Version12:
+			return load12(store, act.Head)
+
 		}
 	}
 
@@ -45,6 +48,9 @@ func MakeState(store adt.Store, av actorstypes.Version, bytecode cid.Cid) (State
 	case actorstypes.Version11:
 		return make11(store, bytecode)
 
+	case actorstypes.Version12:
+		return make12(store, bytecode)
+
 	default:
 		return nil, xerrors.Errorf("evm actor only valid for actors v10 and above, got %d", av)
 	}
diff --git a/chain/actors/builtin/evm/v12.go b/chain/actors/builtin/evm/v12.go
new file mode 100644
index 00000000000..a107368faa4
--- /dev/null
+++ b/chain/actors/builtin/evm/v12.go
@@ -0,0 +1,72 @@
+package evm
+
+import (
+	"github.com/ipfs/go-cid"
+
+	"github.com/filecoin-project/go-state-types/abi"
+	evm12 "github.com/filecoin-project/go-state-types/builtin/v12/evm"
+
+	"github.com/filecoin-project/lotus/chain/actors/adt"
+)
+
+var _ State = (*state12)(nil)
+
+func load12(store adt.Store, root cid.Cid) (State, error) {
+	out := state12{store: store}
+	err := store.Get(store.Context(), root, &out)
+	if err != nil {
+		return nil, err
+	}
+	return &out, nil
+}
+
+func make12(store adt.Store, bytecode cid.Cid) (State, error) {
+	out := state12{store: store}
+	s, err := evm12.ConstructState(store, bytecode)
+	if err != nil {
+		return nil, err
+	}
+
+	out.State = *s
+
+	return &out, nil
+}
+
+type state12 struct {
+	evm12.State
+	store adt.Store
+}
+
+func (s *state12) Nonce() (uint64, error) {
+	return s.State.Nonce, nil
+}
+
+func (s *state12) IsAlive() (bool, error) {
+	return s.State.Tombstone == nil, nil
+}
+
+func (s *state12) GetState() interface{} {
+	return &s.State
+}
+
+func (s *state12) GetBytecodeCID() (cid.Cid, error) {
+	return s.State.Bytecode, nil
+}
+
+func (s *state12) GetBytecodeHash() ([32]byte, error) {
+	return s.State.BytecodeHash, nil
+}
+
+func (s *state12) GetBytecode() ([]byte, error) {
+	bc, err := s.GetBytecodeCID()
+	if err != nil {
+		return nil, err
+	}
+
+	var byteCode abi.CborBytesTransparent
+	if err := s.store.Get(s.store.Context(), bc, &byteCode); err != nil {
+		return nil, err
+	}
+
+	return byteCode, nil
+}
diff --git a/chain/actors/builtin/init/init.go b/chain/actors/builtin/init/init.go
index 2d9e41275df..41a763ecf61 100644
--- a/chain/actors/builtin/init/init.go
+++ b/chain/actors/builtin/init/init.go
@@ -7,7 +7,7 @@ import (
 	"github.com/filecoin-project/go-address"
 	"github.com/filecoin-project/go-state-types/abi"
 	actorstypes "github.com/filecoin-project/go-state-types/actors"
-	builtin11 "github.com/filecoin-project/go-state-types/builtin"
+	builtin12 "github.com/filecoin-project/go-state-types/builtin"
 	"github.com/filecoin-project/go-state-types/cbor"
 	"github.com/filecoin-project/go-state-types/manifest"
 	builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
@@ -25,8 +25,8 @@ import (
 )
 
 var (
-	Address = builtin11.InitActorAddr
-	Methods = builtin11.MethodsInit
+	Address = builtin12.InitActorAddr
+	Methods = builtin12.MethodsInit
 )
 
 func Load(store adt.Store, act *types.Actor) (State, error) {
@@ -49,6 +49,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) {
 		case actorstypes.Version11:
 			return load11(store, act.Head)
 
+		case actorstypes.Version12:
+			return load12(store, act.Head)
+
 		}
 	}
 
@@ -116,6 +119,9 @@ func MakeState(store adt.Store, av actorstypes.Version, networkName string) (Sta
 	case actorstypes.Version11:
 		return make11(store, networkName)
 
+	case actorstypes.Version12:
+		return make12(store, networkName)
+
 	}
 	return nil, xerrors.Errorf("unknown actor version %d", av)
 }
@@ -167,5 +173,6 @@ func AllCodes() []cid.Cid {
 		(&state9{}).Code(),
 		(&state10{}).Code(),
 		(&state11{}).Code(),
+		(&state12{}).Code(),
 	}
 }
diff --git a/chain/actors/builtin/init/v12.go b/chain/actors/builtin/init/v12.go
new file mode 100644
index 00000000000..3eab7a74050
--- /dev/null
+++ b/chain/actors/builtin/init/v12.go
@@ -0,0 +1,147 @@
+package init
+
+import (
+	"crypto/sha256"
+	"fmt"
+
+	"github.com/ipfs/go-cid"
+	cbg "github.com/whyrusleeping/cbor-gen"
+	"golang.org/x/xerrors"
+
+	"github.com/filecoin-project/go-address"
+	"github.com/filecoin-project/go-state-types/abi"
+	actorstypes "github.com/filecoin-project/go-state-types/actors"
+	builtin12 "github.com/filecoin-project/go-state-types/builtin"
+	init12 "github.com/filecoin-project/go-state-types/builtin/v12/init"
+	adt12 "github.com/filecoin-project/go-state-types/builtin/v12/util/adt"
+	"github.com/filecoin-project/go-state-types/manifest"
+
+	"github.com/filecoin-project/lotus/chain/actors"
+	"github.com/filecoin-project/lotus/chain/actors/adt"
+	"github.com/filecoin-project/lotus/node/modules/dtypes"
+)
+
+var _ State = (*state12)(nil)
+
+func load12(store adt.Store, root cid.Cid) (State, error) {
+	out := state12{store: store}
+	err := store.Get(store.Context(), root, &out)
+	if err != nil {
+		return nil, err
+	}
+	return &out, nil
+}
+
+func make12(store adt.Store, networkName string) (State, error) {
+	out := state12{store: store}
+
+	s, err := init12.ConstructState(store, networkName)
+	if err != nil {
+		return nil, err
+	}
+
+	out.State = *s
+
+	return &out, nil
+}
+
+type state12 struct {
+	init12.State
+	store adt.Store
+}
+
+func (s *state12) ResolveAddress(address address.Address) (address.Address, bool, error) {
+	return s.State.ResolveAddress(s.store, address)
+}
+
+func (s *state12) MapAddressToNewID(address address.Address) (address.Address, error) {
+	return s.State.MapAddressToNewID(s.store, address)
+}
+
+func (s *state12) ForEachActor(cb func(id abi.ActorID, address address.Address) error) error {
+	addrs, err := adt12.AsMap(s.store, s.State.AddressMap, builtin12.DefaultHamtBitwidth)
+	if err != nil {
+		return err
+	}
+	var actorID cbg.CborInt
+	return addrs.ForEach(&actorID, func(key string) error {
+		addr, err := address.NewFromBytes([]byte(key))
+		if err != nil {
+			return err
+		}
+		return cb(abi.ActorID(actorID), addr)
+	})
+}
+
+func (s *state12) NetworkName() (dtypes.NetworkName, error) {
+	return dtypes.NetworkName(s.State.NetworkName), nil
+}
+
+func (s *state12) SetNetworkName(name string) error {
+	s.State.NetworkName = name
+	return nil
+}
+
+func (s *state12) SetNextID(id abi.ActorID) error {
+	s.State.NextID = id
+	return nil
+}
+
+func (s *state12) Remove(addrs ...address.Address) (err error) {
+	m, err := adt12.AsMap(s.store, s.State.AddressMap, builtin12.DefaultHamtBitwidth)
+	if err != nil {
+		return err
+	}
+	for _, addr := range addrs {
+		if err = m.Delete(abi.AddrKey(addr)); err != nil {
+			return xerrors.Errorf("failed to delete entry for address: %s; err: %w", addr, err)
+		}
+	}
+	amr, err := m.Root()
+	if err != nil {
+		return xerrors.Errorf("failed to get address map root: %w", err)
+	}
+	s.State.AddressMap = amr
+	return nil
+}
+
+func (s *state12) SetAddressMap(mcid cid.Cid) error {
+	s.State.AddressMap = mcid
+	return nil
+}
+
+func (s *state12) GetState() interface{} {
+	return &s.State
+}
+
+func (s *state12) AddressMap() (adt.Map, error) {
+	return adt12.AsMap(s.store, s.State.AddressMap, builtin12.DefaultHamtBitwidth)
+}
+
+func (s *state12) AddressMapBitWidth() int {
+	return builtin12.DefaultHamtBitwidth
+}
+
+func (s *state12) AddressMapHashFunction() func(input []byte) []byte {
+	return func(input []byte) []byte {
+		res := sha256.Sum256(input)
+		return res[:]
+	}
+}
+
+func (s *state12) ActorKey() string {
+	return manifest.InitKey
+}
+
+func (s *state12) ActorVersion() actorstypes.Version {
+	return actorstypes.Version12
+}
+
+func (s *state12) Code() cid.Cid {
+	code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey())
+	if !ok {
+		panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion()))
+	}
+
+	return code
+}
diff --git a/chain/actors/builtin/market/market.go b/chain/actors/builtin/market/market.go
index 36936e787c5..39473d56062 100644
--- a/chain/actors/builtin/market/market.go
+++ b/chain/actors/builtin/market/market.go
@@ -55,6 +55,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) {
 		case actorstypes.Version11:
 			return load11(store, act.Head)
 
+		case actorstypes.Version12:
+			return load12(store, act.Head)
+
 		}
 	}
 
@@ -122,6 +125,9 @@ func MakeState(store adt.Store, av actorstypes.Version) (State, error) {
 	case actorstypes.Version11:
 		return make11(store)
 
+	case actorstypes.Version12:
+		return make12(store)
+
 	}
 	return nil, xerrors.Errorf("unknown actor version %d", av)
 }
@@ -217,6 +223,9 @@ func DecodePublishStorageDealsReturn(b []byte, nv network.Version) (PublishStora
 	case actorstypes.Version11:
 		return decodePublishStorageDealsReturn11(b)
 
+	case actorstypes.Version12:
+		return decodePublishStorageDealsReturn12(b)
+
 	}
 	return nil, xerrors.Errorf("unknown actor version %d", av)
 }
@@ -303,5 +312,6 @@ func AllCodes() []cid.Cid {
 		(&state9{}).Code(),
 		(&state10{}).Code(),
 		(&state11{}).Code(),
+		(&state12{}).Code(),
 	}
 }
diff --git a/chain/actors/builtin/market/state.go.template b/chain/actors/builtin/market/state.go.template
index bbaa5c775fa..1eab9d74335 100644
--- a/chain/actors/builtin/market/state.go.template
+++ b/chain/actors/builtin/market/state.go.template
@@ -19,7 +19,7 @@ import (
 	"github.com/filecoin-project/lotus/chain/actors/adt"
 	"github.com/filecoin-project/lotus/chain/actors"
 	"github.com/filecoin-project/lotus/chain/types"
-	verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
+	verifregtypes "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
 	"github.com/filecoin-project/go-state-types/manifest"
 
 {{if (le .v 7)}}
diff --git a/chain/actors/builtin/market/v0.go b/chain/actors/builtin/market/v0.go
index c0a628b47fc..ca6970dfaa1 100644
--- a/chain/actors/builtin/market/v0.go
+++ b/chain/actors/builtin/market/v0.go
@@ -11,13 +11,13 @@ import (
 	"github.com/filecoin-project/go-address"
 	"github.com/filecoin-project/go-state-types/abi"
 	actorstypes "github.com/filecoin-project/go-state-types/actors"
-	verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
 	"github.com/filecoin-project/go-state-types/manifest"
 	market0 "github.com/filecoin-project/specs-actors/actors/builtin/market"
 	adt0 "github.com/filecoin-project/specs-actors/actors/util/adt"
 
 	"github.com/filecoin-project/lotus/chain/actors"
 	"github.com/filecoin-project/lotus/chain/actors/adt"
+	verifregtypes "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
 	"github.com/filecoin-project/lotus/chain/types"
 )
 
diff --git a/chain/actors/builtin/market/v10.go b/chain/actors/builtin/market/v10.go
index aaa0ee0f1be..878f0d46584 100644
--- a/chain/actors/builtin/market/v10.go
+++ b/chain/actors/builtin/market/v10.go
@@ -17,11 +17,11 @@ import (
 	market10 "github.com/filecoin-project/go-state-types/builtin/v10/market"
 	adt10 "github.com/filecoin-project/go-state-types/builtin/v10/util/adt"
 	markettypes "github.com/filecoin-project/go-state-types/builtin/v9/market"
-	verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
 	"github.com/filecoin-project/go-state-types/manifest"
 
 	"github.com/filecoin-project/lotus/chain/actors"
 	"github.com/filecoin-project/lotus/chain/actors/adt"
+	verifregtypes "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
 	"github.com/filecoin-project/lotus/chain/types"
 )
 
diff --git a/chain/actors/builtin/market/v11.go b/chain/actors/builtin/market/v11.go
index a816e34092b..a6427220972 100644
--- a/chain/actors/builtin/market/v11.go
+++ b/chain/actors/builtin/market/v11.go
@@ -17,11 +17,11 @@ import (
 	market11 "github.com/filecoin-project/go-state-types/builtin/v11/market"
 	adt11 "github.com/filecoin-project/go-state-types/builtin/v11/util/adt"
 	markettypes "github.com/filecoin-project/go-state-types/builtin/v9/market"
-	verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
 	"github.com/filecoin-project/go-state-types/manifest"
 
 	"github.com/filecoin-project/lotus/chain/actors"
 	"github.com/filecoin-project/lotus/chain/actors/adt"
+	verifregtypes "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
 	"github.com/filecoin-project/lotus/chain/types"
 )
 
diff --git a/chain/actors/builtin/market/v12.go b/chain/actors/builtin/market/v12.go
new file mode 100644
index 00000000000..56e651a9be5
--- /dev/null
+++ b/chain/actors/builtin/market/v12.go
@@ -0,0 +1,377 @@
+package market
+
+import (
+	"bytes"
+	"fmt"
+
+	"github.com/ipfs/go-cid"
+	cbg "github.com/whyrusleeping/cbor-gen"
+	"golang.org/x/xerrors"
+
+	"github.com/filecoin-project/go-address"
+	"github.com/filecoin-project/go-bitfield"
+	rlepluslazy "github.com/filecoin-project/go-bitfield/rle"
+	"github.com/filecoin-project/go-state-types/abi"
+	actorstypes "github.com/filecoin-project/go-state-types/actors"
+	"github.com/filecoin-project/go-state-types/builtin"
+	market12 "github.com/filecoin-project/go-state-types/builtin/v12/market"
+	adt12 "github.com/filecoin-project/go-state-types/builtin/v12/util/adt"
+	markettypes "github.com/filecoin-project/go-state-types/builtin/v9/market"
+	"github.com/filecoin-project/go-state-types/manifest"
+
+	"github.com/filecoin-project/lotus/chain/actors"
+	"github.com/filecoin-project/lotus/chain/actors/adt"
+	verifregtypes "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
+	"github.com/filecoin-project/lotus/chain/types"
+)
+
+var _ State = (*state12)(nil)
+
+func load12(store adt.Store, root cid.Cid) (State, error) {
+	out := state12{store: store}
+	err := store.Get(store.Context(), root, &out)
+	if err != nil {
+		return nil, err
+	}
+	return &out, nil
+}
+
+func make12(store adt.Store) (State, error) {
+	out := state12{store: store}
+
+	s, err := market12.ConstructState(store)
+	if err != nil {
+		return nil, err
+	}
+
+	out.State = *s
+
+	return &out, nil
+}
+
+type state12 struct {
+	market12.State
+	store adt.Store
+}
+
+func (s *state12) TotalLocked() (abi.TokenAmount, error) {
+	fml := types.BigAdd(s.TotalClientLockedCollateral, s.TotalProviderLockedCollateral)
+	fml = types.BigAdd(fml, s.TotalClientStorageFee)
+	return fml, nil
+}
+
+func (s *state12) BalancesChanged(otherState State) (bool, error) {
+	otherState12, ok := otherState.(*state12)
+	if !ok {
+		// there's no way to compare different versions of the state, so let's
+		// just say that means the state of balances has changed
+		return true, nil
+	}
+	return !s.State.EscrowTable.Equals(otherState12.State.EscrowTable) || !s.State.LockedTable.Equals(otherState12.State.LockedTable), nil
+}
+
+func (s *state12) StatesChanged(otherState State) (bool, error) {
+	otherState12, ok := otherState.(*state12)
+	if !ok {
+		// there's no way to compare different versions of the state, so let's
+		// just say that means the state of balances has changed
+		return true, nil
+	}
+	return !s.State.States.Equals(otherState12.State.States), nil
+}
+
+func (s *state12) States() (DealStates, error) {
+	stateArray, err := adt12.AsArray(s.store, s.State.States, market12.StatesAmtBitwidth)
+	if err != nil {
+		return nil, err
+	}
+	return &dealStates12{stateArray}, nil
+}
+
+func (s *state12) ProposalsChanged(otherState State) (bool, error) {
+	otherState12, ok := otherState.(*state12)
+	if !ok {
+		// there's no way to compare different versions of the state, so let's
+		// just say that means the state of balances has changed
+		return true, nil
+	}
+	return !s.State.Proposals.Equals(otherState12.State.Proposals), nil
+}
+
+func (s *state12) Proposals() (DealProposals, error) {
+	proposalArray, err := adt12.AsArray(s.store, s.State.Proposals, market12.ProposalsAmtBitwidth)
+	if err != nil {
+		return nil, err
+	}
+	return &dealProposals12{proposalArray}, nil
+}
+
+func (s *state12) EscrowTable() (BalanceTable, error) {
+	bt, err := adt12.AsBalanceTable(s.store, s.State.EscrowTable)
+	if err != nil {
+		return nil, err
+	}
+	return &balanceTable12{bt}, nil
+}
+
+func (s *state12) LockedTable() (BalanceTable, error) {
+	bt, err := adt12.AsBalanceTable(s.store, s.State.LockedTable)
+	if err != nil {
+		return nil, err
+	}
+	return &balanceTable12{bt}, nil
+}
+
+func (s *state12) VerifyDealsForActivation(
+	minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch,
+) (weight, verifiedWeight abi.DealWeight, err error) {
+	w, vw, _, err := market12.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch)
+	return w, vw, err
+}
+
+func (s *state12) NextID() (abi.DealID, error) {
+	return s.State.NextID, nil
+}
+
+type balanceTable12 struct {
+	*adt12.BalanceTable
+}
+
+func (bt *balanceTable12) ForEach(cb func(address.Address, abi.TokenAmount) error) error {
+	asMap := (*adt12.Map)(bt.BalanceTable)
+	var ta abi.TokenAmount
+	return asMap.ForEach(&ta, func(key string) error {
+		a, err := address.NewFromBytes([]byte(key))
+		if err != nil {
+			return err
+		}
+		return cb(a, ta)
+	})
+}
+
+type dealStates12 struct {
+	adt.Array
+}
+
+func (s *dealStates12) Get(dealID abi.DealID) (*DealState, bool, error) {
+	var deal12 market12.DealState
+	found, err := s.Array.Get(uint64(dealID), &deal12)
+	if err != nil {
+		return nil, false, err
+	}
+	if !found {
+		return nil, false, nil
+	}
+	deal := fromV12DealState(deal12)
+	return &deal, true, nil
+}
+
+func (s *dealStates12) ForEach(cb func(dealID abi.DealID, ds DealState) error) error {
+	var ds12 market12.DealState
+	return s.Array.ForEach(&ds12, func(idx int64) error {
+		return cb(abi.DealID(idx), fromV12DealState(ds12))
+	})
+}
+
+func (s *dealStates12) decode(val *cbg.Deferred) (*DealState, error) {
+	var ds12 market12.DealState
+	if err := ds12.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
+		return nil, err
+	}
+	ds := fromV12DealState(ds12)
+	return &ds, nil
+}
+
+func (s *dealStates12) array() adt.Array {
+	return s.Array
+}
+
+func fromV12DealState(v12 market12.DealState) DealState {
+	ret := DealState{
+		SectorStartEpoch: v12.SectorStartEpoch,
+		LastUpdatedEpoch: v12.LastUpdatedEpoch,
+		SlashEpoch:       v12.SlashEpoch,
+		VerifiedClaim:    0,
+	}
+
+	ret.VerifiedClaim = verifregtypes.AllocationId(v12.VerifiedClaim)
+
+	return ret
+}
+
+type dealProposals12 struct {
+	adt.Array
+}
+
+func (s *dealProposals12) Get(dealID abi.DealID) (*DealProposal, bool, error) {
+	var proposal12 market12.DealProposal
+	found, err := s.Array.Get(uint64(dealID), &proposal12)
+	if err != nil {
+		return nil, false, err
+	}
+	if !found {
+		return nil, false, nil
+	}
+
+	proposal, err := fromV12DealProposal(proposal12)
+	if err != nil {
+		return nil, true, xerrors.Errorf("decoding proposal: %w", err)
+	}
+
+	return &proposal, true, nil
+}
+
+func (s *dealProposals12) ForEach(cb func(dealID abi.DealID, dp DealProposal) error) error {
+	var dp12 market12.DealProposal
+	return s.Array.ForEach(&dp12, func(idx int64) error {
+		dp, err := fromV12DealProposal(dp12)
+		if err != nil {
+			return xerrors.Errorf("decoding proposal: %w", err)
+		}
+
+		return cb(abi.DealID(idx), dp)
+	})
+}
+
+func (s *dealProposals12) decode(val *cbg.Deferred) (*DealProposal, error) {
+	var dp12 market12.DealProposal
+	if err := dp12.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
+		return nil, err
+	}
+
+	dp, err := fromV12DealProposal(dp12)
+	if err != nil {
+		return nil, err
+	}
+
+	return &dp, nil
+}
+
+func (s *dealProposals12) array() adt.Array {
+	return s.Array
+}
+
+func fromV12DealProposal(v12 market12.DealProposal) (DealProposal, error) {
+
+	label, err := fromV12Label(v12.Label)
+
+	if err != nil {
+		return DealProposal{}, xerrors.Errorf("error setting deal label: %w", err)
+	}
+
+	return DealProposal{
+		PieceCID:     v12.PieceCID,
+		PieceSize:    v12.PieceSize,
+		VerifiedDeal: v12.VerifiedDeal,
+		Client:       v12.Client,
+		Provider:     v12.Provider,
+
+		Label: label,
+
+		StartEpoch:           v12.StartEpoch,
+		EndEpoch:             v12.EndEpoch,
+		StoragePricePerEpoch: v12.StoragePricePerEpoch,
+
+		ProviderCollateral: v12.ProviderCollateral,
+		ClientCollateral:   v12.ClientCollateral,
+	}, nil
+}
+
+func fromV12Label(v12 market12.DealLabel) (DealLabel, error) {
+	if v12.IsString() {
+		str, err := v12.ToString()
+		if err != nil {
+			return markettypes.EmptyDealLabel, xerrors.Errorf("failed to convert string label to string: %w", err)
+		}
+		return markettypes.NewLabelFromString(str)
+	}
+
+	bs, err := v12.ToBytes()
+	if err != nil {
+		return markettypes.EmptyDealLabel, xerrors.Errorf("failed to convert bytes label to bytes: %w", err)
+	}
+	return markettypes.NewLabelFromBytes(bs)
+}
+
+func (s *state12) GetState() interface{} {
+	return &s.State
+}
+
+var _ PublishStorageDealsReturn = (*publishStorageDealsReturn12)(nil)
+
+func decodePublishStorageDealsReturn12(b []byte) (PublishStorageDealsReturn, error) {
+	var retval market12.PublishStorageDealsReturn
+	if err := retval.UnmarshalCBOR(bytes.NewReader(b)); err != nil {
+		return nil, xerrors.Errorf("failed to unmarshal PublishStorageDealsReturn: %w", err)
+	}
+
+	return &publishStorageDealsReturn12{retval}, nil
+}
+
+type publishStorageDealsReturn12 struct {
+	market12.PublishStorageDealsReturn
+}
+
+func (r *publishStorageDealsReturn12) IsDealValid(index uint64) (bool, int, error) {
+
+	set, err := r.ValidDeals.IsSet(index)
+	if err != nil || !set {
+		return false, -1, err
+	}
+	maskBf, err := bitfield.NewFromIter(&rlepluslazy.RunSliceIterator{
+		Runs: []rlepluslazy.Run{rlepluslazy.Run{Val: true, Len: index}}})
+	if err != nil {
+		return false, -1, err
+	}
+	before, err := bitfield.IntersectBitField(maskBf, r.ValidDeals)
+	if err != nil {
+		return false, -1, err
+	}
+	outIdx, err := before.Count()
+	if err != nil {
+		return false, -1, err
+	}
+	return set, int(outIdx), nil
+
+}
+
+func (r *publishStorageDealsReturn12) DealIDs() ([]abi.DealID, error) {
+	return r.IDs, nil
+}
+
+func (s *state12) GetAllocationIdForPendingDeal(dealId abi.DealID) (verifregtypes.AllocationId, error) {
+
+	allocations, err := adt12.AsMap(s.store, s.PendingDealAllocationIds, builtin.DefaultHamtBitwidth)
+	if err != nil {
+		return verifregtypes.NoAllocationID, xerrors.Errorf("failed to load allocation id for %d: %w", dealId, err)
+	}
+
+	var allocationId cbg.CborInt
+	found, err := allocations.Get(abi.UIntKey(uint64(dealId)), &allocationId)
+	if err != nil {
+		return verifregtypes.NoAllocationID, xerrors.Errorf("failed to load allocation id for %d: %w", dealId, err)
+	}
+	if !found {
+		return verifregtypes.NoAllocationID, nil
+	}
+
+	return verifregtypes.AllocationId(allocationId), nil
+
+}
+
+func (s *state12) ActorKey() string {
+	return manifest.MarketKey
+}
+
+func (s *state12) ActorVersion() actorstypes.Version {
+	return actorstypes.Version12
+}
+
+func (s *state12) Code() cid.Cid {
+	code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey())
+	if !ok {
+		panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion()))
+	}
+
+	return code
+}
diff --git a/chain/actors/builtin/market/v2.go b/chain/actors/builtin/market/v2.go
index 89ffdde8f55..ba84e3b03a0 100644
--- a/chain/actors/builtin/market/v2.go
+++ b/chain/actors/builtin/market/v2.go
@@ -11,13 +11,13 @@ import (
 	"github.com/filecoin-project/go-address"
 	"github.com/filecoin-project/go-state-types/abi"
 	actorstypes "github.com/filecoin-project/go-state-types/actors"
-	verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
 	"github.com/filecoin-project/go-state-types/manifest"
 	market2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/market"
 	adt2 "github.com/filecoin-project/specs-actors/v2/actors/util/adt"
 
 	"github.com/filecoin-project/lotus/chain/actors"
 	"github.com/filecoin-project/lotus/chain/actors/adt"
+	verifregtypes "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
 	"github.com/filecoin-project/lotus/chain/types"
 )
 
diff --git a/chain/actors/builtin/market/v3.go b/chain/actors/builtin/market/v3.go
index f4d073ed866..f6a0891e730 100644
--- a/chain/actors/builtin/market/v3.go
+++ b/chain/actors/builtin/market/v3.go
@@ -11,13 +11,13 @@ import (
 	"github.com/filecoin-project/go-address"
 	"github.com/filecoin-project/go-state-types/abi"
 	actorstypes "github.com/filecoin-project/go-state-types/actors"
-	verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
 	"github.com/filecoin-project/go-state-types/manifest"
 	market3 "github.com/filecoin-project/specs-actors/v3/actors/builtin/market"
 	adt3 "github.com/filecoin-project/specs-actors/v3/actors/util/adt"
 
 	"github.com/filecoin-project/lotus/chain/actors"
 	"github.com/filecoin-project/lotus/chain/actors/adt"
+	verifregtypes "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
 	"github.com/filecoin-project/lotus/chain/types"
 )
 
diff --git a/chain/actors/builtin/market/v4.go b/chain/actors/builtin/market/v4.go
index 422a30cbb12..629e833b67b 100644
--- a/chain/actors/builtin/market/v4.go
+++ b/chain/actors/builtin/market/v4.go
@@ -11,13 +11,13 @@ import (
 	"github.com/filecoin-project/go-address"
 	"github.com/filecoin-project/go-state-types/abi"
 	actorstypes "github.com/filecoin-project/go-state-types/actors"
-	verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
 	"github.com/filecoin-project/go-state-types/manifest"
 	market4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/market"
 	adt4 "github.com/filecoin-project/specs-actors/v4/actors/util/adt"
 
 	"github.com/filecoin-project/lotus/chain/actors"
 	"github.com/filecoin-project/lotus/chain/actors/adt"
+	verifregtypes "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
 	"github.com/filecoin-project/lotus/chain/types"
 )
 
diff --git a/chain/actors/builtin/market/v5.go b/chain/actors/builtin/market/v5.go
index b30decb03a2..8925889791f 100644
--- a/chain/actors/builtin/market/v5.go
+++ b/chain/actors/builtin/market/v5.go
@@ -11,13 +11,13 @@ import (
 	"github.com/filecoin-project/go-address"
 	"github.com/filecoin-project/go-state-types/abi"
 	actorstypes "github.com/filecoin-project/go-state-types/actors"
-	verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
 	"github.com/filecoin-project/go-state-types/manifest"
 	market5 "github.com/filecoin-project/specs-actors/v5/actors/builtin/market"
 	adt5 "github.com/filecoin-project/specs-actors/v5/actors/util/adt"
 
 	"github.com/filecoin-project/lotus/chain/actors"
 	"github.com/filecoin-project/lotus/chain/actors/adt"
+	verifregtypes "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
 	"github.com/filecoin-project/lotus/chain/types"
 )
 
diff --git a/chain/actors/builtin/market/v6.go b/chain/actors/builtin/market/v6.go
index 377b278ae18..b57d49f9117 100644
--- a/chain/actors/builtin/market/v6.go
+++ b/chain/actors/builtin/market/v6.go
@@ -13,13 +13,13 @@ import (
 	rlepluslazy "github.com/filecoin-project/go-bitfield/rle"
 	"github.com/filecoin-project/go-state-types/abi"
 	actorstypes "github.com/filecoin-project/go-state-types/actors"
-	verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
 	"github.com/filecoin-project/go-state-types/manifest"
 	market6 "github.com/filecoin-project/specs-actors/v6/actors/builtin/market"
 	adt6 "github.com/filecoin-project/specs-actors/v6/actors/util/adt"
 
 	"github.com/filecoin-project/lotus/chain/actors"
 	"github.com/filecoin-project/lotus/chain/actors/adt"
+	verifregtypes "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
 	"github.com/filecoin-project/lotus/chain/types"
 )
 
diff --git a/chain/actors/builtin/market/v7.go b/chain/actors/builtin/market/v7.go
index cd4607cbef7..56a1db328f9 100644
--- a/chain/actors/builtin/market/v7.go
+++ b/chain/actors/builtin/market/v7.go
@@ -13,13 +13,13 @@ import (
 	rlepluslazy "github.com/filecoin-project/go-bitfield/rle"
 	"github.com/filecoin-project/go-state-types/abi"
 	actorstypes "github.com/filecoin-project/go-state-types/actors"
-	verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
 	"github.com/filecoin-project/go-state-types/manifest"
 	market7 "github.com/filecoin-project/specs-actors/v7/actors/builtin/market"
 	adt7 "github.com/filecoin-project/specs-actors/v7/actors/util/adt"
 
 	"github.com/filecoin-project/lotus/chain/actors"
 	"github.com/filecoin-project/lotus/chain/actors/adt"
+	verifregtypes "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
 	"github.com/filecoin-project/lotus/chain/types"
 )
 
diff --git a/chain/actors/builtin/market/v8.go b/chain/actors/builtin/market/v8.go
index 5cce06d3a0a..9c68ee1fd86 100644
--- a/chain/actors/builtin/market/v8.go
+++ b/chain/actors/builtin/market/v8.go
@@ -16,11 +16,11 @@ import (
 	market8 "github.com/filecoin-project/go-state-types/builtin/v8/market"
 	adt8 "github.com/filecoin-project/go-state-types/builtin/v8/util/adt"
 	markettypes "github.com/filecoin-project/go-state-types/builtin/v9/market"
-	verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
 	"github.com/filecoin-project/go-state-types/manifest"
 
 	"github.com/filecoin-project/lotus/chain/actors"
 	"github.com/filecoin-project/lotus/chain/actors/adt"
+	verifregtypes "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
 	"github.com/filecoin-project/lotus/chain/types"
 )
 
diff --git a/chain/actors/builtin/market/v9.go b/chain/actors/builtin/market/v9.go
index 095c2085005..d692c15ccb7 100644
--- a/chain/actors/builtin/market/v9.go
+++ b/chain/actors/builtin/market/v9.go
@@ -17,11 +17,11 @@ import (
 	market9 "github.com/filecoin-project/go-state-types/builtin/v9/market"
 	markettypes "github.com/filecoin-project/go-state-types/builtin/v9/market"
 	adt9 "github.com/filecoin-project/go-state-types/builtin/v9/util/adt"
-	verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
 	"github.com/filecoin-project/go-state-types/manifest"
 
 	"github.com/filecoin-project/lotus/chain/actors"
 	"github.com/filecoin-project/lotus/chain/actors/adt"
+	verifregtypes "github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
 	"github.com/filecoin-project/lotus/chain/types"
 )
 
diff --git a/chain/actors/builtin/miner/actor.go.template b/chain/actors/builtin/miner/actor.go.template
index 7319ee9c59d..b4ad3a4b570 100644
--- a/chain/actors/builtin/miner/actor.go.template
+++ b/chain/actors/builtin/miner/actor.go.template
@@ -154,7 +154,7 @@ type Partition interface {
 
 type SectorOnChainInfo = minertypes.SectorOnChainInfo
 
-func PreferredSealProofTypeFromWindowPoStType(nver network.Version, proof abi.RegisteredPoStProof) (abi.RegisteredSealProof, error) {
+func PreferredSealProofTypeFromWindowPoStType(nver network.Version, proof abi.RegisteredPoStProof, configWantSynthetic bool) (abi.RegisteredSealProof, error) {
 	// We added support for the new proofs in network version 7, and removed support for the old
 	// ones in network version 8.
 	if nver < network.Version7 {
@@ -174,17 +174,34 @@ func PreferredSealProofTypeFromWindowPoStType(nver network.Version, proof abi.Re
 		}
 	}
 
+	if nver < MinSyntheticPoRepVersion || !configWantSynthetic {
+		switch proof {
+		case abi.RegisteredPoStProof_StackedDrgWindow2KiBV1, abi.RegisteredPoStProof_StackedDrgWindow2KiBV1_1:
+			return abi.RegisteredSealProof_StackedDrg2KiBV1_1, nil
+		case abi.RegisteredPoStProof_StackedDrgWindow8MiBV1, abi.RegisteredPoStProof_StackedDrgWindow8MiBV1_1:
+			return abi.RegisteredSealProof_StackedDrg8MiBV1_1, nil
+		case abi.RegisteredPoStProof_StackedDrgWindow512MiBV1, abi.RegisteredPoStProof_StackedDrgWindow512MiBV1_1:
+			return abi.RegisteredSealProof_StackedDrg512MiBV1_1, nil
+		case abi.RegisteredPoStProof_StackedDrgWindow32GiBV1, abi.RegisteredPoStProof_StackedDrgWindow32GiBV1_1:
+			return abi.RegisteredSealProof_StackedDrg32GiBV1_1, nil
+		case abi.RegisteredPoStProof_StackedDrgWindow64GiBV1, abi.RegisteredPoStProof_StackedDrgWindow64GiBV1_1:
+			return abi.RegisteredSealProof_StackedDrg64GiBV1_1, nil
+		default:
+			return -1, xerrors.Errorf("unrecognized window post type: %d", proof)
+		}
+	}
+
 	switch proof {
 	case abi.RegisteredPoStProof_StackedDrgWindow2KiBV1, abi.RegisteredPoStProof_StackedDrgWindow2KiBV1_1:
-		return abi.RegisteredSealProof_StackedDrg2KiBV1_1, nil
+		return abi.RegisteredSealProof_StackedDrg2KiBV1_1_Feat_SyntheticPoRep, nil
 	case abi.RegisteredPoStProof_StackedDrgWindow8MiBV1, abi.RegisteredPoStProof_StackedDrgWindow8MiBV1_1:
-		return abi.RegisteredSealProof_StackedDrg8MiBV1_1, nil
+		return abi.RegisteredSealProof_StackedDrg8MiBV1_1_Feat_SyntheticPoRep, nil
 	case abi.RegisteredPoStProof_StackedDrgWindow512MiBV1, abi.RegisteredPoStProof_StackedDrgWindow512MiBV1_1:
-		return abi.RegisteredSealProof_StackedDrg512MiBV1_1, nil
+		return abi.RegisteredSealProof_StackedDrg512MiBV1_1_Feat_SyntheticPoRep, nil
 	case abi.RegisteredPoStProof_StackedDrgWindow32GiBV1, abi.RegisteredPoStProof_StackedDrgWindow32GiBV1_1:
-		return abi.RegisteredSealProof_StackedDrg32GiBV1_1, nil
+		return abi.RegisteredSealProof_StackedDrg32GiBV1_1_Feat_SyntheticPoRep, nil
 	case abi.RegisteredPoStProof_StackedDrgWindow64GiBV1, abi.RegisteredPoStProof_StackedDrgWindow64GiBV1_1:
-		return abi.RegisteredSealProof_StackedDrg64GiBV1_1, nil
+		return abi.RegisteredSealProof_StackedDrg64GiBV1_1_Feat_SyntheticPoRep, nil
 	default:
 		return -1, xerrors.Errorf("unrecognized window post type: %d", proof)
 	}
@@ -213,8 +230,37 @@ type PendingBeneficiaryChange = minertypes.PendingBeneficiaryChange
 type WorkerKeyChange = minertypes.WorkerKeyChange
 type SectorPreCommitOnChainInfo = minertypes.SectorPreCommitOnChainInfo
 type SectorPreCommitInfo = minertypes.SectorPreCommitInfo
+type SubmitWindowedPoStParams = minertypes.SubmitWindowedPoStParams
+type PoStPartition = minertypes.PoStPartition
+type RecoveryDeclaration = minertypes.RecoveryDeclaration
+type FaultDeclaration = minertypes.FaultDeclaration
+type DeclareFaultsRecoveredParams = minertypes.DeclareFaultsRecoveredParams
+type DeclareFaultsParams = minertypes.DeclareFaultsParams
+type ProveCommitAggregateParams = minertypes.ProveCommitAggregateParams
+type ProveCommitSectorParams = minertypes.ProveCommitSectorParams
+type ProveReplicaUpdatesParams = minertypes.ProveReplicaUpdatesParams
+type ReplicaUpdate = minertypes.ReplicaUpdate
+type PreCommitSectorBatchParams = minertypes.PreCommitSectorBatchParams
+type PreCommitSectorBatchParams2 = minertypes.PreCommitSectorBatchParams2
+type ExtendSectorExpiration2Params = minertypes.ExtendSectorExpiration2Params
+type SectorClaim = minertypes.SectorClaim
+type ExpirationExtension2 = minertypes.ExpirationExtension2
+type CompactPartitionsParams = minertypes.CompactPartitionsParams
+type WithdrawBalanceParams = minertypes.WithdrawBalanceParams
+
+var QAPowerMax = minertypes.QAPowerMax
+
 type WindowPostVerifyInfo = proof.WindowPoStVerifyInfo
 
+var WPoStProvingPeriod = func() abi.ChainEpoch { return minertypes.WPoStProvingPeriod }
+var WPoStChallengeWindow = func() abi.ChainEpoch { return minertypes.WPoStChallengeWindow }
+
+const WPoStPeriodDeadlines = minertypes.WPoStPeriodDeadlines
+const WPoStChallengeLookback = minertypes.WPoStChallengeLookback
+const FaultDeclarationCutoff = minertypes.FaultDeclarationCutoff
+const MinAggregatedSectors = minertypes.MinAggregatedSectors
+const MinSectorExpiration = minertypes.MinSectorExpiration
+
 type SectorExpiration struct {
 	OnTime abi.ChainEpoch
 
diff --git a/chain/actors/builtin/miner/miner.go b/chain/actors/builtin/miner/miner.go
index 1433945d93e..1637cdadeda 100644
--- a/chain/actors/builtin/miner/miner.go
+++ b/chain/actors/builtin/miner/miner.go
@@ -48,6 +48,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) {
 		case actorstypes.Version11:
 			return load11(store, act.Head)
 
+		case actorstypes.Version12:
+			return load12(store, act.Head)
+
 		}
 	}
 
@@ -115,6 +118,9 @@ func MakeState(store adt.Store, av actors.Version) (State, error) {
 	case actors.Version11:
 		return make11(store)
 
+	case actors.Version12:
+		return make12(store)
+
 	}
 	return nil, xerrors.Errorf("unknown actor version %d", av)
 }
@@ -208,7 +214,7 @@ type Partition interface {
 
 type SectorOnChainInfo = minertypes.SectorOnChainInfo
 
-func PreferredSealProofTypeFromWindowPoStType(nver network.Version, proof abi.RegisteredPoStProof) (abi.RegisteredSealProof, error) {
+func PreferredSealProofTypeFromWindowPoStType(nver network.Version, proof abi.RegisteredPoStProof, configWantSynthetic bool) (abi.RegisteredSealProof, error) {
 	// We added support for the new proofs in network version 7, and removed support for the old
 	// ones in network version 8.
 	if nver < network.Version7 {
@@ -228,17 +234,34 @@ func PreferredSealProofTypeFromWindowPoStType(nver network.Version, proof abi.Re
 		}
 	}
 
+	if nver < MinSyntheticPoRepVersion || !configWantSynthetic {
+		switch proof {
+		case abi.RegisteredPoStProof_StackedDrgWindow2KiBV1, abi.RegisteredPoStProof_StackedDrgWindow2KiBV1_1:
+			return abi.RegisteredSealProof_StackedDrg2KiBV1_1, nil
+		case abi.RegisteredPoStProof_StackedDrgWindow8MiBV1, abi.RegisteredPoStProof_StackedDrgWindow8MiBV1_1:
+			return abi.RegisteredSealProof_StackedDrg8MiBV1_1, nil
+		case abi.RegisteredPoStProof_StackedDrgWindow512MiBV1, abi.RegisteredPoStProof_StackedDrgWindow512MiBV1_1:
+			return abi.RegisteredSealProof_StackedDrg512MiBV1_1, nil
+		case abi.RegisteredPoStProof_StackedDrgWindow32GiBV1, abi.RegisteredPoStProof_StackedDrgWindow32GiBV1_1:
+			return abi.RegisteredSealProof_StackedDrg32GiBV1_1, nil
+		case abi.RegisteredPoStProof_StackedDrgWindow64GiBV1, abi.RegisteredPoStProof_StackedDrgWindow64GiBV1_1:
+			return abi.RegisteredSealProof_StackedDrg64GiBV1_1, nil
+		default:
+			return -1, xerrors.Errorf("unrecognized window post type: %d", proof)
+		}
+	}
+
 	switch proof {
 	case abi.RegisteredPoStProof_StackedDrgWindow2KiBV1, abi.RegisteredPoStProof_StackedDrgWindow2KiBV1_1:
-		return abi.RegisteredSealProof_StackedDrg2KiBV1_1, nil
+		return abi.RegisteredSealProof_StackedDrg2KiBV1_1_Feat_SyntheticPoRep, nil
 	case abi.RegisteredPoStProof_StackedDrgWindow8MiBV1, abi.RegisteredPoStProof_StackedDrgWindow8MiBV1_1:
-		return abi.RegisteredSealProof_StackedDrg8MiBV1_1, nil
+		return abi.RegisteredSealProof_StackedDrg8MiBV1_1_Feat_SyntheticPoRep, nil
 	case abi.RegisteredPoStProof_StackedDrgWindow512MiBV1, abi.RegisteredPoStProof_StackedDrgWindow512MiBV1_1:
-		return abi.RegisteredSealProof_StackedDrg512MiBV1_1, nil
+		return abi.RegisteredSealProof_StackedDrg512MiBV1_1_Feat_SyntheticPoRep, nil
 	case abi.RegisteredPoStProof_StackedDrgWindow32GiBV1, abi.RegisteredPoStProof_StackedDrgWindow32GiBV1_1:
-		return abi.RegisteredSealProof_StackedDrg32GiBV1_1, nil
+		return abi.RegisteredSealProof_StackedDrg32GiBV1_1_Feat_SyntheticPoRep, nil
 	case abi.RegisteredPoStProof_StackedDrgWindow64GiBV1, abi.RegisteredPoStProof_StackedDrgWindow64GiBV1_1:
-		return abi.RegisteredSealProof_StackedDrg64GiBV1_1, nil
+		return abi.RegisteredSealProof_StackedDrg64GiBV1_1_Feat_SyntheticPoRep, nil
 	default:
 		return -1, xerrors.Errorf("unrecognized window post type: %d", proof)
 	}
@@ -267,8 +290,37 @@ type PendingBeneficiaryChange = minertypes.PendingBeneficiaryChange
 type WorkerKeyChange = minertypes.WorkerKeyChange
 type SectorPreCommitOnChainInfo = minertypes.SectorPreCommitOnChainInfo
 type SectorPreCommitInfo = minertypes.SectorPreCommitInfo
+type SubmitWindowedPoStParams = minertypes.SubmitWindowedPoStParams
+type PoStPartition = minertypes.PoStPartition
+type RecoveryDeclaration = minertypes.RecoveryDeclaration
+type FaultDeclaration = minertypes.FaultDeclaration
+type DeclareFaultsRecoveredParams = minertypes.DeclareFaultsRecoveredParams
+type DeclareFaultsParams = minertypes.DeclareFaultsParams
+type ProveCommitAggregateParams = minertypes.ProveCommitAggregateParams
+type ProveCommitSectorParams = minertypes.ProveCommitSectorParams
+type ProveReplicaUpdatesParams = minertypes.ProveReplicaUpdatesParams
+type ReplicaUpdate = minertypes.ReplicaUpdate
+type PreCommitSectorBatchParams = minertypes.PreCommitSectorBatchParams
+type PreCommitSectorBatchParams2 = minertypes.PreCommitSectorBatchParams2
+type ExtendSectorExpiration2Params = minertypes.ExtendSectorExpiration2Params
+type SectorClaim = minertypes.SectorClaim
+type ExpirationExtension2 = minertypes.ExpirationExtension2
+type CompactPartitionsParams = minertypes.CompactPartitionsParams
+type WithdrawBalanceParams = minertypes.WithdrawBalanceParams
+
+var QAPowerMax = minertypes.QAPowerMax
+
 type WindowPostVerifyInfo = proof.WindowPoStVerifyInfo
 
+var WPoStProvingPeriod = func() abi.ChainEpoch { return minertypes.WPoStProvingPeriod }
+var WPoStChallengeWindow = func() abi.ChainEpoch { return minertypes.WPoStChallengeWindow }
+
+const WPoStPeriodDeadlines = minertypes.WPoStPeriodDeadlines
+const WPoStChallengeLookback = minertypes.WPoStChallengeLookback
+const FaultDeclarationCutoff = minertypes.FaultDeclarationCutoff
+const MinAggregatedSectors = minertypes.MinAggregatedSectors
+const MinSectorExpiration = minertypes.MinSectorExpiration
+
 type SectorExpiration struct {
 	OnTime abi.ChainEpoch
 
@@ -321,5 +373,6 @@ func AllCodes() []cid.Cid {
 		(&state9{}).Code(),
 		(&state10{}).Code(),
 		(&state11{}).Code(),
+		(&state12{}).Code(),
 	}
 }
diff --git a/chain/actors/builtin/miner/utils.go b/chain/actors/builtin/miner/utils.go
index dae3d3bc205..072eab986bc 100644
--- a/chain/actors/builtin/miner/utils.go
+++ b/chain/actors/builtin/miner/utils.go
@@ -8,6 +8,8 @@ import (
 	"github.com/filecoin-project/go-state-types/network"
 )
 
+var MinSyntheticPoRepVersion = network.Version21
+
 func AllPartSectors(mas State, sget func(Partition) (bitfield.BitField, error)) (bitfield.BitField, error) {
 	var parts []bitfield.BitField
 
@@ -31,7 +33,7 @@ func AllPartSectors(mas State, sget func(Partition) (bitfield.BitField, error))
 
 // SealProofTypeFromSectorSize returns preferred seal proof type for creating
 // new miner actors and new sectors
-func SealProofTypeFromSectorSize(ssize abi.SectorSize, nv network.Version) (abi.RegisteredSealProof, error) {
+func SealProofTypeFromSectorSize(ssize abi.SectorSize, nv network.Version, synthetic bool) (abi.RegisteredSealProof, error) {
 	switch {
 	case nv < network.Version7:
 		switch ssize {
@@ -49,25 +51,49 @@ func SealProofTypeFromSectorSize(ssize abi.SectorSize, nv network.Version) (abi.
 			return 0, xerrors.Errorf("unsupported sector size for miner: %v", ssize)
 		}
 	case nv >= network.Version7:
+		var v abi.RegisteredSealProof
 		switch ssize {
 		case 2 << 10:
-			return abi.RegisteredSealProof_StackedDrg2KiBV1_1, nil
+			v = abi.RegisteredSealProof_StackedDrg2KiBV1_1
 		case 8 << 20:
-			return abi.RegisteredSealProof_StackedDrg8MiBV1_1, nil
+			v = abi.RegisteredSealProof_StackedDrg8MiBV1_1
 		case 512 << 20:
-			return abi.RegisteredSealProof_StackedDrg512MiBV1_1, nil
+			v = abi.RegisteredSealProof_StackedDrg512MiBV1_1
 		case 32 << 30:
-			return abi.RegisteredSealProof_StackedDrg32GiBV1_1, nil
+			v = abi.RegisteredSealProof_StackedDrg32GiBV1_1
 		case 64 << 30:
-			return abi.RegisteredSealProof_StackedDrg64GiBV1_1, nil
+			v = abi.RegisteredSealProof_StackedDrg64GiBV1_1
 		default:
 			return 0, xerrors.Errorf("unsupported sector size for miner: %v", ssize)
 		}
+
+		if nv >= MinSyntheticPoRepVersion && synthetic {
+			return toSynthetic(v)
+		} else {
+			return v, nil
+		}
 	}
 
 	return 0, xerrors.Errorf("unsupported network version")
 }
 
+func toSynthetic(in abi.RegisteredSealProof) (abi.RegisteredSealProof, error) {
+	switch in {
+	case abi.RegisteredSealProof_StackedDrg2KiBV1_1:
+		return abi.RegisteredSealProof_StackedDrg2KiBV1_1_Feat_SyntheticPoRep, nil
+	case abi.RegisteredSealProof_StackedDrg8MiBV1_1:
+		return abi.RegisteredSealProof_StackedDrg8MiBV1_1_Feat_SyntheticPoRep, nil
+	case abi.RegisteredSealProof_StackedDrg512MiBV1_1:
+		return abi.RegisteredSealProof_StackedDrg512MiBV1_1_Feat_SyntheticPoRep, nil
+	case abi.RegisteredSealProof_StackedDrg32GiBV1_1:
+		return abi.RegisteredSealProof_StackedDrg32GiBV1_1_Feat_SyntheticPoRep, nil
+	case abi.RegisteredSealProof_StackedDrg64GiBV1_1:
+		return abi.RegisteredSealProof_StackedDrg64GiBV1_1_Feat_SyntheticPoRep, nil
+	default:
+		return 0, xerrors.Errorf("unsupported conversion to synthetic: %v", in)
+	}
+}
+
 // WindowPoStProofTypeFromSectorSize returns preferred post proof type for creating
 // new miner actors and new sectors
 func WindowPoStProofTypeFromSectorSize(ssize abi.SectorSize, nv network.Version) (abi.RegisteredPoStProof, error) {
diff --git a/chain/actors/builtin/miner/v12.go b/chain/actors/builtin/miner/v12.go
new file mode 100644
index 00000000000..787da7d0f45
--- /dev/null
+++ b/chain/actors/builtin/miner/v12.go
@@ -0,0 +1,591 @@
+package miner
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+
+	"github.com/ipfs/go-cid"
+	cbg "github.com/whyrusleeping/cbor-gen"
+	"golang.org/x/xerrors"
+
+	"github.com/filecoin-project/go-bitfield"
+	rle "github.com/filecoin-project/go-bitfield/rle"
+	"github.com/filecoin-project/go-state-types/abi"
+	actorstypes "github.com/filecoin-project/go-state-types/actors"
+	builtin12 "github.com/filecoin-project/go-state-types/builtin"
+	miner12 "github.com/filecoin-project/go-state-types/builtin/v12/miner"
+	adt12 "github.com/filecoin-project/go-state-types/builtin/v12/util/adt"
+	"github.com/filecoin-project/go-state-types/dline"
+	"github.com/filecoin-project/go-state-types/manifest"
+
+	"github.com/filecoin-project/lotus/chain/actors"
+	"github.com/filecoin-project/lotus/chain/actors/adt"
+)
+
+var _ State = (*state12)(nil)
+
+func load12(store adt.Store, root cid.Cid) (State, error) {
+	out := state12{store: store}
+	err := store.Get(store.Context(), root, &out)
+	if err != nil {
+		return nil, err
+	}
+	return &out, nil
+}
+
+func make12(store adt.Store) (State, error) {
+	out := state12{store: store}
+	out.State = miner12.State{}
+	return &out, nil
+}
+
+type state12 struct {
+	miner12.State
+	store adt.Store
+}
+
+type deadline12 struct {
+	miner12.Deadline
+	store adt.Store
+}
+
+type partition12 struct {
+	miner12.Partition
+	store adt.Store
+}
+
+func (s *state12) AvailableBalance(bal abi.TokenAmount) (available abi.TokenAmount, err error) {
+	defer func() {
+		if r := recover(); r != nil {
+			err = xerrors.Errorf("failed to get available balance: %w", r)
+			available = abi.NewTokenAmount(0)
+		}
+	}()
+	// this panics if the miner doesnt have enough funds to cover their locked pledge
+	available, err = s.GetAvailableBalance(bal)
+	return available, err
+}
+
+func (s *state12) VestedFunds(epoch abi.ChainEpoch) (abi.TokenAmount, error) {
+	return s.CheckVestedFunds(s.store, epoch)
+}
+
+func (s *state12) LockedFunds() (LockedFunds, error) {
+	return LockedFunds{
+		VestingFunds:             s.State.LockedFunds,
+		InitialPledgeRequirement: s.State.InitialPledge,
+		PreCommitDeposits:        s.State.PreCommitDeposits,
+	}, nil
+}
+
+func (s *state12) FeeDebt() (abi.TokenAmount, error) {
+	return s.State.FeeDebt, nil
+}
+
+func (s *state12) InitialPledge() (abi.TokenAmount, error) {
+	return s.State.InitialPledge, nil
+}
+
+func (s *state12) PreCommitDeposits() (abi.TokenAmount, error) {
+	return s.State.PreCommitDeposits, nil
+}
+
+// Returns nil, nil if sector is not found
+func (s *state12) GetSector(num abi.SectorNumber) (*SectorOnChainInfo, error) {
+	info, ok, err := s.State.GetSector(s.store, num)
+	if !ok || err != nil {
+		return nil, err
+	}
+
+	ret := fromV12SectorOnChainInfo(*info)
+	return &ret, nil
+}
+
+func (s *state12) FindSector(num abi.SectorNumber) (*SectorLocation, error) {
+	dlIdx, partIdx, err := s.State.FindSector(s.store, num)
+	if err != nil {
+		return nil, err
+	}
+	return &SectorLocation{
+		Deadline:  dlIdx,
+		Partition: partIdx,
+	}, nil
+}
+
+func (s *state12) NumLiveSectors() (uint64, error) {
+	dls, err := s.State.LoadDeadlines(s.store)
+	if err != nil {
+		return 0, err
+	}
+	var total uint64
+	if err := dls.ForEach(s.store, func(dlIdx uint64, dl *miner12.Deadline) error {
+		total += dl.LiveSectors
+		return nil
+	}); err != nil {
+		return 0, err
+	}
+	return total, nil
+}
+
+// GetSectorExpiration returns the effective expiration of the given sector.
+//
+// If the sector does not expire early, the Early expiration field is 0.
+func (s *state12) GetSectorExpiration(num abi.SectorNumber) (*SectorExpiration, error) {
+	dls, err := s.State.LoadDeadlines(s.store)
+	if err != nil {
+		return nil, err
+	}
+	// NOTE: this can be optimized significantly.
+	// 1. If the sector is non-faulty, it will expire on-time (can be
+	// learned from the sector info).
+	// 2. If it's faulty, it will expire early within the first 42 entries
+	// of the expiration queue.
+
+	stopErr := errors.New("stop")
+	out := SectorExpiration{}
+	err = dls.ForEach(s.store, func(dlIdx uint64, dl *miner12.Deadline) error {
+		partitions, err := dl.PartitionsArray(s.store)
+		if err != nil {
+			return err
+		}
+		quant := s.State.QuantSpecForDeadline(dlIdx)
+		var part miner12.Partition
+		return partitions.ForEach(&part, func(partIdx int64) error {
+			if found, err := part.Sectors.IsSet(uint64(num)); err != nil {
+				return err
+			} else if !found {
+				return nil
+			}
+			if found, err := part.Terminated.IsSet(uint64(num)); err != nil {
+				return err
+			} else if found {
+				// already terminated
+				return stopErr
+			}
+
+			q, err := miner12.LoadExpirationQueue(s.store, part.ExpirationsEpochs, quant, miner12.PartitionExpirationAmtBitwidth)
+			if err != nil {
+				return err
+			}
+			var exp miner12.ExpirationSet
+			return q.ForEach(&exp, func(epoch int64) error {
+				if early, err := exp.EarlySectors.IsSet(uint64(num)); err != nil {
+					return err
+				} else if early {
+					out.Early = abi.ChainEpoch(epoch)
+					return nil
+				}
+				if onTime, err := exp.OnTimeSectors.IsSet(uint64(num)); err != nil {
+					return err
+				} else if onTime {
+					out.OnTime = abi.ChainEpoch(epoch)
+					return stopErr
+				}
+				return nil
+			})
+		})
+	})
+	if err == stopErr {
+		err = nil
+	}
+	if err != nil {
+		return nil, err
+	}
+	if out.Early == 0 && out.OnTime == 0 {
+		return nil, xerrors.Errorf("failed to find sector %d", num)
+	}
+	return &out, nil
+}
+
+func (s *state12) GetPrecommittedSector(num abi.SectorNumber) (*SectorPreCommitOnChainInfo, error) {
+	info, ok, err := s.State.GetPrecommittedSector(s.store, num)
+	if !ok || err != nil {
+		return nil, err
+	}
+
+	ret := fromV12SectorPreCommitOnChainInfo(*info)
+
+	return &ret, nil
+}
+
+func (s *state12) ForEachPrecommittedSector(cb func(SectorPreCommitOnChainInfo) error) error {
+	precommitted, err := adt12.AsMap(s.store, s.State.PreCommittedSectors, builtin12.DefaultHamtBitwidth)
+	if err != nil {
+		return err
+	}
+
+	var info miner12.SectorPreCommitOnChainInfo
+	if err := precommitted.ForEach(&info, func(_ string) error {
+		return cb(fromV12SectorPreCommitOnChainInfo(info))
+	}); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (s *state12) LoadSectors(snos *bitfield.BitField) ([]*SectorOnChainInfo, error) {
+	sectors, err := miner12.LoadSectors(s.store, s.State.Sectors)
+	if err != nil {
+		return nil, err
+	}
+
+	// If no sector numbers are specified, load all.
+	if snos == nil {
+		infos := make([]*SectorOnChainInfo, 0, sectors.Length())
+		var info12 miner12.SectorOnChainInfo
+		if err := sectors.ForEach(&info12, func(_ int64) error {
+			info := fromV12SectorOnChainInfo(info12)
+			infos = append(infos, &info)
+			return nil
+		}); err != nil {
+			return nil, err
+		}
+		return infos, nil
+	}
+
+	// Otherwise, load selected.
+	infos12, err := sectors.Load(*snos)
+	if err != nil {
+		return nil, err
+	}
+	infos := make([]*SectorOnChainInfo, len(infos12))
+	for i, info12 := range infos12 {
+		info := fromV12SectorOnChainInfo(*info12)
+		infos[i] = &info
+	}
+	return infos, nil
+}
+
+func (s *state12) loadAllocatedSectorNumbers() (bitfield.BitField, error) {
+	var allocatedSectors bitfield.BitField
+	err := s.store.Get(s.store.Context(), s.State.AllocatedSectors, &allocatedSectors)
+	return allocatedSectors, err
+}
+
+func (s *state12) IsAllocated(num abi.SectorNumber) (bool, error) {
+	allocatedSectors, err := s.loadAllocatedSectorNumbers()
+	if err != nil {
+		return false, err
+	}
+
+	return allocatedSectors.IsSet(uint64(num))
+}
+
+func (s *state12) GetProvingPeriodStart() (abi.ChainEpoch, error) {
+	return s.State.ProvingPeriodStart, nil
+}
+
+func (s *state12) UnallocatedSectorNumbers(count int) ([]abi.SectorNumber, error) {
+	allocatedSectors, err := s.loadAllocatedSectorNumbers()
+	if err != nil {
+		return nil, err
+	}
+
+	allocatedRuns, err := allocatedSectors.RunIterator()
+	if err != nil {
+		return nil, err
+	}
+
+	unallocatedRuns, err := rle.Subtract(
+		&rle.RunSliceIterator{Runs: []rle.Run{{Val: true, Len: abi.MaxSectorNumber}}},
+		allocatedRuns,
+	)
+	if err != nil {
+		return nil, err
+	}
+
+	iter, err := rle.BitsFromRuns(unallocatedRuns)
+	if err != nil {
+		return nil, err
+	}
+
+	sectors := make([]abi.SectorNumber, 0, count)
+	for iter.HasNext() && len(sectors) < count {
+		nextNo, err := iter.Next()
+		if err != nil {
+			return nil, err
+		}
+		sectors = append(sectors, abi.SectorNumber(nextNo))
+	}
+
+	return sectors, nil
+}
+
+func (s *state12) GetAllocatedSectors() (*bitfield.BitField, error) {
+	var allocatedSectors bitfield.BitField
+	if err := s.store.Get(s.store.Context(), s.State.AllocatedSectors, &allocatedSectors); err != nil {
+		return nil, err
+	}
+
+	return &allocatedSectors, nil
+}
+
+func (s *state12) LoadDeadline(idx uint64) (Deadline, error) {
+	dls, err := s.State.LoadDeadlines(s.store)
+	if err != nil {
+		return nil, err
+	}
+	dl, err := dls.LoadDeadline(s.store, idx)
+	if err != nil {
+		return nil, err
+	}
+	return &deadline12{*dl, s.store}, nil
+}
+
+func (s *state12) ForEachDeadline(cb func(uint64, Deadline) error) error {
+	dls, err := s.State.LoadDeadlines(s.store)
+	if err != nil {
+		return err
+	}
+	return dls.ForEach(s.store, func(i uint64, dl *miner12.Deadline) error {
+		return cb(i, &deadline12{*dl, s.store})
+	})
+}
+
+func (s *state12) NumDeadlines() (uint64, error) {
+	return miner12.WPoStPeriodDeadlines, nil
+}
+
+func (s *state12) DeadlinesChanged(other State) (bool, error) {
+	other12, ok := other.(*state12)
+	if !ok {
+		// treat an upgrade as a change, always
+		return true, nil
+	}
+
+	return !s.State.Deadlines.Equals(other12.Deadlines), nil
+}
+
+func (s *state12) MinerInfoChanged(other State) (bool, error) {
+	other0, ok := other.(*state12)
+	if !ok {
+		// treat an upgrade as a change, always
+		return true, nil
+	}
+	return !s.State.Info.Equals(other0.State.Info), nil
+}
+
+func (s *state12) Info() (MinerInfo, error) {
+	info, err := s.State.GetInfo(s.store)
+	if err != nil {
+		return MinerInfo{}, err
+	}
+
+	mi := MinerInfo{
+		Owner:            info.Owner,
+		Worker:           info.Worker,
+		ControlAddresses: info.ControlAddresses,
+
+		PendingWorkerKey: (*WorkerKeyChange)(info.PendingWorkerKey),
+
+		PeerId:                     info.PeerId,
+		Multiaddrs:                 info.Multiaddrs,
+		WindowPoStProofType:        info.WindowPoStProofType,
+		SectorSize:                 info.SectorSize,
+		WindowPoStPartitionSectors: info.WindowPoStPartitionSectors,
+		ConsensusFaultElapsed:      info.ConsensusFaultElapsed,
+
+		Beneficiary:            info.Beneficiary,
+		BeneficiaryTerm:        BeneficiaryTerm(info.BeneficiaryTerm),
+		PendingBeneficiaryTerm: (*PendingBeneficiaryChange)(info.PendingBeneficiaryTerm),
+	}
+
+	return mi, nil
+}
+
+func (s *state12) DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error) {
+	return s.State.RecordedDeadlineInfo(epoch), nil
+}
+
+func (s *state12) DeadlineCronActive() (bool, error) {
+	return s.State.DeadlineCronActive, nil
+}
+
+func (s *state12) sectors() (adt.Array, error) {
+	return adt12.AsArray(s.store, s.Sectors, miner12.SectorsAmtBitwidth)
+}
+
+func (s *state12) decodeSectorOnChainInfo(val *cbg.Deferred) (SectorOnChainInfo, error) {
+	var si miner12.SectorOnChainInfo
+	err := si.UnmarshalCBOR(bytes.NewReader(val.Raw))
+	if err != nil {
+		return SectorOnChainInfo{}, err
+	}
+
+	return fromV12SectorOnChainInfo(si), nil
+}
+
+func (s *state12) precommits() (adt.Map, error) {
+	return adt12.AsMap(s.store, s.PreCommittedSectors, builtin12.DefaultHamtBitwidth)
+}
+
+func (s *state12) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreCommitOnChainInfo, error) {
+	var sp miner12.SectorPreCommitOnChainInfo
+	err := sp.UnmarshalCBOR(bytes.NewReader(val.Raw))
+	if err != nil {
+		return SectorPreCommitOnChainInfo{}, err
+	}
+
+	return fromV12SectorPreCommitOnChainInfo(sp), nil
+}
+
+func (s *state12) EraseAllUnproven() error {
+
+	dls, err := s.State.LoadDeadlines(s.store)
+	if err != nil {
+		return err
+	}
+
+	err = dls.ForEach(s.store, func(dindx uint64, dl *miner12.Deadline) error {
+		ps, err := dl.PartitionsArray(s.store)
+		if err != nil {
+			return err
+		}
+
+		var part miner12.Partition
+		err = ps.ForEach(&part, func(pindx int64) error {
+			_ = part.ActivateUnproven()
+			err = ps.Set(uint64(pindx), &part)
+			return nil
+		})
+
+		if err != nil {
+			return err
+		}
+
+		dl.Partitions, err = ps.Root()
+		if err != nil {
+			return err
+		}
+
+		return dls.UpdateDeadline(s.store, dindx, dl)
+	})
+	if err != nil {
+		return err
+	}
+
+	return s.State.SaveDeadlines(s.store, dls)
+
+}
+
+func (d *deadline12) LoadPartition(idx uint64) (Partition, error) {
+	p, err := d.Deadline.LoadPartition(d.store, idx)
+	if err != nil {
+		return nil, err
+	}
+	return &partition12{*p, d.store}, nil
+}
+
+func (d *deadline12) ForEachPartition(cb func(uint64, Partition) error) error {
+	ps, err := d.Deadline.PartitionsArray(d.store)
+	if err != nil {
+		return err
+	}
+	var part miner12.Partition
+	return ps.ForEach(&part, func(i int64) error {
+		return cb(uint64(i), &partition12{part, d.store})
+	})
+}
+
+func (d *deadline12) PartitionsChanged(other Deadline) (bool, error) {
+	other12, ok := other.(*deadline12)
+	if !ok {
+		// treat an upgrade as a change, always
+		return true, nil
+	}
+
+	return !d.Deadline.Partitions.Equals(other12.Deadline.Partitions), nil
+}
+
+func (d *deadline12) PartitionsPoSted() (bitfield.BitField, error) {
+	return d.Deadline.PartitionsPoSted, nil
+}
+
+func (d *deadline12) DisputableProofCount() (uint64, error) {
+
+	ops, err := d.OptimisticProofsSnapshotArray(d.store)
+	if err != nil {
+		return 0, err
+	}
+
+	return ops.Length(), nil
+
+}
+
+func (p *partition12) AllSectors() (bitfield.BitField, error) {
+	return p.Partition.Sectors, nil
+}
+
+func (p *partition12) FaultySectors() (bitfield.BitField, error) {
+	return p.Partition.Faults, nil
+}
+
+func (p *partition12) RecoveringSectors() (bitfield.BitField, error) {
+	return p.Partition.Recoveries, nil
+}
+
+func (p *partition12) UnprovenSectors() (bitfield.BitField, error) {
+	return p.Partition.Unproven, nil
+}
+
+func fromV12SectorOnChainInfo(v12 miner12.SectorOnChainInfo) SectorOnChainInfo {
+	info := SectorOnChainInfo{
+		SectorNumber:          v12.SectorNumber,
+		SealProof:             v12.SealProof,
+		SealedCID:             v12.SealedCID,
+		DealIDs:               v12.DealIDs,
+		Activation:            v12.Activation,
+		Expiration:            v12.Expiration,
+		DealWeight:            v12.DealWeight,
+		VerifiedDealWeight:    v12.VerifiedDealWeight,
+		InitialPledge:         v12.InitialPledge,
+		ExpectedDayReward:     v12.ExpectedDayReward,
+		ExpectedStoragePledge: v12.ExpectedStoragePledge,
+
+		SectorKeyCID: v12.SectorKeyCID,
+	}
+	return info
+}
+
+func fromV12SectorPreCommitOnChainInfo(v12 miner12.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo {
+	ret := SectorPreCommitOnChainInfo{
+		Info: SectorPreCommitInfo{
+			SealProof:     v12.Info.SealProof,
+			SectorNumber:  v12.Info.SectorNumber,
+			SealedCID:     v12.Info.SealedCID,
+			SealRandEpoch: v12.Info.SealRandEpoch,
+			DealIDs:       v12.Info.DealIDs,
+			Expiration:    v12.Info.Expiration,
+			UnsealedCid:   nil,
+		},
+		PreCommitDeposit: v12.PreCommitDeposit,
+		PreCommitEpoch:   v12.PreCommitEpoch,
+	}
+
+	ret.Info.UnsealedCid = v12.Info.UnsealedCid
+
+	return ret
+}
+
+func (s *state12) GetState() interface{} {
+	return &s.State
+}
+
+func (s *state12) ActorKey() string {
+	return manifest.MinerKey
+}
+
+func (s *state12) ActorVersion() actorstypes.Version {
+	return actorstypes.Version12
+}
+
+func (s *state12) Code() cid.Cid {
+	code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey())
+	if !ok {
+		panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion()))
+	}
+
+	return code
+}
diff --git a/chain/actors/builtin/multisig/message10.go b/chain/actors/builtin/multisig/message10.go
index 5f70ea3c170..8f7bb5a6f2e 100644
--- a/chain/actors/builtin/multisig/message10.go
+++ b/chain/actors/builtin/multisig/message10.go
@@ -8,7 +8,7 @@ import (
 	actorstypes "github.com/filecoin-project/go-state-types/actors"
 	builtintypes "github.com/filecoin-project/go-state-types/builtin"
 	multisig10 "github.com/filecoin-project/go-state-types/builtin/v10/multisig"
-	init11 "github.com/filecoin-project/go-state-types/builtin/v11/init"
+	init12 "github.com/filecoin-project/go-state-types/builtin/v12/init"
 	"github.com/filecoin-project/go-state-types/manifest"
 
 	"github.com/filecoin-project/lotus/chain/actors"
@@ -57,7 +57,7 @@ func (m message10) Create(
 	}
 
 	// new actors are created by invoking 'exec' on the init actor with the constructor params
-	execParams := &init11.ExecParams{
+	execParams := &init12.ExecParams{
 		CodeCID:           code,
 		ConstructorParams: enc,
 	}
diff --git a/chain/actors/builtin/multisig/message11.go b/chain/actors/builtin/multisig/message11.go
index a2c08661453..4c7520d5dea 100644
--- a/chain/actors/builtin/multisig/message11.go
+++ b/chain/actors/builtin/multisig/message11.go
@@ -7,8 +7,8 @@ import (
 	"github.com/filecoin-project/go-state-types/abi"
 	actorstypes "github.com/filecoin-project/go-state-types/actors"
 	builtintypes "github.com/filecoin-project/go-state-types/builtin"
-	init11 "github.com/filecoin-project/go-state-types/builtin/v11/init"
 	multisig11 "github.com/filecoin-project/go-state-types/builtin/v11/multisig"
+	init12 "github.com/filecoin-project/go-state-types/builtin/v12/init"
 	"github.com/filecoin-project/go-state-types/manifest"
 
 	"github.com/filecoin-project/lotus/chain/actors"
@@ -57,7 +57,7 @@ func (m message11) Create(
 	}
 
 	// new actors are created by invoking 'exec' on the init actor with the constructor params
-	execParams := &init11.ExecParams{
+	execParams := &init12.ExecParams{
 		CodeCID:           code,
 		ConstructorParams: enc,
 	}
diff --git a/chain/actors/builtin/multisig/message12.go b/chain/actors/builtin/multisig/message12.go
new file mode 100644
index 00000000000..43658c04b03
--- /dev/null
+++ b/chain/actors/builtin/multisig/message12.go
@@ -0,0 +1,77 @@
+package multisig
+
+import (
+	"golang.org/x/xerrors"
+
+	"github.com/filecoin-project/go-address"
+	"github.com/filecoin-project/go-state-types/abi"
+	actorstypes "github.com/filecoin-project/go-state-types/actors"
+	builtintypes "github.com/filecoin-project/go-state-types/builtin"
+	init12 "github.com/filecoin-project/go-state-types/builtin/v12/init"
+	multisig12 "github.com/filecoin-project/go-state-types/builtin/v12/multisig"
+	"github.com/filecoin-project/go-state-types/manifest"
+
+	"github.com/filecoin-project/lotus/chain/actors"
+	init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
+	"github.com/filecoin-project/lotus/chain/types"
+)
+
+type message12 struct{ message0 }
+
+func (m message12) Create(
+	signers []address.Address, threshold uint64,
+	unlockStart, unlockDuration abi.ChainEpoch,
+	initialAmount abi.TokenAmount,
+) (*types.Message, error) {
+
+	lenAddrs := uint64(len(signers))
+
+	if lenAddrs < threshold {
+		return nil, xerrors.Errorf("cannot require signing of more addresses than provided for multisig")
+	}
+
+	if threshold == 0 {
+		threshold = lenAddrs
+	}
+
+	if m.from == address.Undef {
+		return nil, xerrors.Errorf("must provide source address")
+	}
+
+	// Set up constructor parameters for multisig
+	msigParams := &multisig12.ConstructorParams{
+		Signers:               signers,
+		NumApprovalsThreshold: threshold,
+		UnlockDuration:        unlockDuration,
+		StartEpoch:            unlockStart,
+	}
+
+	enc, actErr := actors.SerializeParams(msigParams)
+	if actErr != nil {
+		return nil, actErr
+	}
+
+	code, ok := actors.GetActorCodeID(actorstypes.Version12, manifest.MultisigKey)
+	if !ok {
+		return nil, xerrors.Errorf("failed to get multisig code ID")
+	}
+
+	// new actors are created by invoking 'exec' on the init actor with the constructor params
+	execParams := &init12.ExecParams{
+		CodeCID:           code,
+		ConstructorParams: enc,
+	}
+
+	enc, actErr = actors.SerializeParams(execParams)
+	if actErr != nil {
+		return nil, actErr
+	}
+
+	return &types.Message{
+		To:     init_.Address,
+		From:   m.from,
+		Method: builtintypes.MethodsInit.Exec,
+		Params: enc,
+		Value:  initialAmount,
+	}, nil
+}
diff --git a/chain/actors/builtin/multisig/message8.go b/chain/actors/builtin/multisig/message8.go
index 817d66726d4..390c94691e4 100644
--- a/chain/actors/builtin/multisig/message8.go
+++ b/chain/actors/builtin/multisig/message8.go
@@ -7,7 +7,7 @@ import (
 	"github.com/filecoin-project/go-state-types/abi"
 	actorstypes "github.com/filecoin-project/go-state-types/actors"
 	builtintypes "github.com/filecoin-project/go-state-types/builtin"
-	init11 "github.com/filecoin-project/go-state-types/builtin/v11/init"
+	init12 "github.com/filecoin-project/go-state-types/builtin/v12/init"
 	multisig8 "github.com/filecoin-project/go-state-types/builtin/v8/multisig"
 	"github.com/filecoin-project/go-state-types/manifest"
 
@@ -57,7 +57,7 @@ func (m message8) Create(
 	}
 
 	// new actors are created by invoking 'exec' on the init actor with the constructor params
-	execParams := &init11.ExecParams{
+	execParams := &init12.ExecParams{
 		CodeCID:           code,
 		ConstructorParams: enc,
 	}
diff --git a/chain/actors/builtin/multisig/message9.go b/chain/actors/builtin/multisig/message9.go
index 1472c4e664a..907bec7d556 100644
--- a/chain/actors/builtin/multisig/message9.go
+++ b/chain/actors/builtin/multisig/message9.go
@@ -7,7 +7,7 @@ import (
 	"github.com/filecoin-project/go-state-types/abi"
 	actorstypes "github.com/filecoin-project/go-state-types/actors"
 	builtintypes "github.com/filecoin-project/go-state-types/builtin"
-	init11 "github.com/filecoin-project/go-state-types/builtin/v11/init"
+	init12 "github.com/filecoin-project/go-state-types/builtin/v12/init"
 	multisig9 "github.com/filecoin-project/go-state-types/builtin/v9/multisig"
 	"github.com/filecoin-project/go-state-types/manifest"
 
@@ -57,7 +57,7 @@ func (m message9) Create(
 	}
 
 	// new actors are created by invoking 'exec' on the init actor with the constructor params
-	execParams := &init11.ExecParams{
+	execParams := &init12.ExecParams{
 		CodeCID:           code,
 		ConstructorParams: enc,
 	}
diff --git a/chain/actors/builtin/multisig/multisig.go b/chain/actors/builtin/multisig/multisig.go
index 9ab8fffb5e9..71a3b7b2237 100644
--- a/chain/actors/builtin/multisig/multisig.go
+++ b/chain/actors/builtin/multisig/multisig.go
@@ -12,7 +12,7 @@ import (
 	"github.com/filecoin-project/go-state-types/abi"
 	actorstypes "github.com/filecoin-project/go-state-types/actors"
 	builtintypes "github.com/filecoin-project/go-state-types/builtin"
-	msig11 "github.com/filecoin-project/go-state-types/builtin/v11/multisig"
+	msig12 "github.com/filecoin-project/go-state-types/builtin/v12/multisig"
 	"github.com/filecoin-project/go-state-types/cbor"
 	"github.com/filecoin-project/go-state-types/manifest"
 	builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
@@ -48,6 +48,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) {
 		case actorstypes.Version11:
 			return load11(store, act.Head)
 
+		case actorstypes.Version12:
+			return load12(store, act.Head)
+
 		}
 	}
 
@@ -115,6 +118,9 @@ func MakeState(store adt.Store, av actorstypes.Version, signers []address.Addres
 	case actorstypes.Version11:
 		return make11(store, signers, threshold, startEpoch, unlockDuration, initialBalance)
 
+	case actorstypes.Version12:
+		return make12(store, signers, threshold, startEpoch, unlockDuration, initialBalance)
+
 	}
 	return nil, xerrors.Errorf("unknown actor version %d", av)
 }
@@ -141,7 +147,7 @@ type State interface {
 	GetState() interface{}
 }
 
-type Transaction = msig11.Transaction
+type Transaction = msig12.Transaction
 
 var Methods = builtintypes.MethodsMultisig
 
@@ -180,6 +186,9 @@ func Message(version actorstypes.Version, from address.Address) MessageBuilder {
 
 	case actorstypes.Version11:
 		return message11{message0{from}}
+
+	case actorstypes.Version12:
+		return message12{message0{from}}
 	default:
 		panic(fmt.Sprintf("unsupported actors version: %d", version))
 	}
@@ -203,13 +212,13 @@ type MessageBuilder interface {
 }
 
 // this type is the same between v0 and v2
-type ProposalHashData = msig11.ProposalHashData
-type ProposeReturn = msig11.ProposeReturn
-type ProposeParams = msig11.ProposeParams
-type ApproveReturn = msig11.ApproveReturn
+type ProposalHashData = msig12.ProposalHashData
+type ProposeReturn = msig12.ProposeReturn
+type ProposeParams = msig12.ProposeParams
+type ApproveReturn = msig12.ApproveReturn
 
 func txnParams(id uint64, data *ProposalHashData) ([]byte, error) {
-	params := msig11.TxnIDParams{ID: msig11.TxnID(id)}
+	params := msig12.TxnIDParams{ID: msig12.TxnID(id)}
 	if data != nil {
 		if data.Requester.Protocol() != address.ID {
 			return nil, xerrors.Errorf("proposer address must be an ID address, was %s", data.Requester)
@@ -244,5 +253,6 @@ func AllCodes() []cid.Cid {
 		(&state9{}).Code(),
 		(&state10{}).Code(),
 		(&state11{}).Code(),
+		(&state12{}).Code(),
 	}
 }
diff --git a/chain/actors/builtin/multisig/v12.go b/chain/actors/builtin/multisig/v12.go
new file mode 100644
index 00000000000..d3d2f3809a9
--- /dev/null
+++ b/chain/actors/builtin/multisig/v12.go
@@ -0,0 +1,138 @@
+package multisig
+
+import (
+	"bytes"
+	"encoding/binary"
+	"fmt"
+
+	"github.com/ipfs/go-cid"
+	cbg "github.com/whyrusleeping/cbor-gen"
+	"golang.org/x/xerrors"
+
+	"github.com/filecoin-project/go-address"
+	"github.com/filecoin-project/go-state-types/abi"
+	actorstypes "github.com/filecoin-project/go-state-types/actors"
+	builtin12 "github.com/filecoin-project/go-state-types/builtin"
+	msig12 "github.com/filecoin-project/go-state-types/builtin/v12/multisig"
+	adt12 "github.com/filecoin-project/go-state-types/builtin/v12/util/adt"
+	"github.com/filecoin-project/go-state-types/manifest"
+
+	"github.com/filecoin-project/lotus/chain/actors"
+	"github.com/filecoin-project/lotus/chain/actors/adt"
+)
+
+var _ State = (*state12)(nil)
+
+func load12(store adt.Store, root cid.Cid) (State, error) {
+	out := state12{store: store}
+	err := store.Get(store.Context(), root, &out)
+	if err != nil {
+		return nil, err
+	}
+	return &out, nil
+}
+
+func make12(store adt.Store, signers []address.Address, threshold uint64, startEpoch abi.ChainEpoch, unlockDuration abi.ChainEpoch, initialBalance abi.TokenAmount) (State, error) {
+	out := state12{store: store}
+	out.State = msig12.State{}
+	out.State.Signers = signers
+	out.State.NumApprovalsThreshold = threshold
+	out.State.StartEpoch = startEpoch
+	out.State.UnlockDuration = unlockDuration
+	out.State.InitialBalance = initialBalance
+
+	em, err := adt12.StoreEmptyMap(store, builtin12.DefaultHamtBitwidth)
+	if err != nil {
+		return nil, err
+	}
+
+	out.State.PendingTxns = em
+
+	return &out, nil
+}
+
+type state12 struct {
+	msig12.State
+	store adt.Store
+}
+
+func (s *state12) LockedBalance(currEpoch abi.ChainEpoch) (abi.TokenAmount, error) {
+	return s.State.AmountLocked(currEpoch - s.State.StartEpoch), nil
+}
+
+func (s *state12) StartEpoch() (abi.ChainEpoch, error) {
+	return s.State.StartEpoch, nil
+}
+
+func (s *state12) UnlockDuration() (abi.ChainEpoch, error) {
+	return s.State.UnlockDuration, nil
+}
+
+func (s *state12) InitialBalance() (abi.TokenAmount, error) {
+	return s.State.InitialBalance, nil
+}
+
+func (s *state12) Threshold() (uint64, error) {
+	return s.State.NumApprovalsThreshold, nil
+}
+
+func (s *state12) Signers() ([]address.Address, error) {
+	return s.State.Signers, nil
+}
+
+func (s *state12) ForEachPendingTxn(cb func(id int64, txn Transaction) error) error {
+	arr, err := adt12.AsMap(s.store, s.State.PendingTxns, builtin12.DefaultHamtBitwidth)
+	if err != nil {
+		return err
+	}
+	var out msig12.Transaction
+	return arr.ForEach(&out, func(key string) error {
+		txid, n := binary.Varint([]byte(key))
+		if n <= 0 {
+			return xerrors.Errorf("invalid pending transaction key: %v", key)
+		}
+		return cb(txid, (Transaction)(out)) //nolint:unconvert
+	})
+}
+
+func (s *state12) PendingTxnChanged(other State) (bool, error) {
+	other12, ok := other.(*state12)
+	if !ok {
+		// treat an upgrade as a change, always
+		return true, nil
+	}
+	return !s.State.PendingTxns.Equals(other12.PendingTxns), nil
+}
+
+func (s *state12) transactions() (adt.Map, error) {
+	return adt12.AsMap(s.store, s.PendingTxns, builtin12.DefaultHamtBitwidth)
+}
+
+func (s *state12) decodeTransaction(val *cbg.Deferred) (Transaction, error) {
+	var tx msig12.Transaction
+	if err := tx.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
+		return Transaction{}, err
+	}
+	return Transaction(tx), nil
+}
+
+func (s *state12) GetState() interface{} {
+	return &s.State
+}
+
+func (s *state12) ActorKey() string {
+	return manifest.MultisigKey
+}
+
+func (s *state12) ActorVersion() actorstypes.Version {
+	return actorstypes.Version12
+}
+
+func (s *state12) Code() cid.Cid {
+	code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey())
+	if !ok {
+		panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion()))
+	}
+
+	return code
+}
diff --git a/chain/actors/builtin/paych/message12.go b/chain/actors/builtin/paych/message12.go
new file mode 100644
index 00000000000..bd821641ae4
--- /dev/null
+++ b/chain/actors/builtin/paych/message12.go
@@ -0,0 +1,109 @@
+package paych
+
+import (
+	"golang.org/x/xerrors"
+
+	"github.com/filecoin-project/go-address"
+	"github.com/filecoin-project/go-state-types/abi"
+	actorstypes "github.com/filecoin-project/go-state-types/actors"
+	builtin12 "github.com/filecoin-project/go-state-types/builtin"
+	init12 "github.com/filecoin-project/go-state-types/builtin/v12/init"
+	paych12 "github.com/filecoin-project/go-state-types/builtin/v12/paych"
+	paychtypes "github.com/filecoin-project/go-state-types/builtin/v8/paych"
+
+	"github.com/filecoin-project/lotus/chain/actors"
+	init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
+	"github.com/filecoin-project/lotus/chain/types"
+)
+
+type message12 struct{ from address.Address }
+
+func (m message12) Create(to address.Address, initialAmount abi.TokenAmount) (*types.Message, error) {
+
+	actorCodeID, ok := actors.GetActorCodeID(actorstypes.Version12, "paymentchannel")
+	if !ok {
+		return nil, xerrors.Errorf("error getting actor paymentchannel code id for actor version %d", 12)
+	}
+
+	params, aerr := actors.SerializeParams(&paych12.ConstructorParams{From: m.from, To: to})
+	if aerr != nil {
+		return nil, aerr
+	}
+	enc, aerr := actors.SerializeParams(&init12.ExecParams{
+		CodeCID:           actorCodeID,
+		ConstructorParams: params,
+	})
+	if aerr != nil {
+		return nil, aerr
+	}
+
+	return &types.Message{
+		To:     init_.Address,
+		From:   m.from,
+		Value:  initialAmount,
+		Method: builtin12.MethodsInit.Exec,
+		Params: enc,
+	}, nil
+}
+
+func (m message12) Update(paych address.Address, sv *paychtypes.SignedVoucher, secret []byte) (*types.Message, error) {
+	params, aerr := actors.SerializeParams(&paych12.UpdateChannelStateParams{
+
+		Sv: toV12SignedVoucher(*sv),
+
+		Secret: secret,
+	})
+	if aerr != nil {
+		return nil, aerr
+	}
+
+	return &types.Message{
+		To:     paych,
+		From:   m.from,
+		Value:  abi.NewTokenAmount(0),
+		Method: builtin12.MethodsPaych.UpdateChannelState,
+		Params: params,
+	}, nil
+}
+
+func toV12SignedVoucher(sv paychtypes.SignedVoucher) paych12.SignedVoucher {
+	merges := make([]paych12.Merge, len(sv.Merges))
+	for i := range sv.Merges {
+		merges[i] = paych12.Merge{
+			Lane:  sv.Merges[i].Lane,
+			Nonce: sv.Merges[i].Nonce,
+		}
+	}
+
+	return paych12.SignedVoucher{
+		ChannelAddr:     sv.ChannelAddr,
+		TimeLockMin:     sv.TimeLockMin,
+		TimeLockMax:     sv.TimeLockMax,
+		SecretHash:      sv.SecretHash,
+		Extra:           (*paych12.ModVerifyParams)(sv.Extra),
+		Lane:            sv.Lane,
+		Nonce:           sv.Nonce,
+		Amount:          sv.Amount,
+		MinSettleHeight: sv.MinSettleHeight,
+		Merges:          merges,
+		Signature:       sv.Signature,
+	}
+}
+
+func (m message12) Settle(paych address.Address) (*types.Message, error) {
+	return &types.Message{
+		To:     paych,
+		From:   m.from,
+		Value:  abi.NewTokenAmount(0),
+		Method: builtin12.MethodsPaych.Settle,
+	}, nil
+}
+
+func (m message12) Collect(paych address.Address) (*types.Message, error) {
+	return &types.Message{
+		To:     paych,
+		From:   m.from,
+		Value:  abi.NewTokenAmount(0),
+		Method: builtin12.MethodsPaych.Collect,
+	}, nil
+}
diff --git a/chain/actors/builtin/paych/paych.go b/chain/actors/builtin/paych/paych.go
index ccf48dbcee0..8a7979e95f7 100644
--- a/chain/actors/builtin/paych/paych.go
+++ b/chain/actors/builtin/paych/paych.go
@@ -50,6 +50,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) {
 		case actorstypes.Version11:
 			return load11(store, act.Head)
 
+		case actorstypes.Version12:
+			return load12(store, act.Head)
+
 		}
 	}
 
@@ -167,6 +170,9 @@ func Message(version actorstypes.Version, from address.Address) MessageBuilder {
 	case actorstypes.Version11:
 		return message11{from}
 
+	case actorstypes.Version12:
+		return message12{from}
+
 	default:
 		panic(fmt.Sprintf("unsupported actors version: %d", version))
 	}
@@ -208,5 +214,6 @@ func AllCodes() []cid.Cid {
 		(&state9{}).Code(),
 		(&state10{}).Code(),
 		(&state11{}).Code(),
+		(&state12{}).Code(),
 	}
 }
diff --git a/chain/actors/builtin/paych/v12.go b/chain/actors/builtin/paych/v12.go
new file mode 100644
index 00000000000..5c1330d76bc
--- /dev/null
+++ b/chain/actors/builtin/paych/v12.go
@@ -0,0 +1,135 @@
+package paych
+
+import (
+	"fmt"
+
+	"github.com/ipfs/go-cid"
+
+	"github.com/filecoin-project/go-address"
+	"github.com/filecoin-project/go-state-types/abi"
+	actorstypes "github.com/filecoin-project/go-state-types/actors"
+	"github.com/filecoin-project/go-state-types/big"
+	paych12 "github.com/filecoin-project/go-state-types/builtin/v12/paych"
+	adt12 "github.com/filecoin-project/go-state-types/builtin/v12/util/adt"
+	"github.com/filecoin-project/go-state-types/manifest"
+
+	"github.com/filecoin-project/lotus/chain/actors"
+	"github.com/filecoin-project/lotus/chain/actors/adt"
+)
+
+var _ State = (*state12)(nil)
+
+func load12(store adt.Store, root cid.Cid) (State, error) {
+	out := state12{store: store}
+	err := store.Get(store.Context(), root, &out)
+	if err != nil {
+		return nil, err
+	}
+	return &out, nil
+}
+
+func make12(store adt.Store) (State, error) {
+	out := state12{store: store}
+	out.State = paych12.State{}
+	return &out, nil
+}
+
+type state12 struct {
+	paych12.State
+	store adt.Store
+	lsAmt *adt12.Array
+}
+
+// Channel owner, who has funded the actor
+func (s *state12) From() (address.Address, error) {
+	return s.State.From, nil
+}
+
+// Recipient of payouts from channel
+func (s *state12) To() (address.Address, error) {
+	return s.State.To, nil
+}
+
+// Height at which the channel can be `Collected`
+func (s *state12) SettlingAt() (abi.ChainEpoch, error) {
+	return s.State.SettlingAt, nil
+}
+
+// Amount successfully redeemed through the payment channel, paid out on `Collect()`
+func (s *state12) ToSend() (abi.TokenAmount, error) {
+	return s.State.ToSend, nil
+}
+
+func (s *state12) getOrLoadLsAmt() (*adt12.Array, error) {
+	if s.lsAmt != nil {
+		return s.lsAmt, nil
+	}
+
+	// Get the lane state from the chain
+	lsamt, err := adt12.AsArray(s.store, s.State.LaneStates, paych12.LaneStatesAmtBitwidth)
+	if err != nil {
+		return nil, err
+	}
+
+	s.lsAmt = lsamt
+	return lsamt, nil
+}
+
+// Get total number of lanes
+func (s *state12) LaneCount() (uint64, error) {
+	lsamt, err := s.getOrLoadLsAmt()
+	if err != nil {
+		return 0, err
+	}
+	return lsamt.Length(), nil
+}
+
+func (s *state12) GetState() interface{} {
+	return &s.State
+}
+
+// Iterate lane states
+func (s *state12) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error {
+	// Get the lane state from the chain
+	lsamt, err := s.getOrLoadLsAmt()
+	if err != nil {
+		return err
+	}
+
+	// Note: we use a map instead of an array to store laneStates because the
+	// client sets the lane ID (the index) and potentially they could use a
+	// very large index.
+	var ls paych12.LaneState
+	return lsamt.ForEach(&ls, func(i int64) error {
+		return cb(uint64(i), &laneState12{ls})
+	})
+}
+
+type laneState12 struct {
+	paych12.LaneState
+}
+
+func (ls *laneState12) Redeemed() (big.Int, error) {
+	return ls.LaneState.Redeemed, nil
+}
+
+func (ls *laneState12) Nonce() (uint64, error) {
+	return ls.LaneState.Nonce, nil
+}
+
+func (s *state12) ActorKey() string {
+	return manifest.PaychKey
+}
+
+func (s *state12) ActorVersion() actorstypes.Version {
+	return actorstypes.Version12
+}
+
+func (s *state12) Code() cid.Cid {
+	code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey())
+	if !ok {
+		panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion()))
+	}
+
+	return code
+}
diff --git a/chain/actors/builtin/power/power.go b/chain/actors/builtin/power/power.go
index f3bcef5bb2f..9b64ded3877 100644
--- a/chain/actors/builtin/power/power.go
+++ b/chain/actors/builtin/power/power.go
@@ -9,7 +9,7 @@ import (
 	"github.com/filecoin-project/go-state-types/abi"
 	actorstypes "github.com/filecoin-project/go-state-types/actors"
 	"github.com/filecoin-project/go-state-types/big"
-	builtin11 "github.com/filecoin-project/go-state-types/builtin"
+	builtin12 "github.com/filecoin-project/go-state-types/builtin"
 	"github.com/filecoin-project/go-state-types/cbor"
 	"github.com/filecoin-project/go-state-types/manifest"
 	builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
@@ -27,8 +27,8 @@ import (
 )
 
 var (
-	Address = builtin11.StoragePowerActorAddr
-	Methods = builtin11.MethodsPower
+	Address = builtin12.StoragePowerActorAddr
+	Methods = builtin12.MethodsPower
 )
 
 func Load(store adt.Store, act *types.Actor) (State, error) {
@@ -51,6 +51,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) {
 		case actorstypes.Version11:
 			return load11(store, act.Head)
 
+		case actorstypes.Version12:
+			return load12(store, act.Head)
+
 		}
 	}
 
@@ -118,6 +121,9 @@ func MakeState(store adt.Store, av actorstypes.Version) (State, error) {
 	case actorstypes.Version11:
 		return make11(store)
 
+	case actorstypes.Version12:
+		return make12(store)
+
 	}
 	return nil, xerrors.Errorf("unknown actor version %d", av)
 }
@@ -183,5 +189,6 @@ func AllCodes() []cid.Cid {
 		(&state9{}).Code(),
 		(&state10{}).Code(),
 		(&state11{}).Code(),
+		(&state12{}).Code(),
 	}
 }
diff --git a/chain/actors/builtin/power/v12.go b/chain/actors/builtin/power/v12.go
new file mode 100644
index 00000000000..2e910902269
--- /dev/null
+++ b/chain/actors/builtin/power/v12.go
@@ -0,0 +1,207 @@
+package power
+
+import (
+	"bytes"
+	"fmt"
+
+	"github.com/ipfs/go-cid"
+	cbg "github.com/whyrusleeping/cbor-gen"
+
+	"github.com/filecoin-project/go-address"
+	"github.com/filecoin-project/go-state-types/abi"
+	actorstypes "github.com/filecoin-project/go-state-types/actors"
+	builtin12 "github.com/filecoin-project/go-state-types/builtin"
+	power12 "github.com/filecoin-project/go-state-types/builtin/v12/power"
+	adt12 "github.com/filecoin-project/go-state-types/builtin/v12/util/adt"
+	"github.com/filecoin-project/go-state-types/manifest"
+
+	"github.com/filecoin-project/lotus/chain/actors"
+	"github.com/filecoin-project/lotus/chain/actors/adt"
+	"github.com/filecoin-project/lotus/chain/actors/builtin"
+)
+
+var _ State = (*state12)(nil)
+
+func load12(store adt.Store, root cid.Cid) (State, error) {
+	out := state12{store: store}
+	err := store.Get(store.Context(), root, &out)
+	if err != nil {
+		return nil, err
+	}
+	return &out, nil
+}
+
+func make12(store adt.Store) (State, error) {
+	out := state12{store: store}
+
+	s, err := power12.ConstructState(store)
+	if err != nil {
+		return nil, err
+	}
+
+	out.State = *s
+
+	return &out, nil
+}
+
+type state12 struct {
+	power12.State
+	store adt.Store
+}
+
+func (s *state12) TotalLocked() (abi.TokenAmount, error) {
+	return s.TotalPledgeCollateral, nil
+}
+
+func (s *state12) TotalPower() (Claim, error) {
+	return Claim{
+		RawBytePower:    s.TotalRawBytePower,
+		QualityAdjPower: s.TotalQualityAdjPower,
+	}, nil
+}
+
+// Committed power to the network. Includes miners below the minimum threshold.
+func (s *state12) TotalCommitted() (Claim, error) {
+	return Claim{
+		RawBytePower:    s.TotalBytesCommitted,
+		QualityAdjPower: s.TotalQABytesCommitted,
+	}, nil
+}
+
+func (s *state12) MinerPower(addr address.Address) (Claim, bool, error) {
+	claims, err := s.claims()
+	if err != nil {
+		return Claim{}, false, err
+	}
+	var claim power12.Claim
+	ok, err := claims.Get(abi.AddrKey(addr), &claim)
+	if err != nil {
+		return Claim{}, false, err
+	}
+	return Claim{
+		RawBytePower:    claim.RawBytePower,
+		QualityAdjPower: claim.QualityAdjPower,
+	}, ok, nil
+}
+
+func (s *state12) MinerNominalPowerMeetsConsensusMinimum(a address.Address) (bool, error) {
+	return s.State.MinerNominalPowerMeetsConsensusMinimum(s.store, a)
+}
+
+func (s *state12) TotalPowerSmoothed() (builtin.FilterEstimate, error) {
+	return builtin.FilterEstimate(s.State.ThisEpochQAPowerSmoothed), nil
+}
+
+func (s *state12) MinerCounts() (uint64, uint64, error) {
+	return uint64(s.State.MinerAboveMinPowerCount), uint64(s.State.MinerCount), nil
+}
+
+func (s *state12) ListAllMiners() ([]address.Address, error) {
+	claims, err := s.claims()
+	if err != nil {
+		return nil, err
+	}
+
+	var miners []address.Address
+	err = claims.ForEach(nil, func(k string) error {
+		a, err := address.NewFromBytes([]byte(k))
+		if err != nil {
+			return err
+		}
+		miners = append(miners, a)
+		return nil
+	})
+	if err != nil {
+		return nil, err
+	}
+
+	return miners, nil
+}
+
+func (s *state12) ForEachClaim(cb func(miner address.Address, claim Claim) error) error {
+	claims, err := s.claims()
+	if err != nil {
+		return err
+	}
+
+	var claim power12.Claim
+	return claims.ForEach(&claim, func(k string) error {
+		a, err := address.NewFromBytes([]byte(k))
+		if err != nil {
+			return err
+		}
+		return cb(a, Claim{
+			RawBytePower:    claim.RawBytePower,
+			QualityAdjPower: claim.QualityAdjPower,
+		})
+	})
+}
+
+func (s *state12) ClaimsChanged(other State) (bool, error) {
+	other12, ok := other.(*state12)
+	if !ok {
+		// treat an upgrade as a change, always
+		return true, nil
+	}
+	return !s.State.Claims.Equals(other12.State.Claims), nil
+}
+
+func (s *state12) SetTotalQualityAdjPower(p abi.StoragePower) error {
+	s.State.TotalQualityAdjPower = p
+	return nil
+}
+
+func (s *state12) SetTotalRawBytePower(p abi.StoragePower) error {
+	s.State.TotalRawBytePower = p
+	return nil
+}
+
+func (s *state12) SetThisEpochQualityAdjPower(p abi.StoragePower) error {
+	s.State.ThisEpochQualityAdjPower = p
+	return nil
+}
+
+func (s *state12) SetThisEpochRawBytePower(p abi.StoragePower) error {
+	s.State.ThisEpochRawBytePower = p
+	return nil
+}
+
+func (s *state12) GetState() interface{} {
+	return &s.State
+}
+
+func (s *state12) claims() (adt.Map, error) {
+	return adt12.AsMap(s.store, s.Claims, builtin12.DefaultHamtBitwidth)
+}
+
+func (s *state12) decodeClaim(val *cbg.Deferred) (Claim, error) {
+	var ci power12.Claim
+	if err := ci.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil {
+		return Claim{}, err
+	}
+	return fromV12Claim(ci), nil
+}
+
+func fromV12Claim(v12 power12.Claim) Claim {
+	return Claim{
+		RawBytePower:    v12.RawBytePower,
+		QualityAdjPower: v12.QualityAdjPower,
+	}
+}
+
+func (s *state12) ActorKey() string {
+	return manifest.PowerKey
+}
+
+func (s *state12) ActorVersion() actorstypes.Version {
+	return actorstypes.Version12
+}
+
+func (s *state12) Code() cid.Cid {
+	code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey())
+	if !ok {
+		panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion()))
+	}
+
+	return code
+}
diff --git a/chain/actors/builtin/registry.go b/chain/actors/builtin/registry.go
index 4addbd45118..6ba5fef03b2 100644
--- a/chain/actors/builtin/registry.go
+++ b/chain/actors/builtin/registry.go
@@ -42,6 +42,22 @@ import (
 	reward11 "github.com/filecoin-project/go-state-types/builtin/v11/reward"
 	system11 "github.com/filecoin-project/go-state-types/builtin/v11/system"
 	verifreg11 "github.com/filecoin-project/go-state-types/builtin/v11/verifreg"
+	account12 "github.com/filecoin-project/go-state-types/builtin/v12/account"
+	cron12 "github.com/filecoin-project/go-state-types/builtin/v12/cron"
+	datacap12 "github.com/filecoin-project/go-state-types/builtin/v12/datacap"
+	eam12 "github.com/filecoin-project/go-state-types/builtin/v12/eam"
+	ethaccount12 "github.com/filecoin-project/go-state-types/builtin/v12/ethaccount"
+	evm12 "github.com/filecoin-project/go-state-types/builtin/v12/evm"
+	_init12 "github.com/filecoin-project/go-state-types/builtin/v12/init"
+	market12 "github.com/filecoin-project/go-state-types/builtin/v12/market"
+	miner12 "github.com/filecoin-project/go-state-types/builtin/v12/miner"
+	multisig12 "github.com/filecoin-project/go-state-types/builtin/v12/multisig"
+	paych12 "github.com/filecoin-project/go-state-types/builtin/v12/paych"
+	placeholder12 "github.com/filecoin-project/go-state-types/builtin/v12/placeholder"
+	power12 "github.com/filecoin-project/go-state-types/builtin/v12/power"
+	reward12 "github.com/filecoin-project/go-state-types/builtin/v12/reward"
+	system12 "github.com/filecoin-project/go-state-types/builtin/v12/system"
+	verifreg12 "github.com/filecoin-project/go-state-types/builtin/v12/verifreg"
 	account8 "github.com/filecoin-project/go-state-types/builtin/v8/account"
 	cron8 "github.com/filecoin-project/go-state-types/builtin/v8/cron"
 	_init8 "github.com/filecoin-project/go-state-types/builtin/v8/init"
@@ -497,6 +513,110 @@ func MakeRegistry(av actorstypes.Version) []RegistryEntry {
 			}
 		}
 
+	case actorstypes.Version12:
+		for key, codeID := range codeIDs {
+			switch key {
+			case manifest.AccountKey:
+				registry = append(registry, RegistryEntry{
+					code:    codeID,
+					methods: account12.Methods,
+					state:   new(account12.State),
+				})
+			case manifest.CronKey:
+				registry = append(registry, RegistryEntry{
+					code:    codeID,
+					methods: cron12.Methods,
+					state:   new(cron12.State),
+				})
+			case manifest.InitKey:
+				registry = append(registry, RegistryEntry{
+					code:    codeID,
+					methods: _init12.Methods,
+					state:   new(_init12.State),
+				})
+			case manifest.MarketKey:
+				registry = append(registry, RegistryEntry{
+					code:    codeID,
+					methods: market12.Methods,
+					state:   new(market12.State),
+				})
+			case manifest.MinerKey:
+				registry = append(registry, RegistryEntry{
+					code:    codeID,
+					methods: miner12.Methods,
+					state:   new(miner12.State),
+				})
+			case manifest.MultisigKey:
+				registry = append(registry, RegistryEntry{
+					code:    codeID,
+					methods: multisig12.Methods,
+					state:   new(multisig12.State),
+				})
+			case manifest.PaychKey:
+				registry = append(registry, RegistryEntry{
+					code:    codeID,
+					methods: paych12.Methods,
+					state:   new(paych12.State),
+				})
+			case manifest.PowerKey:
+				registry = append(registry, RegistryEntry{
+					code:    codeID,
+					methods: power12.Methods,
+					state:   new(power12.State),
+				})
+			case manifest.RewardKey:
+				registry = append(registry, RegistryEntry{
+					code:    codeID,
+					methods: reward12.Methods,
+					state:   new(reward12.State),
+				})
+			case manifest.SystemKey:
+				registry = append(registry, RegistryEntry{
+					code:    codeID,
+					methods: system12.Methods,
+					state:   new(system12.State),
+				})
+			case manifest.VerifregKey:
+				registry = append(registry, RegistryEntry{
+					code:    codeID,
+					methods: verifreg12.Methods,
+					state:   new(verifreg12.State),
+				})
+			case manifest.DatacapKey:
+				registry = append(registry, RegistryEntry{
+					code:    codeID,
+					methods: datacap12.Methods,
+					state:   new(datacap12.State),
+				})
+
+			case manifest.EvmKey:
+				registry = append(registry, RegistryEntry{
+					code:    codeID,
+					methods: evm12.Methods,
+					state:   new(evm12.State),
+				})
+			case manifest.EamKey:
+				registry = append(registry, RegistryEntry{
+					code:    codeID,
+					methods: eam12.Methods,
+					state:   nil,
+				})
+			case manifest.PlaceholderKey:
+				registry = append(registry, RegistryEntry{
+					code:    codeID,
+					methods: placeholder12.Methods,
+					state:   nil,
+				})
+			case manifest.EthAccountKey:
+				registry = append(registry, RegistryEntry{
+					code:    codeID,
+					methods: ethaccount12.Methods,
+					state:   nil,
+				})
+
+			}
+		}
+
 	default:
 		panic("expected version v8 and up only, use specs-actors for v0-7")
 	}
diff --git a/chain/actors/builtin/reward/reward.go b/chain/actors/builtin/reward/reward.go
index b0060a21775..3c646364585 100644
--- a/chain/actors/builtin/reward/reward.go
+++ b/chain/actors/builtin/reward/reward.go
@@ -6,7 +6,7 @@ import (
 
 	"github.com/filecoin-project/go-state-types/abi"
 	actorstypes "github.com/filecoin-project/go-state-types/actors"
-	builtin11 "github.com/filecoin-project/go-state-types/builtin"
+	builtin12 "github.com/filecoin-project/go-state-types/builtin"
 	"github.com/filecoin-project/go-state-types/cbor"
 	"github.com/filecoin-project/go-state-types/manifest"
 	builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
@@ -25,8 +25,8 @@ import (
 )
 
 var (
-	Address = builtin11.RewardActorAddr
-	Methods = builtin11.MethodsReward
+	Address = builtin12.RewardActorAddr
+	Methods = builtin12.MethodsReward
 )
 
 func Load(store adt.Store, act *types.Actor) (State, error) {
@@ -49,6 +49,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) {
 		case actorstypes.Version11:
 			return load11(store, act.Head)
 
+		case actorstypes.Version12:
+			return load12(store, act.Head)
+
 		}
 	}
 
@@ -116,6 +119,9 @@ func MakeState(store adt.Store, av actorstypes.Version, currRealizedPower abi.St
 	case actorstypes.Version11:
 		return make11(store, currRealizedPower)
 
+	case actorstypes.Version12:
+		return make12(store, currRealizedPower)
+
 	}
 	return nil, xerrors.Errorf("unknown actor version %d", av)
 }
@@ -159,5 +165,6 @@ func AllCodes() []cid.Cid {
 		(&state9{}).Code(),
 		(&state10{}).Code(),
 		(&state11{}).Code(),
+		(&state12{}).Code(),
 	}
 }
diff --git a/chain/actors/builtin/reward/v12.go b/chain/actors/builtin/reward/v12.go
new file mode 100644
index 00000000000..ecc8ff5a0c4
--- /dev/null
+++ b/chain/actors/builtin/reward/v12.go
@@ -0,0 +1,120 @@
+package reward
+
+import (
+	"fmt"
+
+	"github.com/ipfs/go-cid"
+
+	"github.com/filecoin-project/go-state-types/abi"
+	actorstypes "github.com/filecoin-project/go-state-types/actors"
+	miner12 "github.com/filecoin-project/go-state-types/builtin/v12/miner"
+	reward12 "github.com/filecoin-project/go-state-types/builtin/v12/reward"
+	smoothing12 "github.com/filecoin-project/go-state-types/builtin/v12/util/smoothing"
+	"github.com/filecoin-project/go-state-types/manifest"
+
+	"github.com/filecoin-project/lotus/chain/actors"
+	"github.com/filecoin-project/lotus/chain/actors/adt"
+	"github.com/filecoin-project/lotus/chain/actors/builtin"
+)
+
+var _ State = (*state12)(nil)
+
+func load12(store adt.Store, root cid.Cid) (State, error) {
+	out := state12{store: store}
+	err := store.Get(store.Context(), root, &out)
+	if err != nil {
+		return nil, err
+	}
+	return &out, nil
+}
+
+func make12(store adt.Store, currRealizedPower abi.StoragePower) (State, error) {
+	out := state12{store: store}
+	out.State = *reward12.ConstructState(currRealizedPower)
+	return &out, nil
+}
+
+type state12 struct {
+	reward12.State
+	store adt.Store
+}
+
+func (s *state12) ThisEpochReward() (abi.TokenAmount, error) {
+	return s.State.ThisEpochReward, nil
+}
+
+func (s *state12) ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) {
+
+	return builtin.FilterEstimate{
+		PositionEstimate: s.State.ThisEpochRewardSmoothed.PositionEstimate,
+		VelocityEstimate: s.State.ThisEpochRewardSmoothed.VelocityEstimate,
+	}, nil
+
+}
+
+func (s *state12) ThisEpochBaselinePower() (abi.StoragePower, error) {
+	return s.State.ThisEpochBaselinePower, nil
+}
+
+func (s *state12) TotalStoragePowerReward() (abi.TokenAmount, error) {
+	return s.State.TotalStoragePowerReward, nil
+}
+
+func (s *state12) EffectiveBaselinePower() (abi.StoragePower, error) {
+	return s.State.EffectiveBaselinePower, nil
+}
+
+func (s *state12) EffectiveNetworkTime() (abi.ChainEpoch, error) {
+	return s.State.EffectiveNetworkTime, nil
+}
+
+func (s *state12) CumsumBaseline() (reward12.Spacetime, error) {
+	return s.State.CumsumBaseline, nil
+}
+
+func (s *state12) CumsumRealized() (reward12.Spacetime, error) {
+	return s.State.CumsumRealized, nil
+}
+
+func (s *state12) InitialPledgeForPower(qaPower abi.StoragePower, networkTotalPledge abi.TokenAmount, networkQAPower *builtin.FilterEstimate, circSupply abi.TokenAmount) (abi.TokenAmount, error) {
+	return miner12.InitialPledgeForPower(
+		qaPower,
+		s.State.ThisEpochBaselinePower,
+		s.State.ThisEpochRewardSmoothed,
+		smoothing12.FilterEstimate{
+			PositionEstimate: networkQAPower.PositionEstimate,
+			VelocityEstimate: networkQAPower.VelocityEstimate,
+		},
+		circSupply,
+	), nil
+}
+
+func (s *state12) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, sectorWeight abi.StoragePower) (abi.TokenAmount, error) {
+	return miner12.PreCommitDepositForPower(s.State.ThisEpochRewardSmoothed,
+		smoothing12.FilterEstimate{
+			PositionEstimate: networkQAPower.PositionEstimate,
+			VelocityEstimate: networkQAPower.VelocityEstimate,
+		},
+		sectorWeight), nil
+}
+
+func (s *state12) GetState() interface{} {
+	return &s.State
+}
+
+func (s *state12) ActorKey() string {
+	return manifest.RewardKey
+}
+
+func (s *state12) ActorVersion() actorstypes.Version {
+	return actorstypes.Version12
+}
+
+func (s *state12) Code() cid.Cid {
+	code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey())
+	if !ok {
+		panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion()))
+	}
+
+	return code
+}
diff --git a/chain/actors/builtin/system/system.go b/chain/actors/builtin/system/system.go
index 4db8db610ea..2a2b703bb1c 100644
--- a/chain/actors/builtin/system/system.go
+++ b/chain/actors/builtin/system/system.go
@@ -5,7 +5,7 @@ import (
 	"golang.org/x/xerrors"
 
 	actorstypes "github.com/filecoin-project/go-state-types/actors"
-	builtin11 "github.com/filecoin-project/go-state-types/builtin"
+	builtin12 "github.com/filecoin-project/go-state-types/builtin"
 	"github.com/filecoin-project/go-state-types/manifest"
 	builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
 	builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
@@ -21,7 +21,7 @@ import (
 )
 
 var (
-	Address = builtin11.SystemActorAddr
+	Address = builtin12.SystemActorAddr
 )
 
 func Load(store adt.Store, act *types.Actor) (State, error) {
@@ -44,6 +44,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) {
 		case actorstypes.Version11:
 			return load11(store, act.Head)
 
+		case actorstypes.Version12:
+			return load12(store, act.Head)
+
 		}
 	}
 
@@ -111,6 +114,9 @@ func MakeState(store adt.Store, av actorstypes.Version, builtinActors cid.Cid) (
 	case actorstypes.Version11:
 		return make11(store, builtinActors)
 
+	case actorstypes.Version12:
+		return make12(store, builtinActors)
+
 	}
 	return nil, xerrors.Errorf("unknown actor version %d", av)
 }
@@ -138,5 +144,6 @@ func AllCodes() []cid.Cid {
 		(&state9{}).Code(),
 		(&state10{}).Code(),
 		(&state11{}).Code(),
+		(&state12{}).Code(),
 	}
 }
diff --git a/chain/actors/builtin/system/v12.go b/chain/actors/builtin/system/v12.go
new file mode 100644
index 00000000000..71938e799f6
--- /dev/null
+++ b/chain/actors/builtin/system/v12.go
@@ -0,0 +1,72 @@
+package system
+
+import (
+	"fmt"
+
+	"github.com/ipfs/go-cid"
+
+	actorstypes "github.com/filecoin-project/go-state-types/actors"
+	system12 "github.com/filecoin-project/go-state-types/builtin/v12/system"
+	"github.com/filecoin-project/go-state-types/manifest"
+
+	"github.com/filecoin-project/lotus/chain/actors"
+	"github.com/filecoin-project/lotus/chain/actors/adt"
+)
+
+var _ State = (*state12)(nil)
+
+func load12(store adt.Store, root cid.Cid) (State, error) {
+	out := state12{store: store}
+	err := store.Get(store.Context(), root, &out)
+	if err != nil {
+		return nil, err
+	}
+	return &out, nil
+}
+
+func make12(store adt.Store, builtinActors cid.Cid) (State, error) {
+	out := state12{store: store}
+	out.State = system12.State{
+		BuiltinActors: builtinActors,
+	}
+	return &out, nil
+}
+
+type state12 struct {
+	system12.State
+	store adt.Store
+}
+
+func (s *state12) GetState() interface{} {
+	return &s.State
+}
+
+func (s *state12) GetBuiltinActors() cid.Cid {
+
+	return s.State.BuiltinActors
+
+}
+
+func (s *state12) SetBuiltinActors(c cid.Cid) error {
+
+	s.State.BuiltinActors = c
+	return nil
+
+}
+
+func (s *state12) ActorKey() string {
+	return manifest.SystemKey
+}
+
+func (s *state12) ActorVersion() actorstypes.Version {
+	return actorstypes.Version12
+}
+
+func (s *state12) Code() cid.Cid {
+	code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey())
+	if !ok {
+		panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion()))
+	}
+
+	return code
+}
diff --git a/chain/actors/builtin/verifreg/actor.go.template b/chain/actors/builtin/verifreg/actor.go.template
index 9b779a68df5..991c6717bd7 100644
--- a/chain/actors/builtin/verifreg/actor.go.template
+++ b/chain/actors/builtin/verifreg/actor.go.template
@@ -97,4 +97,6 @@ func AllCodes() []cid.Cid {
 type Allocation = verifregtypes.Allocation
 type AllocationId = verifregtypes.AllocationId
 type Claim = verifregtypes.Claim
-type ClaimId = verifregtypes.ClaimId
\ No newline at end of file
+type ClaimId = verifregtypes.ClaimId
+
+const NoAllocationID = verifregtypes.NoAllocationID
diff --git a/chain/actors/builtin/verifreg/v12.go b/chain/actors/builtin/verifreg/v12.go
new file mode 100644
index 00000000000..77a113fbe86
--- /dev/null
+++ b/chain/actors/builtin/verifreg/v12.go
@@ -0,0 +1,170 @@
+package verifreg
+
+import (
+	"fmt"
+
+	"github.com/ipfs/go-cid"
+	"golang.org/x/xerrors"
+
+	"github.com/filecoin-project/go-address"
+	"github.com/filecoin-project/go-state-types/abi"
+	actorstypes "github.com/filecoin-project/go-state-types/actors"
+	"github.com/filecoin-project/go-state-types/big"
+	builtin12 "github.com/filecoin-project/go-state-types/builtin"
+	adt12 "github.com/filecoin-project/go-state-types/builtin/v12/util/adt"
+	verifreg12 "github.com/filecoin-project/go-state-types/builtin/v12/verifreg"
+	verifreg9 "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
+	"github.com/filecoin-project/go-state-types/manifest"
+
+	"github.com/filecoin-project/lotus/chain/actors"
+	"github.com/filecoin-project/lotus/chain/actors/adt"
+)
+
+var _ State = (*state12)(nil)
+
+func load12(store adt.Store, root cid.Cid) (State, error) {
+	out := state12{store: store}
+	err := store.Get(store.Context(), root, &out)
+	if err != nil {
+		return nil, err
+	}
+	return &out, nil
+}
+
+func make12(store adt.Store, rootKeyAddress address.Address) (State, error) {
+	out := state12{store: store}
+
+	s, err := verifreg12.ConstructState(store, rootKeyAddress)
+	if err != nil {
+		return nil, err
+	}
+
+	out.State = *s
+
+	return &out, nil
+}
+
+type state12 struct {
+	verifreg12.State
+	store adt.Store
+}
+
+func (s *state12) RootKey() (address.Address, error) {
+	return s.State.RootKey, nil
+}
+
+func (s *state12) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) {
+
+	return false, big.Zero(), xerrors.Errorf("unsupported in actors v12")
+
+}
+
+func (s *state12) VerifierDataCap(addr address.Address) (bool, abi.StoragePower, error) {
+	return getDataCap(s.store, actors.Version12, s.verifiers, addr)
+}
+
+func (s *state12) RemoveDataCapProposalID(verifier address.Address, client address.Address) (bool, uint64, error) {
+	return getRemoveDataCapProposalID(s.store, actors.Version12, s.removeDataCapProposalIDs, verifier, client)
+}
+
+func (s *state12) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error {
+	return forEachCap(s.store, actors.Version12, s.verifiers, cb)
+}
+
+func (s *state12) ForEachClient(cb func(addr address.Address, dcap abi.StoragePower) error) error {
+
+	return xerrors.Errorf("unsupported in actors v12")
+
+}
+
+func (s *state12) verifiedClients() (adt.Map, error) {
+
+	return nil, xerrors.Errorf("unsupported in actors v12")
+
+}
+
+func (s *state12) verifiers() (adt.Map, error) {
+	return adt12.AsMap(s.store, s.Verifiers, builtin12.DefaultHamtBitwidth)
+}
+
+func (s *state12) removeDataCapProposalIDs() (adt.Map, error) {
+	return adt12.AsMap(s.store, s.RemoveDataCapProposalIDs, builtin12.DefaultHamtBitwidth)
+}
+
+func (s *state12) GetState() interface{} {
+	return &s.State
+}
+
+func (s *state12) GetAllocation(clientIdAddr address.Address, allocationId verifreg9.AllocationId) (*Allocation, bool, error) {
+
+	alloc, ok, err := s.FindAllocation(s.store, clientIdAddr, verifreg12.AllocationId(allocationId))
+	return (*Allocation)(alloc), ok, err
+}
+
+func (s *state12) GetAllocations(clientIdAddr address.Address) (map[AllocationId]Allocation, error) {
+
+	v12Map, err := s.LoadAllocationsToMap(s.store, clientIdAddr)
+
+	retMap := make(map[AllocationId]Allocation, len(v12Map))
+	for k, v := range v12Map {
+		retMap[AllocationId(k)] = Allocation(v)
+	}
+
+	return retMap, err
+
+}
+
+func (s *state12) GetClaim(providerIdAddr address.Address, claimId verifreg9.ClaimId) (*Claim, bool, error) {
+
+	claim, ok, err := s.FindClaim(s.store, providerIdAddr, verifreg12.ClaimId(claimId))
+	return (*Claim)(claim), ok, err
+
+}
+
+func (s *state12) GetClaims(providerIdAddr address.Address) (map[ClaimId]Claim, error) {
+
+	v12Map, err := s.LoadClaimsToMap(s.store, providerIdAddr)
+
+	retMap := make(map[ClaimId]Claim, len(v12Map))
+	for k, v := range v12Map {
+		retMap[ClaimId(k)] = Claim(v)
+	}
+
+	return retMap, err
+
+}
+
+func (s *state12) GetClaimIdsBySector(providerIdAddr address.Address) (map[abi.SectorNumber][]ClaimId, error) {
+
+	v12Map, err := s.LoadClaimsToMap(s.store, providerIdAddr)
+
+	retMap := make(map[abi.SectorNumber][]ClaimId)
+	for k, v := range v12Map {
+		claims, ok := retMap[v.Sector]
+		if !ok {
+			retMap[v.Sector] = []ClaimId{ClaimId(k)}
+		} else {
+			retMap[v.Sector] = append(claims, ClaimId(k))
+		}
+	}
+
+	return retMap, err
+
+}
+
+func (s *state12) ActorKey() string {
+	return manifest.VerifregKey
+}
+
+func (s *state12) ActorVersion() actorstypes.Version {
+	return actorstypes.Version12
+}
+
+func (s *state12) Code() cid.Cid {
+	code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey())
+	if !ok {
+		panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion()))
+	}
+
+	return code
+}
diff --git a/chain/actors/builtin/verifreg/verifreg.go b/chain/actors/builtin/verifreg/verifreg.go
index eb911ea4608..de906f52127 100644
--- a/chain/actors/builtin/verifreg/verifreg.go
+++ b/chain/actors/builtin/verifreg/verifreg.go
@@ -7,7 +7,7 @@ import (
 	"github.com/filecoin-project/go-address"
 	"github.com/filecoin-project/go-state-types/abi"
 	actorstypes "github.com/filecoin-project/go-state-types/actors"
-	builtin11 "github.com/filecoin-project/go-state-types/builtin"
+	builtin12 "github.com/filecoin-project/go-state-types/builtin"
 	verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
 	"github.com/filecoin-project/go-state-types/cbor"
 	"github.com/filecoin-project/go-state-types/manifest"
@@ -25,8 +25,8 @@ import (
 )
 
 var (
-	Address = builtin11.VerifiedRegistryActorAddr
-	Methods = builtin11.MethodsVerifiedRegistry
+	Address = builtin12.VerifiedRegistryActorAddr
+	Methods = builtin12.MethodsVerifiedRegistry
 )
 
 func Load(store adt.Store, act *types.Actor) (State, error) {
@@ -49,6 +49,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) {
 		case actorstypes.Version11:
 			return load11(store, act.Head)
 
+		case actorstypes.Version12:
+			return load12(store, act.Head)
+
 		}
 	}
 
@@ -116,6 +119,9 @@ func MakeState(store adt.Store, av actorstypes.Version, rootKeyAddress address.A
 	case actorstypes.Version11:
 		return make11(store, rootKeyAddress)
 
+	case actorstypes.Version12:
+		return make12(store, rootKeyAddress)
+
 	}
 	return nil, xerrors.Errorf("unknown actor version %d", av)
 }
@@ -154,6 +160,7 @@ func AllCodes() []cid.Cid {
 		(&state9{}).Code(),
 		(&state10{}).Code(),
 		(&state11{}).Code(),
+		(&state12{}).Code(),
 	}
 }
 
@@ -161,3 +168,5 @@ type Allocation = verifregtypes.Allocation
 type AllocationId = verifregtypes.AllocationId
 type Claim = verifregtypes.Claim
 type ClaimId = verifregtypes.ClaimId
+
+const NoAllocationID = verifregtypes.NoAllocationID
diff --git a/chain/actors/manifest.go b/chain/actors/manifest.go
index f58768ca24b..62c17193a57 100644
--- a/chain/actors/manifest.go
+++ b/chain/actors/manifest.go
@@ -51,6 +51,12 @@ func RegisterManifest(av actorstypes.Version, manifestCid cid.Cid, entries map[s
 	}
 }
 
+func AddActorMeta(name string, codeId cid.Cid, av actorstypes.Version) {
+	manifestMx.Lock()
+	defer manifestMx.Unlock()
+	actorMeta[codeId] = actorEntry{name: name, version: av}
+}
+
 // GetManifest gets a loaded manifest.
 func GetManifest(av actorstypes.Version) (cid.Cid, bool) {
 	manifestMx.RLock()
diff --git a/chain/actors/policy/policy.go b/chain/actors/policy/policy.go
index bf982af8904..a0e4728fe1a 100644
--- a/chain/actors/policy/policy.go
+++ b/chain/actors/policy/policy.go
@@ -8,6 +8,7 @@ import (
 	"github.com/filecoin-project/go-state-types/big"
 	builtin10 "github.com/filecoin-project/go-state-types/builtin"
 	builtin11 "github.com/filecoin-project/go-state-types/builtin"
+	builtin12 "github.com/filecoin-project/go-state-types/builtin"
 	builtin8 "github.com/filecoin-project/go-state-types/builtin"
 	builtin9 "github.com/filecoin-project/go-state-types/builtin"
 	market10 "github.com/filecoin-project/go-state-types/builtin/v10/market"
@@ -15,8 +16,11 @@ import (
 	verifreg10 "github.com/filecoin-project/go-state-types/builtin/v10/verifreg"
 	market11 "github.com/filecoin-project/go-state-types/builtin/v11/market"
 	miner11 "github.com/filecoin-project/go-state-types/builtin/v11/miner"
-	paych11 "github.com/filecoin-project/go-state-types/builtin/v11/paych"
 	verifreg11 "github.com/filecoin-project/go-state-types/builtin/v11/verifreg"
+	market12 "github.com/filecoin-project/go-state-types/builtin/v12/market"
+	miner12 "github.com/filecoin-project/go-state-types/builtin/v12/miner"
+	paych12 "github.com/filecoin-project/go-state-types/builtin/v12/paych"
+	verifreg12 "github.com/filecoin-project/go-state-types/builtin/v12/verifreg"
 	market8 "github.com/filecoin-project/go-state-types/builtin/v8/market"
 	miner8 "github.com/filecoin-project/go-state-types/builtin/v8/miner"
 	verifreg8 "github.com/filecoin-project/go-state-types/builtin/v8/verifreg"
@@ -55,14 +59,14 @@ import (
 )
 
 const (
-	ChainFinality                  = miner11.ChainFinality
+	ChainFinality                  = miner12.ChainFinality
 	SealRandomnessLookback         = ChainFinality
-	PaychSettleDelay               = paych11.SettleDelay
-	MaxPreCommitRandomnessLookback = builtin11.EpochsInDay + SealRandomnessLookback
+	PaychSettleDelay               = paych12.SettleDelay
+	MaxPreCommitRandomnessLookback = builtin12.EpochsInDay + SealRandomnessLookback
 )
 
 var (
-	MarketDefaultAllocationTermBuffer = market11.MarketDefaultAllocationTermBuffer
+	MarketDefaultAllocationTermBuffer = market12.MarketDefaultAllocationTermBuffer
 )
 
 // SetSupportedProofTypes sets supported proof types, across all actor versions.
@@ -175,11 +179,13 @@ func SetPreCommitChallengeDelay(delay abi.ChainEpoch) {
 
 	miner11.PreCommitChallengeDelay = delay
 
+	miner12.PreCommitChallengeDelay = delay
+
 }
 
 // TODO: this function shouldn't really exist. Instead, the API should expose the precommit delay.
 func GetPreCommitChallengeDelay() abi.ChainEpoch {
-	return miner11.PreCommitChallengeDelay
+	return miner12.PreCommitChallengeDelay
 }
 
 // SetConsensusMinerMinPower sets the minimum power of an individual miner must
@@ -229,6 +235,10 @@ func SetConsensusMinerMinPower(p abi.StoragePower) {
 		policy.ConsensusMinerMinPower = p
 	}
 
+	for _, policy := range builtin12.PoStProofPolicies {
+		policy.ConsensusMinerMinPower = p
+	}
+
 }
 
 // SetMinVerifiedDealSize sets the minimum size of a verified deal. This should
@@ -257,6 +267,8 @@ func SetMinVerifiedDealSize(size abi.StoragePower) {
 
 	verifreg11.MinVerifiedDealSize = size
 
+	verifreg12.MinVerifiedDealSize = size
+
 }
 
 func GetMaxProveCommitDuration(ver actorstypes.Version, t abi.RegisteredSealProof) (abi.ChainEpoch, error) {
@@ -306,6 +318,10 @@ func GetMaxProveCommitDuration(ver actorstypes.Version, t abi.RegisteredSealProo
 
 		return miner11.MaxProveCommitDuration[t], nil
 
+	case actorstypes.Version12:
+
+		return miner12.MaxProveCommitDuration[t], nil
+
 	default:
 		return 0, xerrors.Errorf("unsupported actors version")
 	}
@@ -366,6 +382,11 @@ func SetProviderCollateralSupplyTarget(num, denom big.Int) {
 		Denominator: denom,
 	}
 
+	market12.ProviderCollateralSupplyTarget = builtin12.BigFrac{
+		Numerator:   num,
+		Denominator: denom,
+	}
+
 }
 
 func DealProviderCollateralBounds(
@@ -434,13 +455,18 @@ func DealProviderCollateralBounds(
 		min, max := market11.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil)
 		return min, max, nil
 
+	case actorstypes.Version12:
+
+		min, max := market12.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil)
+		return min, max, nil
+
 	default:
 		return big.Zero(), big.Zero(), xerrors.Errorf("unsupported actors version")
 	}
 }
 
 func DealDurationBounds(pieceSize abi.PaddedPieceSize) (min, max abi.ChainEpoch) {
-	return market11.DealDurationBounds(pieceSize)
+	return market12.DealDurationBounds(pieceSize)
 }
 
 // Sets the challenge window and scales the proving period to match (such that
@@ -516,6 +542,13 @@ func SetWPoStChallengeWindow(period abi.ChainEpoch) {
 	// scale it if we're scaling the challenge period.
 	miner11.WPoStDisputeWindow = period * 30
 
+	miner12.WPoStChallengeWindow = period
+	miner12.WPoStProvingPeriod = period * abi.ChainEpoch(miner12.WPoStPeriodDeadlines)
+
+	// by default, this is 2x finality which is 30 periods.
+	// scale it if we're scaling the challenge period.
+	miner12.WPoStDisputeWindow = period * 30
+
 }
 
 func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch {
@@ -527,16 +560,61 @@ func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch {
 	return ChainFinality
 }
 
-func GetMaxSectorExpirationExtension() abi.ChainEpoch {
-	return miner11.MaxSectorExpirationExtension
+func GetMaxSectorExpirationExtension(nv network.Version) (abi.ChainEpoch, error) {
+	v, err := actorstypes.VersionForNetwork(nv)
+	if err != nil {
+		return 0, xerrors.Errorf("failed to get actors version: %w", err)
+	}
+	switch v {
+
+	case actorstypes.Version0:
+		return miner0.MaxSectorExpirationExtension, nil
+
+	case actorstypes.Version2:
+		return miner2.MaxSectorExpirationExtension, nil
+
+	case actorstypes.Version3:
+		return miner3.MaxSectorExpirationExtension, nil
+
+	case actorstypes.Version4:
+		return miner4.MaxSectorExpirationExtension, nil
+
+	case actorstypes.Version5:
+		return miner5.MaxSectorExpirationExtension, nil
+
+	case actorstypes.Version6:
+		return miner6.MaxSectorExpirationExtension, nil
+
+	case actorstypes.Version7:
+		return miner7.MaxSectorExpirationExtension, nil
+
+	case actorstypes.Version8:
+		return miner8.MaxSectorExpirationExtension, nil
+
+	case actorstypes.Version9:
+		return miner9.MaxSectorExpirationExtension, nil
+
+	case actorstypes.Version10:
+		return miner10.MaxSectorExpirationExtension, nil
+
+	case actorstypes.Version11:
+		return miner11.MaxSectorExpirationExtension, nil
+
+	case actorstypes.Version12:
+		return miner12.MaxSectorExpirationExtension, nil
+
+	default:
+		return 0, xerrors.Errorf("unsupported network version")
+	}
+
 }
 
 func GetMinSectorExpiration() abi.ChainEpoch {
-	return miner11.MinSectorExpiration
+	return miner12.MinSectorExpiration
 }
 
 func GetMaxPoStPartitions(nv network.Version, p abi.RegisteredPoStProof) (int, error) {
-	sectorsPerPart, err := builtin11.PoStProofWindowPoStPartitionSectors(p)
+	sectorsPerPart, err := builtin12.PoStProofWindowPoStPartitionSectors(p)
 	if err != nil {
 		return 0, err
 	}
@@ -544,7 +622,8 @@ func GetMaxPoStPartitions(nv network.Version, p abi.RegisteredPoStProof) (int, e
 	if err != nil {
 		return 0, err
 	}
-	return int(uint64(maxSectors) / sectorsPerPart), nil
+
+	return min(miner12.PoStedPartitionsMax, int(uint64(maxSectors)/sectorsPerPart)), nil
 }
 
 func GetDefaultAggregationProof() abi.RegisteredAggregationProof {
@@ -556,7 +635,7 @@ func GetSectorMaxLifetime(proof abi.RegisteredSealProof, nwVer network.Version)
 		return builtin4.SealProofPoliciesV0[proof].SectorMaxLifetime
 	}
 
-	return builtin11.SealProofPoliciesV11[proof].SectorMaxLifetime
+	return builtin12.SealProofPoliciesV11[proof].SectorMaxLifetime
 }
 
 func GetAddressedSectorsMax(nwVer network.Version) (int, error) {
@@ -599,6 +678,9 @@ func GetAddressedSectorsMax(nwVer network.Version) (int, error) {
 	case actorstypes.Version11:
 		return miner11.AddressedSectorsMax, nil
 
+	case actorstypes.Version12:
+		return miner12.AddressedSectorsMax, nil
+
 	default:
 		return 0, xerrors.Errorf("unsupported network version")
 	}
@@ -656,6 +738,10 @@ func GetDeclarationsMax(nwVer network.Version) (int, error) {
 
 		return miner11.DeclarationsMax, nil
 
+	case actorstypes.Version12:
+
+		return miner12.DeclarationsMax, nil
+
 	default:
 		return 0, xerrors.Errorf("unsupported network version")
 	}
@@ -712,6 +798,10 @@ func AggregateProveCommitNetworkFee(nwVer network.Version, aggregateSize int, ba
 
 		return miner11.AggregateProveCommitNetworkFee(aggregateSize, baseFee), nil
 
+	case actorstypes.Version12:
+
+		return miner12.AggregateProveCommitNetworkFee(aggregateSize, baseFee), nil
+
 	default:
 		return big.Zero(), xerrors.Errorf("unsupported network version")
 	}
@@ -768,7 +858,18 @@ func AggregatePreCommitNetworkFee(nwVer network.Version, aggregateSize int, base
 
 		return miner11.AggregatePreCommitNetworkFee(aggregateSize, baseFee), nil
 
+	case actorstypes.Version12:
+
+		return miner12.AggregatePreCommitNetworkFee(aggregateSize, baseFee), nil
+
 	default:
 		return big.Zero(), xerrors.Errorf("unsupported network version")
 	}
 }
+
+func min(a, b int) int {
+	if a < b {
+		return a
+	}
+	return b
+}
diff --git a/chain/actors/policy/policy.go.template b/chain/actors/policy/policy.go.template
index 3eb39836ac4..8803c97e6a2 100644
--- a/chain/actors/policy/policy.go.template
+++ b/chain/actors/policy/policy.go.template
@@ -223,8 +223,20 @@ func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch {
 	return ChainFinality
 }
 
-func GetMaxSectorExpirationExtension() abi.ChainEpoch {
-	return miner{{.latestVersion}}.MaxSectorExpirationExtension
+func GetMaxSectorExpirationExtension(nv network.Version) (abi.ChainEpoch, error) {
+	v, err := actorstypes.VersionForNetwork(nv)
+	if err != nil {
+		return 0, xerrors.Errorf("failed to get actors version: %w", err)
+	}
+	switch v {
+		{{range .versions}}
+			case actorstypes.Version{{.}}:
+				return miner{{.}}.MaxSectorExpirationExtension, nil
+		{{end}}
+	default:
+		return 0, xerrors.Errorf("unsupported network version")
+	}
+
 }
 
 func GetMinSectorExpiration() abi.ChainEpoch {
@@ -240,7 +252,8 @@ func GetMaxPoStPartitions(nv network.Version, p abi.RegisteredPoStProof) (int, e
 	if err != nil {
 		return 0, err
 	}
-	return int(uint64(maxSectors) / sectorsPerPart), nil
+
+	return min(miner{{.latestVersion}}.PoStedPartitionsMax, int(uint64(maxSectors) / sectorsPerPart)), nil
 }
 
 func GetDefaultAggregationProof() abi.RegisteredAggregationProof {
@@ -329,3 +342,10 @@ func AggregatePreCommitNetworkFee(nwVer network.Version, aggregateSize int, base
 		return big.Zero(), xerrors.Errorf("unsupported network version")
 	}
 }
+
+func min(a, b int) int {
+    if a < b {
+        return a
+    }
+    return b
+}
\ No newline at end of file
diff --git a/chain/actors/policy/policy_test.go b/chain/actors/policy/policy_test.go
index 726fca95a07..5fd4bd7b094 100644
--- a/chain/actors/policy/policy_test.go
+++ b/chain/actors/policy/policy_test.go
@@ -7,7 +7,6 @@ import (
 	"github.com/stretchr/testify/require"
 
 	"github.com/filecoin-project/go-state-types/abi"
-	"github.com/filecoin-project/go-state-types/network"
 	builtin0 "github.com/filecoin-project/specs-actors/actors/builtin"
 	miner0 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
 	paych0 "github.com/filecoin-project/specs-actors/actors/builtin/paych"
@@ -74,13 +73,3 @@ func TestPartitionSizes(t *testing.T) {
 		require.Equal(t, sizeOld, sizeNew)
 	}
 }
-
-func TestPoStSize(t *testing.T) {
-	//stm: @BLOCKCHAIN_POLICY_GET_MAX_POST_PARTITIONS_001
-	v12PoStSize, err := GetMaxPoStPartitions(network.Version12, abi.RegisteredPoStProof_StackedDrgWindow64GiBV1)
-	require.Equal(t, 4, v12PoStSize)
-	require.NoError(t, err)
-	v13PoStSize, err := GetMaxPoStPartitions(network.Version13, abi.RegisteredPoStProof_StackedDrgWindow64GiBV1)
-	require.NoError(t, err)
-	require.Equal(t, 10, v13PoStSize)
-}
diff --git a/chain/actors/version.go b/chain/actors/version.go
index 3a5b935bfd4..92c0da00687 100644
--- a/chain/actors/version.go
+++ b/chain/actors/version.go
@@ -14,9 +14,9 @@ const ({{range .actorVersions}}
 
 /* inline-gen start */
 
-var LatestVersion = 11
+var LatestVersion = 12
 
-var Versions = []int{0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
+var Versions = []int{0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
 
 const (
 	Version0  Version = 0
@@ -30,6 +30,7 @@ const (
 	Version9  Version = 9
 	Version10 Version = 10
 	Version11 Version = 11
+	Version12 Version = 12
 )
 
 /* inline-gen end */
diff --git a/chain/badtscache.go b/chain/badtscache.go
index 0f215dcdc22..162e6b7a701 100644
--- a/chain/badtscache.go
+++ b/chain/badtscache.go
@@ -3,14 +3,14 @@ package chain
 import (
 	"fmt"
 
-	lru "github.com/hashicorp/golang-lru/v2"
+	"github.com/hashicorp/golang-lru/arc/v2"
 	"github.com/ipfs/go-cid"
 
 	"github.com/filecoin-project/lotus/build"
 )
 
 type BadBlockCache struct {
-	badBlocks *lru.ARCCache[cid.Cid, BadBlockReason]
+	badBlocks *arc.ARCCache[cid.Cid, BadBlockReason]
 }
 
 type BadBlockReason struct {
@@ -43,7 +43,7 @@ func (bbr BadBlockReason) String() string {
 }
 
 func NewBadBlockCache() *BadBlockCache {
-	cache, err := lru.NewARC[cid.Cid, BadBlockReason](build.BadBlockCacheSize)
+	cache, err := arc.NewARC[cid.Cid, BadBlockReason](build.BadBlockCacheSize)
 	if err != nil {
 		panic(err) // ok
 	}
diff --git a/chain/consensus/compute_state.go b/chain/consensus/compute_state.go
index 64b9624ea2b..1edeb60b7e3 100644
--- a/chain/consensus/compute_state.go
+++ b/chain/consensus/compute_state.go
@@ -52,6 +52,7 @@ func NewActorRegistry() *vm.ActorRegistry {
 	inv.Register(actorstypes.Version9, vm.ActorsVersionPredicate(actorstypes.Version9), builtin.MakeRegistry(actorstypes.Version9))
 	inv.Register(actorstypes.Version10, vm.ActorsVersionPredicate(actorstypes.Version10), builtin.MakeRegistry(actorstypes.Version10))
 	inv.Register(actorstypes.Version11, vm.ActorsVersionPredicate(actorstypes.Version11), builtin.MakeRegistry(actorstypes.Version11))
+	inv.Register(actorstypes.Version12, vm.ActorsVersionPredicate(actorstypes.Version12), builtin.MakeRegistry(actorstypes.Version12))
 
 	return inv
 }
@@ -80,7 +81,7 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context,
 	pstate cid.Cid,
 	bms []FilecoinBlockMessages,
 	epoch abi.ChainEpoch,
-	r vm.Rand,
+	r rand.Rand,
 	em stmgr.ExecMonitor,
 	vmTracing bool,
 	baseFee abi.TokenAmount,
diff --git a/chain/consensus/filcns/filecoin.go b/chain/consensus/filcns/filecoin.go
index fd49f1c9a33..b5ec13a6090 100644
--- a/chain/consensus/filcns/filecoin.go
+++ b/chain/consensus/filcns/filecoin.go
@@ -201,7 +201,7 @@ func (filec *FilecoinEC) ValidateBlock(ctx context.Context, b *types.FullBlock)
 			return xerrors.Errorf("failed to marshal miner address to cbor: %w", err)
 		}
 
-		vrfBase, err := rand.DrawRandomness(rBeacon.Data, crypto.DomainSeparationTag_ElectionProofProduction, h.Height, buf.Bytes())
+		vrfBase, err := rand.DrawRandomnessFromBase(rBeacon.Data, crypto.DomainSeparationTag_ElectionProofProduction, h.Height, buf.Bytes())
 		if err != nil {
 			return xerrors.Errorf("could not draw randomness: %w", err)
 		}
@@ -267,7 +267,7 @@ func (filec *FilecoinEC) ValidateBlock(ctx context.Context, b *types.FullBlock)
 			beaconBase = h.BeaconEntries[len(h.BeaconEntries)-1]
 		}
 
-		vrfBase, err := rand.DrawRandomness(beaconBase.Data, crypto.DomainSeparationTag_TicketProduction, h.Height-build.TicketRandomnessLookback, buf.Bytes())
+		vrfBase, err := rand.DrawRandomnessFromBase(beaconBase.Data, crypto.DomainSeparationTag_TicketProduction, h.Height-build.TicketRandomnessLookback, buf.Bytes())
 		if err != nil {
 			return xerrors.Errorf("failed to compute vrf base for ticket: %w", err)
 		}
@@ -345,7 +345,7 @@ func (filec *FilecoinEC) VerifyWinningPoStProof(ctx context.Context, nv network.
 		rbase = h.BeaconEntries[len(h.BeaconEntries)-1]
 	}
 
-	rand, err := rand.DrawRandomness(rbase.Data, crypto.DomainSeparationTag_WinningPoStChallengeSeed, h.Height, buf.Bytes())
+	rand, err := rand.DrawRandomnessFromBase(rbase.Data, crypto.DomainSeparationTag_WinningPoStChallengeSeed, h.Height, buf.Bytes())
 	if err != nil {
 		return xerrors.Errorf("failed to get randomness for verifying winning post proof: %w", err)
 	}
diff --git a/chain/consensus/filcns/upgrades.go b/chain/consensus/filcns/upgrades.go
index 075937a3c3d..d7e0914fe2e 100644
--- a/chain/consensus/filcns/upgrades.go
+++ b/chain/consensus/filcns/upgrades.go
@@ -1,6 +1,7 @@
 package filcns
 
 import (
+	"bytes"
 	"context"
 	_ "embed"
 	"fmt"
@@ -19,7 +20,10 @@ import (
 	actorstypes "github.com/filecoin-project/go-state-types/actors"
 	"github.com/filecoin-project/go-state-types/big"
 	nv18 "github.com/filecoin-project/go-state-types/builtin/v10/migration"
+	init11 "github.com/filecoin-project/go-state-types/builtin/v11/init"
 	nv19 "github.com/filecoin-project/go-state-types/builtin/v11/migration"
+	system11 "github.com/filecoin-project/go-state-types/builtin/v11/system"
+	nv21 "github.com/filecoin-project/go-state-types/builtin/v12/migration"
 	nv17 "github.com/filecoin-project/go-state-types/builtin/v9/migration"
 	"github.com/filecoin-project/go-state-types/manifest"
 	"github.com/filecoin-project/go-state-types/migration"
@@ -261,7 +265,27 @@ func DefaultUpgradeSchedule() stmgr.UpgradeSchedule {
 		Height:    build.UpgradeThunderHeight,
 		Network:   network.Version20,
 		Migration: nil,
+	}, {
+		Height:    build.UpgradeWatermelonHeight,
+		Network:   network.Version21,
+		Migration: UpgradeActorsV12,
+		PreMigrations: []stmgr.PreMigration{{
+			PreMigration:    PreUpgradeActorsV12,
+			StartWithin:     180,
+			DontStartWithin: 15,
+			StopWithin:      10,
+		}},
+		Expensive: true,
+	}, {
+		Height:    build.UpgradeWatermelonFixHeight,
+		Network:   network.Version21,
+		Migration: buildUpgradeActorsV12MinerFix(calibnetv12BuggyMinerCID1, calibnetv12BuggyManifestCID2),
 	},
+		{
+			Height:    build.UpgradeWatermelonFix2Height,
+			Network:   network.Version21,
+			Migration: buildUpgradeActorsV12MinerFix(calibnetv12BuggyMinerCID2, calibnetv12CorrectManifestCID1),
+		},
 	}
 
 	for _, u := range updates {
@@ -1814,6 +1838,316 @@ func upgradeActorsV11Common(
 	return newRoot, nil
 }
 
+func PreUpgradeActorsV12(ctx context.Context, sm *stmgr.StateManager, cache stmgr.MigrationCache, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) error {
+	// Use half the CPUs for pre-migration, but leave at least 3.
+	workerCount := MigrationMaxWorkerCount
+	if workerCount <= 4 {
+		workerCount = 1
+	} else {
+		workerCount /= 2
+	}
+
+	lbts, lbRoot, err := stmgr.GetLookbackTipSetForRound(ctx, sm, ts, epoch)
+	if err != nil {
+		return xerrors.Errorf("error getting lookback ts for premigration: %w", err)
+	}
+
+	config := migration.Config{
+		MaxWorkers:        uint(workerCount),
+		ProgressLogPeriod: time.Minute * 5,
+	}
+
+	_, err = upgradeActorsV12Common(ctx, sm, cache, lbRoot, epoch, lbts, config)
+	return err
+}
+
+func UpgradeActorsV12(ctx context.Context, sm *stmgr.StateManager, cache stmgr.MigrationCache, cb stmgr.ExecMonitor,
+	root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) {
+	// Use all the CPUs except 2.
+	workerCount := MigrationMaxWorkerCount - 3
+	if workerCount <= 0 {
+		workerCount = 1
+	}
+	config := migration.Config{
+		MaxWorkers:        uint(workerCount),
+		JobQueueSize:      1000,
+		ResultQueueSize:   100,
+		ProgressLogPeriod: 10 * time.Second,
+	}
+	newRoot, err := upgradeActorsV12Common(ctx, sm, cache, root, epoch, ts, config)
+	if err != nil {
+		return cid.Undef, xerrors.Errorf("migrating actors v11 state: %w", err)
+	}
+	return newRoot, nil
+}
+
+var (
+	calibnetv12BuggyMinerCID1 = cid.MustParse("bafk2bzacecnh2ouohmonvebq7uughh4h3ppmg4cjsk74dzxlbbtlcij4xbzxq")
+	calibnetv12BuggyMinerCID2 = cid.MustParse("bafk2bzaced7emkbbnrewv5uvrokxpf5tlm4jslu2jsv77ofw2yqdglg657uie")
+
+	calibnetv12BuggyBundleSuffix1 = "calibrationnet-12-rc1"
+	calibnetv12BuggyBundleSuffix2 = "calibrationnet-12-rc2"
+
+	calibnetv12BuggyManifestCID1   = cid.MustParse("bafy2bzacedrunxfqta5skb7q7x32lnp4efz2oq7fn226ffm7fu5iqs62jkmvs")
+	calibnetv12BuggyManifestCID2   = cid.MustParse("bafy2bzacebl4w5ptfvuw6746w7ev562idkbf5ppq72e6zub22435ws2rukzru")
+	calibnetv12CorrectManifestCID1 = cid.MustParse("bafy2bzacednzb3pkrfnbfhmoqtb3bc6dgvxszpqklf3qcc7qzcage4ewzxsca")
+)
+
+func upgradeActorsV12Common(
+	ctx context.Context, sm *stmgr.StateManager, cache stmgr.MigrationCache,
+	root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet,
+	config migration.Config,
+) (cid.Cid, error) {
+	writeStore := blockstore.NewAutobatch(ctx, sm.ChainStore().StateBlockstore(), units.GiB/4)
+	adtStore := store.ActorStore(ctx, writeStore)
+	// ensure that the manifest is loaded in the blockstore
+	if err := bundle.LoadBundles(ctx, writeStore, actorstypes.Version12); err != nil {
+		return cid.Undef, xerrors.Errorf("failed to load manifest bundle: %w", err)
+	}
+
+	// Load the state root.
+	var stateRoot types.StateRoot
+	if err := adtStore.Get(ctx, root, &stateRoot); err != nil {
+		return cid.Undef, xerrors.Errorf("failed to decode state root: %w", err)
+	}
+
+	if stateRoot.Version != types.StateTreeVersion5 {
+		return cid.Undef, xerrors.Errorf(
+			"expected state root version 5 for actors v12 upgrade, got %d",
+			stateRoot.Version,
+		)
+	}
+
+	// check whether or not this is a calibnet upgrade
+	// we do this because calibnet upgraded to a "wrong" actors bundle, which was then corrected
+	// we thus upgrade to calibrationnet-buggy in this upgrade
+	actorsIn, err := state.LoadStateTree(adtStore, root)
+	if err != nil {
+		return cid.Undef, xerrors.Errorf("loading state tree: %w", err)
+	}
+
+	initActor, err := actorsIn.GetActor(builtin.InitActorAddr)
+	if err != nil {
+		return cid.Undef, xerrors.Errorf("failed to get system actor: %w", err)
+	}
+
+	var initState init11.State
+	if err := adtStore.Get(ctx, initActor.Head, &initState); err != nil {
+		return cid.Undef, xerrors.Errorf("failed to get system actor state: %w", err)
+	}
+
+	var manifestCid cid.Cid
+	if initState.NetworkName == "calibrationnet" {
+		embedded, ok := build.GetEmbeddedBuiltinActorsBundle(actorstypes.Version12, calibnetv12BuggyBundleSuffix1)
+		if !ok {
+			return cid.Undef, xerrors.Errorf("didn't find buggy calibrationnet bundle")
+		}
+
+		var err error
+		manifestCid, err = bundle.LoadBundle(ctx, writeStore, bytes.NewReader(embedded))
+		if err != nil {
+			return cid.Undef, xerrors.Errorf("failed to load buggy calibnet bundle: %w", err)
+		}
+
+		if manifestCid != calibnetv12BuggyManifestCID1 {
+			return cid.Undef, xerrors.Errorf("didn't find expected buggy calibnet bundle manifest: %s != %s", manifestCid, calibnetv12BuggyManifestCID1)
+		}
+	} else {
+		ok := false
+		manifestCid, ok = actors.GetManifest(actorstypes.Version12)
+		if !ok {
+			return cid.Undef, xerrors.Errorf("no manifest CID for v12 upgrade")
+		}
+	}
+
+	// Perform the migration
+	newHamtRoot, err := nv21.MigrateStateTree(ctx, adtStore, manifestCid, stateRoot.Actors, epoch, config,
+		migrationLogger{}, cache)
+	if err != nil {
+		return cid.Undef, xerrors.Errorf("upgrading to actors v12: %w", err)
+	}
+
+	// Persist the result.
+	newRoot, err := adtStore.Put(ctx, &types.StateRoot{
+		Version: types.StateTreeVersion5,
+		Actors:  newHamtRoot,
+		Info:    stateRoot.Info,
+	})
+	if err != nil {
+		return cid.Undef, xerrors.Errorf("failed to persist new state root: %w", err)
+	}
+
+	// Persists the new tree and shuts down the flush worker
+	if err := writeStore.Flush(ctx); err != nil {
+		return cid.Undef, xerrors.Errorf("writeStore flush failed: %w", err)
+	}
+
+	if err := writeStore.Shutdown(ctx); err != nil {
+		return cid.Undef, xerrors.Errorf("writeStore shutdown failed: %w", err)
+	}
+
+	return newRoot, nil
+}
+
+// ////////////////////
+func buildUpgradeActorsV12MinerFix(oldBuggyMinerCID, newManifestCID cid.Cid) func(ctx context.Context, sm *stmgr.StateManager, cache stmgr.MigrationCache, cb stmgr.ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) {
+	return func(ctx context.Context, sm *stmgr.StateManager, cache stmgr.MigrationCache, cb stmgr.ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) {
+		stateStore := sm.ChainStore().StateBlockstore()
+		adtStore := store.ActorStore(ctx, stateStore)
+
+		// ensure that the manifest is loaded in the blockstore
+
+		// this loads the "correct" bundle for UpgradeWatermelonFix2Height
+		if err := bundle.LoadBundles(ctx, stateStore, actorstypes.Version12); err != nil {
+			return cid.Undef, xerrors.Errorf("failed to load manifest bundle: %w", err)
+		}
+
+		// this loads the second buggy bundle, for UpgradeWatermelonFixHeight
+		embedded, ok := build.GetEmbeddedBuiltinActorsBundle(actorstypes.Version12, calibnetv12BuggyBundleSuffix2)
+		if !ok {
+			return cid.Undef, xerrors.Errorf("didn't find buggy calibrationnet bundle")
+		}
+
+		_, err := bundle.LoadBundle(ctx, stateStore, bytes.NewReader(embedded))
+		if err != nil {
+			return cid.Undef, xerrors.Errorf("failed to load buggy calibnet bundle: %w", err)
+		}
+
+		// now confirm we have the one we're migrating to
+		if haveManifest, err := stateStore.Has(ctx, newManifestCID); err != nil {
+			return cid.Undef, xerrors.Errorf("blockstore error when loading manifest %s: %w", newManifestCID, err)
+		} else if !haveManifest {
+			return cid.Undef, xerrors.Errorf("missing new manifest %s in blockstore", newManifestCID)
+		}
+
+		// Load input state tree
+		actorsIn, err := state.LoadStateTree(adtStore, root)
+		if err != nil {
+			return cid.Undef, xerrors.Errorf("loading state tree: %w", err)
+		}
+
+		// load old manifest data
+		systemActor, err := actorsIn.GetActor(builtin.SystemActorAddr)
+		if err != nil {
+			return cid.Undef, xerrors.Errorf("failed to get system actor: %w", err)
+		}
+
+		var systemState system11.State
+		if err := adtStore.Get(ctx, systemActor.Head, &systemState); err != nil {
+			return cid.Undef, xerrors.Errorf("failed to get system actor state: %w", err)
+		}
+
+		var oldManifestData manifest.ManifestData
+		if err := adtStore.Get(ctx, systemState.BuiltinActors, &oldManifestData); err != nil {
+			return cid.Undef, xerrors.Errorf("failed to get old manifest data: %w", err)
+		}
+
+		// load new manifest
+		var newManifest manifest.Manifest
+		if err := adtStore.Get(ctx, newManifestCID, &newManifest); err != nil {
+			return cid.Undef, xerrors.Errorf("error reading actor manifest: %w", err)
+		}
+
+		if err := newManifest.Load(ctx, adtStore); err != nil {
+			return cid.Undef, xerrors.Errorf("error loading actor manifest: %w", err)
+		}
+
+		// build the CID mapping
+		codeMapping := make(map[cid.Cid]cid.Cid, len(oldManifestData.Entries))
+		for _, oldEntry := range oldManifestData.Entries {
+			newCID, ok := newManifest.Get(oldEntry.Name)
+			if !ok {
+				return cid.Undef, xerrors.Errorf("missing manifest entry for %s", oldEntry.Name)
+			}
+
+			// Note: we expect newCID to be the same as oldEntry.Code for all actors except the miner actor
+			codeMapping[oldEntry.Code] = newCID
+		}
+
+		// Create empty actorsOut
+
+		actorsOut, err := state.NewStateTree(adtStore, actorsIn.Version())
+		if err != nil {
+			return cid.Undef, xerrors.Errorf("failed to create new tree: %w", err)
+		}
+
+		// Perform the migration
+		err = actorsIn.ForEach(func(a address.Address, actor *types.Actor) error {
+			newCid, ok := codeMapping[actor.Code]
+			if !ok {
+				return xerrors.Errorf("didn't find mapping for %s", actor.Code)
+			}
+
+			return actorsOut.SetActor(a, &types.ActorV5{
+				Code:    newCid,
+				Head:    actor.Head,
+				Nonce:   actor.Nonce,
+				Balance: actor.Balance,
+				Address: actor.Address,
+			})
+		})
+		if err != nil {
+			return cid.Undef, xerrors.Errorf("failed to perform migration: %w", err)
+		}
+
+		systemState.BuiltinActors = newManifest.Data
+		newSystemHead, err := adtStore.Put(ctx, &systemState)
+		if err != nil {
+			return cid.Undef, xerrors.Errorf("failed to put new system state: %w", err)
+		}
+
+		systemActor.Head = newSystemHead
+		if err = actorsOut.SetActor(builtin.SystemActorAddr, systemActor); err != nil {
+			return cid.Undef, xerrors.Errorf("failed to put new system actor: %w", err)
+		}
+
+		// Sanity checking
+
+		err = actorsIn.ForEach(func(a address.Address, inActor *types.Actor) error {
+			outActor, err := actorsOut.GetActor(a)
+			if err != nil {
+				return xerrors.Errorf("failed to get actor in outTree: %w", err)
+			}
+
+			if inActor.Nonce != outActor.Nonce {
+				return xerrors.Errorf("mismatched nonce for actor %s", a)
+			}
+
+			if !inActor.Balance.Equals(outActor.Balance) {
+				return xerrors.Errorf("mismatched balance for actor %s: %d != %d", a, inActor.Balance, outActor.Balance)
+			}
+
+			if inActor.Address != outActor.Address && inActor.Address.String() != outActor.Address.String() {
+				return xerrors.Errorf("mismatched address for actor %s: %s != %s", a, inActor.Address, outActor.Address)
+			}
+
+			if inActor.Head != outActor.Head && a != builtin.SystemActorAddr {
+				return xerrors.Errorf("mismatched head for actor %s", a)
+			}
+
+			// Actor Codes are only expected to change for the miner actor
+			if inActor.Code != oldBuggyMinerCID && inActor.Code != outActor.Code {
+				return xerrors.Errorf("unexpected change in code for actor %s", a)
+			}
+
+			return nil
+		})
+		if err != nil {
+			return cid.Undef, xerrors.Errorf("failed to sanity check migration: %w", err)
+		}
+
+		// Persist the result.
+		newRoot, err := actorsOut.Flush(ctx)
+		if err != nil {
+			return cid.Undef, xerrors.Errorf("failed to persist new state root: %w", err)
+		}
+
+		return newRoot, nil
+	}
+}
+
+////////////////////
+
 // Example upgrade function if upgrade requires only code changes
 //func UpgradeActorsV9(ctx context.Context, sm *stmgr.StateManager, _ stmgr.MigrationCache, _ stmgr.ExecMonitor, root cid.Cid, _ abi.ChainEpoch, _ *types.TipSet) (cid.Cid, error) {
 //	buf := blockstore.NewTieredBstore(sm.ChainStore().StateBlockstore(), blockstore.NewMemorySync())
diff --git a/chain/events/message_cache.go b/chain/events/message_cache.go
index d47d3a168ed..96f6bcbd761 100644
--- a/chain/events/message_cache.go
+++ b/chain/events/message_cache.go
@@ -4,7 +4,7 @@ import (
 	"context"
 	"sync"
 
-	lru "github.com/hashicorp/golang-lru/v2"
+	"github.com/hashicorp/golang-lru/arc/v2"
 	"github.com/ipfs/go-cid"
 
 	"github.com/filecoin-project/lotus/api"
@@ -14,11 +14,11 @@ type messageCache struct {
 	api EventAPI
 
 	blockMsgLk    sync.Mutex
-	blockMsgCache *lru.ARCCache[cid.Cid, *api.BlockMessages]
+	blockMsgCache *arc.ARCCache[cid.Cid, *api.BlockMessages]
 }
 
 func newMessageCache(a EventAPI) *messageCache {
-	blsMsgCache, _ := lru.NewARC[cid.Cid, *api.BlockMessages](500)
+	blsMsgCache, _ := arc.NewARC[cid.Cid, *api.BlockMessages](500)
 
 	return &messageCache{
 		api:           a,
diff --git a/chain/exchange/cbor_gen.go b/chain/exchange/cbor_gen.go
index d1eb271e99a..e66b6d798c4 100644
--- a/chain/exchange/cbor_gen.go
+++ b/chain/exchange/cbor_gen.go
@@ -43,9 +43,11 @@ func (t *Request) MarshalCBOR(w io.Writer) error {
 		return err
 	}
 	for _, v := range t.Head {
-		if err := cbg.WriteCid(w, v); err != nil {
-			return xerrors.Errorf("failed writing cid field t.Head: %w", err)
+
+		if err := cbg.WriteCid(cw, v); err != nil {
+			return xerrors.Errorf("failed to write cid field v: %w", err)
 		}
+
 	}
 
 	// t.Length (uint64) (uint64)
@@ -106,12 +108,25 @@ func (t *Request) UnmarshalCBOR(r io.Reader) (err error) {
 	}
 
 	for i := 0; i < int(extra); i++ {
+		{
+			var maj byte
+			var extra uint64
+			var err error
+			_ = maj
+			_ = extra
+			_ = err
 
-		c, err := cbg.ReadCid(cr)
-		if err != nil {
-			return xerrors.Errorf("reading cid field t.Head failed: %w", err)
+			{
+
+				c, err := cbg.ReadCid(cr)
+				if err != nil {
+					return xerrors.Errorf("failed to read cid field t.Head[i]: %w", err)
+				}
+
+				t.Head[i] = c
+
+			}
 		}
-		t.Head[i] = c
 	}
 
 	// t.Length (uint64) (uint64)
@@ -173,7 +188,7 @@ func (t *Response) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.ErrorMessage))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string(t.ErrorMessage)); err != nil {
+	if _, err := cw.WriteString(string(t.ErrorMessage)); err != nil {
 		return err
 	}
 
@@ -260,13 +275,32 @@ func (t *Response) UnmarshalCBOR(r io.Reader) (err error) {
 	}
 
 	for i := 0; i < int(extra); i++ {
+		{
+			var maj byte
+			var extra uint64
+			var err error
+			_ = maj
+			_ = extra
+			_ = err
 
-		var v BSTipSet
-		if err := v.UnmarshalCBOR(cr); err != nil {
-			return err
-		}
+			{
 
-		t.Chain[i] = &v
+				b, err := cr.ReadByte()
+				if err != nil {
+					return err
+				}
+				if b != cbg.CborNull[0] {
+					if err := cr.UnreadByte(); err != nil {
+						return err
+					}
+					t.Chain[i] = new(BSTipSet)
+					if err := t.Chain[i].UnmarshalCBOR(cr); err != nil {
+						return xerrors.Errorf("unmarshaling t.Chain[i] pointer: %w", err)
+					}
+				}
+
+			}
+		}
 	}
 
 	return nil
@@ -317,9 +351,11 @@ func (t *CompactedMessages) MarshalCBOR(w io.Writer) error {
 			return err
 		}
 		for _, v := range v {
-			if err := cw.CborWriteHeader(cbg.MajUnsignedInt, uint64(v)); err != nil {
+
+			if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(v)); err != nil {
 				return err
 			}
+
 		}
 	}
 
@@ -354,9 +390,11 @@ func (t *CompactedMessages) MarshalCBOR(w io.Writer) error {
 			return err
 		}
 		for _, v := range v {
-			if err := cw.CborWriteHeader(cbg.MajUnsignedInt, uint64(v)); err != nil {
+
+			if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(v)); err != nil {
 				return err
 			}
+
 		}
 	}
 	return nil
@@ -405,13 +443,32 @@ func (t *CompactedMessages) UnmarshalCBOR(r io.Reader) (err error) {
 	}
 
 	for i := 0; i < int(extra); i++ {
+		{
+			var maj byte
+			var extra uint64
+			var err error
+			_ = maj
+			_ = extra
+			_ = err
 
-		var v types.Message
-		if err := v.UnmarshalCBOR(cr); err != nil {
-			return err
-		}
+			{
 
-		t.Bls[i] = &v
+				b, err := cr.ReadByte()
+				if err != nil {
+					return err
+				}
+				if b != cbg.CborNull[0] {
+					if err := cr.UnreadByte(); err != nil {
+						return err
+					}
+					t.Bls[i] = new(types.Message)
+					if err := t.Bls[i].UnmarshalCBOR(cr); err != nil {
+						return xerrors.Errorf("unmarshaling t.Bls[i] pointer: %w", err)
+					}
+				}
+
+			}
+		}
 	}
 
 	// t.BlsIncludes ([][]uint64) (slice)
@@ -438,6 +495,9 @@ func (t *CompactedMessages) UnmarshalCBOR(r io.Reader) (err error) {
 			var maj byte
 			var extra uint64
 			var err error
+			_ = maj
+			_ = extra
+			_ = err
 
 			maj, extra, err = cr.ReadHeader()
 			if err != nil {
@@ -457,17 +517,27 @@ func (t *CompactedMessages) UnmarshalCBOR(r io.Reader) (err error) {
 			}
 
 			for j := 0; j < int(extra); j++ {
-
-				maj, val, err := cr.ReadHeader()
-				if err != nil {
-					return xerrors.Errorf("failed to read uint64 for t.BlsIncludes[i] slice: %w", err)
+				{
+					var maj byte
+					var extra uint64
+					var err error
+					_ = maj
+					_ = extra
+					_ = err
+
+					{
+
+						maj, extra, err = cr.ReadHeader()
+						if err != nil {
+							return err
+						}
+						if maj != cbg.MajUnsignedInt {
+							return fmt.Errorf("wrong type for uint64 field")
+						}
+						t.BlsIncludes[i][j] = uint64(extra)
+
+					}
 				}
-
-				if maj != cbg.MajUnsignedInt {
-					return xerrors.Errorf("value read for array t.BlsIncludes[i] was not a uint, instead got %d", maj)
-				}
-
-				t.BlsIncludes[i][j] = uint64(val)
 			}
 
 		}
@@ -493,13 +563,32 @@ func (t *CompactedMessages) UnmarshalCBOR(r io.Reader) (err error) {
 	}
 
 	for i := 0; i < int(extra); i++ {
+		{
+			var maj byte
+			var extra uint64
+			var err error
+			_ = maj
+			_ = extra
+			_ = err
 
-		var v types.SignedMessage
-		if err := v.UnmarshalCBOR(cr); err != nil {
-			return err
-		}
+			{
 
-		t.Secpk[i] = &v
+				b, err := cr.ReadByte()
+				if err != nil {
+					return err
+				}
+				if b != cbg.CborNull[0] {
+					if err := cr.UnreadByte(); err != nil {
+						return err
+					}
+					t.Secpk[i] = new(types.SignedMessage)
+					if err := t.Secpk[i].UnmarshalCBOR(cr); err != nil {
+						return xerrors.Errorf("unmarshaling t.Secpk[i] pointer: %w", err)
+					}
+				}
+
+			}
+		}
 	}
 
 	// t.SecpkIncludes ([][]uint64) (slice)
@@ -526,6 +615,9 @@ func (t *CompactedMessages) UnmarshalCBOR(r io.Reader) (err error) {
 			var maj byte
 			var extra uint64
 			var err error
+			_ = maj
+			_ = extra
+			_ = err
 
 			maj, extra, err = cr.ReadHeader()
 			if err != nil {
@@ -545,17 +637,27 @@ func (t *CompactedMessages) UnmarshalCBOR(r io.Reader) (err error) {
 			}
 
 			for j := 0; j < int(extra); j++ {
-
-				maj, val, err := cr.ReadHeader()
-				if err != nil {
-					return xerrors.Errorf("failed to read uint64 for t.SecpkIncludes[i] slice: %w", err)
-				}
-
-				if maj != cbg.MajUnsignedInt {
-					return xerrors.Errorf("value read for array t.SecpkIncludes[i] was not a uint, instead got %d", maj)
+				{
+					var maj byte
+					var extra uint64
+					var err error
+					_ = maj
+					_ = extra
+					_ = err
+
+					{
+
+						maj, extra, err = cr.ReadHeader()
+						if err != nil {
+							return err
+						}
+						if maj != cbg.MajUnsignedInt {
+							return fmt.Errorf("wrong type for uint64 field")
+						}
+						t.SecpkIncludes[i][j] = uint64(extra)
+
+					}
 				}
-
-				t.SecpkIncludes[i][j] = uint64(val)
 			}
 
 		}
@@ -642,13 +744,32 @@ func (t *BSTipSet) UnmarshalCBOR(r io.Reader) (err error) {
 	}
 
 	for i := 0; i < int(extra); i++ {
+		{
+			var maj byte
+			var extra uint64
+			var err error
+			_ = maj
+			_ = extra
+			_ = err
 
-		var v types.BlockHeader
-		if err := v.UnmarshalCBOR(cr); err != nil {
-			return err
-		}
+			{
 
-		t.Blocks[i] = &v
+				b, err := cr.ReadByte()
+				if err != nil {
+					return err
+				}
+				if b != cbg.CborNull[0] {
+					if err := cr.UnreadByte(); err != nil {
+						return err
+					}
+					t.Blocks[i] = new(types.BlockHeader)
+					if err := t.Blocks[i].UnmarshalCBOR(cr); err != nil {
+						return xerrors.Errorf("unmarshaling t.Blocks[i] pointer: %w", err)
+					}
+				}
+
+			}
+		}
 	}
 
 	// t.Messages (exchange.CompactedMessages) (struct)
diff --git a/chain/gen/gen.go b/chain/gen/gen.go
index 2e5f5e7f724..087f0e00cd1 100644
--- a/chain/gen/gen.go
+++ b/chain/gen/gen.go
@@ -376,7 +376,7 @@ func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m add
 		buf.Write(pts.MinTicket().VRFProof)
 	}
 
-	ticketRand, err := rand.DrawRandomness(rbase.Data, crypto.DomainSeparationTag_TicketProduction, round-build.TicketRandomnessLookback, buf.Bytes())
+	ticketRand, err := rand.DrawRandomnessFromBase(rbase.Data, crypto.DomainSeparationTag_TicketProduction, round-build.TicketRandomnessLookback, buf.Bytes())
 	if err != nil {
 		return nil, nil, nil, err
 	}
@@ -636,7 +636,7 @@ func IsRoundWinner(ctx context.Context, ts *types.TipSet, round abi.ChainEpoch,
 		return nil, xerrors.Errorf("failed to cbor marshal address: %w", err)
 	}
 
-	electionRand, err := rand.DrawRandomness(brand.Data, crypto.DomainSeparationTag_ElectionProofProduction, round, buf.Bytes())
+	electionRand, err := rand.DrawRandomnessFromBase(brand.Data, crypto.DomainSeparationTag_ElectionProofProduction, round, buf.Bytes())
 	if err != nil {
 		return nil, xerrors.Errorf("failed to draw randomness: %w", err)
 	}
diff --git a/chain/gen/genesis/genesis.go b/chain/gen/genesis/genesis.go
index 3e88480218e..8ec657479f7 100644
--- a/chain/gen/genesis/genesis.go
+++ b/chain/gen/genesis/genesis.go
@@ -578,7 +578,7 @@ func MakeGenesisBlock(ctx context.Context, j journal.Journal, bs bstore.Blocksto
 	}
 
 	// setup Storage Miners
-	stateroot, err = SetupStorageMiners(ctx, cs, sys, stateroot, template.Miners, template.NetworkVersion)
+	stateroot, err = SetupStorageMiners(ctx, cs, sys, stateroot, template.Miners, template.NetworkVersion, false)
 	if err != nil {
 		return nil, xerrors.Errorf("setup miners failed: %w", err)
 	}
diff --git a/chain/gen/genesis/miners.go b/chain/gen/genesis/miners.go
index c083f4fda60..0bac282d2b3 100644
--- a/chain/gen/genesis/miners.go
+++ b/chain/gen/genesis/miners.go
@@ -43,6 +43,7 @@ import (
 	"github.com/filecoin-project/lotus/chain/actors/builtin/reward"
 	"github.com/filecoin-project/lotus/chain/actors/policy"
 	"github.com/filecoin-project/lotus/chain/consensus"
+	lrand "github.com/filecoin-project/lotus/chain/rand"
 	"github.com/filecoin-project/lotus/chain/state"
 	"github.com/filecoin-project/lotus/chain/store"
 	"github.com/filecoin-project/lotus/chain/types"
@@ -78,7 +79,7 @@ func mkFakedSigSyscalls(base vm.SyscallBuilder) vm.SyscallBuilder {
 }
 
 // Note: Much of this is brittle, if the methodNum / param / return changes, it will break things
-func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sys vm.SyscallBuilder, sroot cid.Cid, miners []genesis.Miner, nv network.Version) (cid.Cid, error) {
+func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sys vm.SyscallBuilder, sroot cid.Cid, miners []genesis.Miner, nv network.Version, synthetic bool) (cid.Cid, error) {
 
 	cst := cbor.NewCborStore(cs.StateBlockstore())
 	av, err := actorstypes.VersionForNetwork(nv)
@@ -124,14 +125,18 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sys vm.Syscal
 		sectorWeight []abi.StoragePower
 	}, len(miners))
 
-	maxPeriods := policy.GetMaxSectorExpirationExtension() / minertypes.WPoStProvingPeriod
+	maxLifetime, err := policy.GetMaxSectorExpirationExtension(nv)
+	if err != nil {
+		return cid.Undef, xerrors.Errorf("failed to get max extension: %w", err)
+	}
+	maxPeriods := maxLifetime / minertypes.WPoStProvingPeriod
 	rawPow, qaPow := big.NewInt(0), big.NewInt(0)
 	for i, m := range miners {
 		// Create miner through power actor
 		i := i
 		m := m
 
-		spt, err := miner.SealProofTypeFromSectorSize(m.SectorSize, nv)
+		spt, err := miner.SealProofTypeFromSectorSize(m.SectorSize, nv, synthetic)
 		if err != nil {
 			return cid.Undef, err
 		}
@@ -590,19 +595,21 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sys vm.Syscal
 	return c, nil
 }
 
+var _ lrand.Rand = new(fakeRand)
+
 // TODO: copied from actors test harness, deduplicate or remove from here
 type fakeRand struct{}
 
-func (fr *fakeRand) GetChainRandomness(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
+func (fr *fakeRand) GetChainRandomness(ctx context.Context, randEpoch abi.ChainEpoch) ([32]byte, error) {
 	out := make([]byte, 32)
 	_, _ = rand.New(rand.NewSource(int64(randEpoch * 1000))).Read(out) //nolint
-	return out, nil
+	return *(*[32]byte)(out), nil
 }
 
-func (fr *fakeRand) GetBeaconRandomness(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
+func (fr *fakeRand) GetBeaconRandomness(ctx context.Context, randEpoch abi.ChainEpoch) ([32]byte, error) {
 	out := make([]byte, 32)
 	_, _ = rand.New(rand.NewSource(int64(randEpoch))).Read(out) //nolint
-	return out, nil
+	return *(*[32]byte)(out), nil
 }
 
 func currentTotalPower(ctx context.Context, vm vm.Interface, maddr address.Address) (*power0.CurrentTotalPowerReturn, error) {
diff --git a/chain/rand/rand.go b/chain/rand/rand.go
index c35280ab5cf..40f9f593a03 100644
--- a/chain/rand/rand.go
+++ b/chain/rand/rand.go
@@ -17,18 +17,20 @@ import (
 	"github.com/filecoin-project/lotus/chain/beacon"
 	"github.com/filecoin-project/lotus/chain/store"
 	"github.com/filecoin-project/lotus/chain/types"
-	"github.com/filecoin-project/lotus/chain/vm"
 )
 
 var log = logging.Logger("rand")
 
-func DrawRandomness(rbase []byte, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
+func DrawRandomnessFromBase(rbase []byte, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
+	return DrawRandomnessFromDigest(blake2b.Sum256(rbase), pers, round, entropy)
+}
+
+func DrawRandomnessFromDigest(digest [32]byte, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
 	h := blake2b.New256()
 	if err := binary.Write(h, binary.BigEndian, int64(pers)); err != nil {
 		return nil, xerrors.Errorf("deriving randomness: %w", err)
 	}
-	VRFDigest := blake2b.Sum256(rbase)
-	_, err := h.Write(VRFDigest[:])
+	_, err := h.Write(digest[:])
 	if err != nil {
 		return nil, xerrors.Errorf("hashing VRFDigest: %w", err)
 	}
@@ -70,18 +72,18 @@ func (sr *stateRand) GetBeaconRandomnessTipset(ctx context.Context, round abi.Ch
 	return randTs, nil
 }
 
-func (sr *stateRand) getChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte, lookback bool) ([]byte, error) {
+func (sr *stateRand) getChainRandomness(ctx context.Context, round abi.ChainEpoch, lookback bool) ([32]byte, error) {
 	_, span := trace.StartSpan(ctx, "store.GetChainRandomness")
 	defer span.End()
 	span.AddAttributes(trace.Int64Attribute("round", int64(round)))
 
 	ts, err := sr.cs.LoadTipSet(ctx, types.NewTipSetKey(sr.blks...))
 	if err != nil {
-		return nil, err
+		return [32]byte{}, err
 	}
 
 	if round > ts.Height() {
-		return nil, xerrors.Errorf("cannot draw randomness from the future")
+		return [32]byte{}, xerrors.Errorf("cannot draw randomness from the future")
 	}
 
 	searchHeight := round
@@ -91,14 +93,10 @@ func (sr *stateRand) getChainRandomness(ctx context.Context, pers crypto.DomainS
 
 	randTs, err := sr.cs.GetTipsetByHeight(ctx, searchHeight, ts, lookback)
 	if err != nil {
-		return nil, err
+		return [32]byte{}, err
 	}
 
-	mtb := randTs.MinTicketBlock()
-
-	// if at (or just past -- for null epochs) appropriate epoch
-	// or at genesis (works for negative epochs)
-	return DrawRandomness(mtb.Ticket.VRFProof, pers, round, entropy)
+	return blake2b.Sum256(randTs.MinTicketBlock().Ticket.VRFProof), nil
 }
 
 type NetworkVersionGetter func(context.Context, abi.ChainEpoch) network.Version
@@ -110,7 +108,12 @@ type stateRand struct {
 	networkVersionGetter NetworkVersionGetter
 }
 
-func NewStateRand(cs *store.ChainStore, blks []cid.Cid, b beacon.Schedule, networkVersionGetter NetworkVersionGetter) vm.Rand {
+type Rand interface {
+	GetChainRandomness(ctx context.Context, round abi.ChainEpoch) ([32]byte, error)
+	GetBeaconRandomness(ctx context.Context, round abi.ChainEpoch) ([32]byte, error)
+}
+
+func NewStateRand(cs *store.ChainStore, blks []cid.Cid, b beacon.Schedule, networkVersionGetter NetworkVersionGetter) Rand {
 	return &stateRand{
 		cs:                   cs,
 		blks:                 blks,
@@ -120,76 +123,102 @@ func NewStateRand(cs *store.ChainStore, blks []cid.Cid, b beacon.Schedule, netwo
 }
 
 // network v0-12
-func (sr *stateRand) getBeaconRandomnessV1(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
+func (sr *stateRand) getBeaconRandomnessV1(ctx context.Context, round abi.ChainEpoch) ([32]byte, error) {
 	randTs, err := sr.GetBeaconRandomnessTipset(ctx, round, true)
 	if err != nil {
-		return nil, err
+		return [32]byte{}, err
 	}
 
 	be, err := sr.cs.GetLatestBeaconEntry(ctx, randTs)
 	if err != nil {
-		return nil, err
+		return [32]byte{}, err
 	}
 
-	// if at (or just past -- for null epochs) appropriate epoch
-	// or at genesis (works for negative epochs)
-	return DrawRandomness(be.Data, pers, round, entropy)
+	return blake2b.Sum256(be.Data), nil
 }
 
 // network v13
-func (sr *stateRand) getBeaconRandomnessV2(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
+func (sr *stateRand) getBeaconRandomnessV2(ctx context.Context, round abi.ChainEpoch) ([32]byte, error) {
 	randTs, err := sr.GetBeaconRandomnessTipset(ctx, round, false)
 	if err != nil {
-		return nil, err
+		return [32]byte{}, err
 	}
 
 	be, err := sr.cs.GetLatestBeaconEntry(ctx, randTs)
 	if err != nil {
-		return nil, err
+		return [32]byte{}, err
 	}
 
-	// if at (or just past -- for null epochs) appropriate epoch
-	// or at genesis (works for negative epochs)
-	return DrawRandomness(be.Data, pers, round, entropy)
+	return blake2b.Sum256(be.Data), nil
 }
 
 // network v14 and on
-func (sr *stateRand) getBeaconRandomnessV3(ctx context.Context, pers crypto.DomainSeparationTag, filecoinEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
+func (sr *stateRand) getBeaconRandomnessV3(ctx context.Context, filecoinEpoch abi.ChainEpoch) ([32]byte, error) {
 	if filecoinEpoch < 0 {
-		return sr.getBeaconRandomnessV2(ctx, pers, filecoinEpoch, entropy)
+		return sr.getBeaconRandomnessV2(ctx, filecoinEpoch)
 	}
 
 	be, err := sr.extractBeaconEntryForEpoch(ctx, filecoinEpoch)
 	if err != nil {
 		log.Errorf("failed to get beacon entry as expected: %s", err)
-		return nil, err
+		return [32]byte{}, err
 	}
 
-	return DrawRandomness(be.Data, pers, filecoinEpoch, entropy)
+	return blake2b.Sum256(be.Data), nil
 }
 
-func (sr *stateRand) GetChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, filecoinEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
+func (sr *stateRand) GetChainRandomness(ctx context.Context, filecoinEpoch abi.ChainEpoch) ([32]byte, error) {
 	nv := sr.networkVersionGetter(ctx, filecoinEpoch)
 
 	if nv >= network.Version13 {
-		return sr.getChainRandomness(ctx, pers, filecoinEpoch, entropy, false)
+		return sr.getChainRandomness(ctx, filecoinEpoch, false)
 	}
 
-	return sr.getChainRandomness(ctx, pers, filecoinEpoch, entropy, true)
+	return sr.getChainRandomness(ctx, filecoinEpoch, true)
 }
 
-func (sr *stateRand) GetBeaconRandomness(ctx context.Context, pers crypto.DomainSeparationTag, filecoinEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
+func (sr *stateRand) GetBeaconRandomness(ctx context.Context, filecoinEpoch abi.ChainEpoch) ([32]byte, error) {
 	nv := sr.networkVersionGetter(ctx, filecoinEpoch)
 
 	if nv >= network.Version14 {
-		return sr.getBeaconRandomnessV3(ctx, pers, filecoinEpoch, entropy)
+		return sr.getBeaconRandomnessV3(ctx, filecoinEpoch)
 	} else if nv == network.Version13 {
-		return sr.getBeaconRandomnessV2(ctx, pers, filecoinEpoch, entropy)
+		return sr.getBeaconRandomnessV2(ctx, filecoinEpoch)
 	} else {
-		return sr.getBeaconRandomnessV1(ctx, pers, filecoinEpoch, entropy)
+		return sr.getBeaconRandomnessV1(ctx, filecoinEpoch)
 	}
 }
 
+func (sr *stateRand) DrawChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, filecoinEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
+	digest, err := sr.GetChainRandomness(ctx, filecoinEpoch)
+
+	if err != nil {
+		return nil, xerrors.Errorf("failed to get chain randomness: %w", err)
+	}
+
+	ret, err := DrawRandomnessFromDigest(digest, pers, filecoinEpoch, entropy)
+	if err != nil {
+		return nil, xerrors.Errorf("failed to draw chain randomness: %w", err)
+	}
+
+	return ret, nil
+}
+
+func (sr *stateRand) DrawBeaconRandomness(ctx context.Context, pers crypto.DomainSeparationTag, filecoinEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
+	digest, err := sr.GetBeaconRandomness(ctx, filecoinEpoch)
+
+	if err != nil {
+		return nil, xerrors.Errorf("failed to get beacon randomness: %w", err)
+	}
+
+	ret, err := DrawRandomnessFromDigest(digest, pers, filecoinEpoch, entropy)
+	if err != nil {
+		return nil, xerrors.Errorf("failed to draw beacon randomness: %w", err)
+	}
+
+	return ret, nil
+}
+
 func (sr *stateRand) extractBeaconEntryForEpoch(ctx context.Context, filecoinEpoch abi.ChainEpoch) (*types.BeaconEntry, error) {
 	randTs, err := sr.GetBeaconRandomnessTipset(ctx, filecoinEpoch, false)
 	if err != nil {
diff --git a/chain/rand/rand_test.go b/chain/rand/rand_test.go
index acd92885491..e2e7221658b 100644
--- a/chain/rand/rand_test.go
+++ b/chain/rand/rand_test.go
@@ -69,7 +69,7 @@ func TestNullRandomnessV1(t *testing.T) {
 		}
 
 		//stm: @BLOCKCHAIN_RAND_DRAW_RANDOMNESS_01
-		rand2, err := rand.DrawRandomness(resp.Entry.Data, pers, randEpoch, entropy)
+		rand2, err := rand.DrawRandomnessFromBase(resp.Entry.Data, pers, randEpoch, entropy)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -148,8 +148,8 @@ func TestNullRandomnessV2(t *testing.T) {
 		}
 
 		//stm: @BLOCKCHAIN_RAND_DRAW_RANDOMNESS_01, @BLOCKCHAIN_RAND_EXTRACT_BEACON_ENTRY_FOR_EPOCH_01, @BLOCKCHAIN_RAND_GET_BEACON_RANDOMNESS_TIPSET_03
-		// note that the randEpoch passed to DrawRandomness is still randEpoch (not the latest ts height)
-		rand2, err := rand.DrawRandomness(resp.Entry.Data, pers, randEpoch, entropy)
+		// note that the randEpoch passed to DrawRandomnessFromBase is still randEpoch (not the latest ts height)
+		rand2, err := rand.DrawRandomnessFromBase(resp.Entry.Data, pers, randEpoch, entropy)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -232,7 +232,7 @@ func TestNullRandomnessV3(t *testing.T) {
 		}
 
 		//stm: @BLOCKCHAIN_RAND_DRAW_RANDOMNESS_01
-		rand2, err := rand.DrawRandomness(resp.Entry.Data, pers, randEpoch, entropy)
+		rand2, err := rand.DrawRandomnessFromBase(resp.Entry.Data, pers, randEpoch, entropy)
 		if err != nil {
 			t.Fatal(err)
 		}
diff --git a/chain/state/statetree.go b/chain/state/statetree.go
index 3142a07d8b5..c71473e8fa0 100644
--- a/chain/state/statetree.go
+++ b/chain/state/statetree.go
@@ -156,7 +156,7 @@ func VersionForNetwork(ver network.Version) (types.StateTreeVersion, error) {
 	case network.Version13, network.Version14, network.Version15, network.Version16, network.Version17:
 		return types.StateTreeVersion4, nil
 
-	case network.Version18, network.Version19, network.Version20:
+	case network.Version18, network.Version19, network.Version20, network.Version21:
 		return types.StateTreeVersion5, nil
 
 	default:
diff --git a/chain/stmgr/actors.go b/chain/stmgr/actors.go
index 4de39c7f172..56744fa7489 100644
--- a/chain/stmgr/actors.go
+++ b/chain/stmgr/actors.go
@@ -355,7 +355,7 @@ func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcs beacon.Schedule
 		return nil, xerrors.Errorf("failed to marshal miner address: %w", err)
 	}
 
-	prand, err := rand.DrawRandomness(rbase.Data, crypto.DomainSeparationTag_WinningPoStChallengeSeed, round, buf.Bytes())
+	prand, err := rand.DrawRandomnessFromBase(rbase.Data, crypto.DomainSeparationTag_WinningPoStChallengeSeed, round, buf.Bytes())
 	if err != nil {
 		return nil, xerrors.Errorf("failed to get randomness for winning post: %w", err)
 	}
diff --git a/chain/stmgr/forks.go b/chain/stmgr/forks.go
index 1f9977d961d..8d1ac1dfbba 100644
--- a/chain/stmgr/forks.go
+++ b/chain/stmgr/forks.go
@@ -4,6 +4,7 @@ import (
 	"bytes"
 	"context"
 	"encoding/binary"
+	"errors"
 	"os"
 	"sort"
 	"strings"
@@ -11,6 +12,7 @@ import (
 	"time"
 
 	"github.com/ipfs/go-cid"
+	"github.com/ipfs/go-datastore"
 	"golang.org/x/xerrors"
 
 	"github.com/filecoin-project/go-address"
@@ -176,12 +178,18 @@ func (sm *StateManager) HandleStateForks(ctx context.Context, root cid.Cid, heig
 	retCid := root
 	u := sm.stateMigrations[height]
 	if u != nil && u.upgrade != nil {
-		migCid, ok, err := u.migrationResultCache.Get(ctx, root)
-		if err == nil && ok {
-			log.Infow("CACHED migration", "height", height, "from", root, "to", migCid)
-			return migCid, nil
-		} else if err != nil {
-			log.Errorw("failed to lookup previous migration result", "err", err)
+		if height != build.UpgradeWatermelonFixHeight {
+			migCid, ok, err := u.migrationResultCache.Get(ctx, root)
+			if err == nil {
+				if ok {
+					log.Infow("CACHED migration", "height", height, "from", root, "to", migCid)
+					return migCid, nil
+				}
+			} else if !errors.Is(err, datastore.ErrNotFound) {
+				log.Errorw("failed to lookup previous migration result", "err", err)
+			} else {
+				log.Debug("no cached migration found, migrating from scratch")
+			}
 		}
 
 		startTime := time.Now()
@@ -189,6 +197,7 @@ func (sm *StateManager) HandleStateForks(ctx context.Context, root cid.Cid, heig
 		// Yes, we clone the cache, even for the final upgrade epoch. Why? Reverts. We may
 		// have to migrate multiple times.
 		tmpCache := u.cache.Clone()
+		var err error
 		retCid, err = u.upgrade(ctx, sm, tmpCache, cb, root, height, ts)
 		if err != nil {
 			log.Errorw("FAILED migration", "height", height, "from", root, "error", err)
diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go
index 12b991e577f..49913e442d1 100644
--- a/chain/stmgr/stmgr.go
+++ b/chain/stmgr/stmgr.go
@@ -7,7 +7,7 @@ import (
 	"strconv"
 	"sync"
 
-	lru "github.com/hashicorp/golang-lru/v2"
+	"github.com/hashicorp/golang-lru/arc/v2"
 	"github.com/ipfs/go-cid"
 	dstore "github.com/ipfs/go-datastore"
 	cbor "github.com/ipfs/go-ipld-cbor"
@@ -156,7 +156,7 @@ type StateManager struct {
 
 	// We keep a small cache for calls to ExecutionTrace which helps improve
 	// performance for node operators like exchanges and block explorers
-	execTraceCache *lru.ARCCache[types.TipSetKey, tipSetCacheEntry]
+	execTraceCache *arc.ARCCache[types.TipSetKey, tipSetCacheEntry]
 	// We need a lock while making the copy as to prevent other callers
 	// overwrite the cache while making the copy
 	execTraceCacheLock sync.Mutex
@@ -213,10 +213,10 @@ func NewStateManager(cs *store.ChainStore, exec Executor, sys vm.SyscallBuilder,
 	}
 
 	log.Debugf("execTraceCache size: %d", execTraceCacheSize)
-	var execTraceCache *lru.ARCCache[types.TipSetKey, tipSetCacheEntry]
+	var execTraceCache *arc.ARCCache[types.TipSetKey, tipSetCacheEntry]
 	var err error
 	if execTraceCacheSize > 0 {
-		execTraceCache, err = lru.NewARC[types.TipSetKey, tipSetCacheEntry](execTraceCacheSize)
+		execTraceCache, err = arc.NewARC[types.TipSetKey, tipSetCacheEntry](execTraceCacheSize)
 		if err != nil {
 			return nil, err
 		}
@@ -509,7 +509,17 @@ func (sm *StateManager) GetRandomnessFromBeacon(ctx context.Context, personaliza
 
 	r := rand.NewStateRand(sm.ChainStore(), pts.Cids(), sm.beacon, sm.GetNetworkVersion)
 
-	return r.GetBeaconRandomness(ctx, personalization, randEpoch, entropy)
+	digest, err := r.GetBeaconRandomness(ctx, randEpoch)
+	if err != nil {
+		return nil, xerrors.Errorf("getting beacon randomness: %w", err)
+	}
+
+	ret, err := rand.DrawRandomnessFromDigest(digest, personalization, randEpoch, entropy)
+	if err != nil {
+		return nil, xerrors.Errorf("drawing beacon randomness: %w", err)
+	}
+
+	return ret, nil
 
 }
 
@@ -521,5 +531,38 @@ func (sm *StateManager) GetRandomnessFromTickets(ctx context.Context, personaliz
 
 	r := rand.NewStateRand(sm.ChainStore(), pts.Cids(), sm.beacon, sm.GetNetworkVersion)
 
-	return r.GetChainRandomness(ctx, personalization, randEpoch, entropy)
+	digest, err := r.GetChainRandomness(ctx, randEpoch)
+	if err != nil {
+		return nil, xerrors.Errorf("getting chain randomness: %w", err)
+	}
+
+	ret, err := rand.DrawRandomnessFromDigest(digest, personalization, randEpoch, entropy)
+	if err != nil {
+		return nil, xerrors.Errorf("drawing chain randomness: %w", err)
+	}
+
+	return ret, nil
+}
+
+func (sm *StateManager) GetRandomnessDigestFromBeacon(ctx context.Context, randEpoch abi.ChainEpoch, tsk types.TipSetKey) ([32]byte, error) {
+	pts, err := sm.ChainStore().GetTipSetFromKey(ctx, tsk)
+	if err != nil {
+		return [32]byte{}, xerrors.Errorf("loading tipset %s: %w", tsk, err)
+	}
+
+	r := rand.NewStateRand(sm.ChainStore(), pts.Cids(), sm.beacon, sm.GetNetworkVersion)
+
+	return r.GetBeaconRandomness(ctx, randEpoch)
+
+}
+
+func (sm *StateManager) GetRandomnessDigestFromTickets(ctx context.Context, randEpoch abi.ChainEpoch, tsk types.TipSetKey) ([32]byte, error) {
+	pts, err := sm.ChainStore().LoadTipSet(ctx, tsk)
+	if err != nil {
+		return [32]byte{}, xerrors.Errorf("loading tipset key: %w", err)
+	}
+
+	r := rand.NewStateRand(sm.ChainStore(), pts.Cids(), sm.beacon, sm.GetNetworkVersion)
+
+	return r.GetChainRandomness(ctx, randEpoch)
 }
diff --git a/chain/store/store.go b/chain/store/store.go
index 88103ac48be..342939daffa 100644
--- a/chain/store/store.go
+++ b/chain/store/store.go
@@ -11,7 +11,7 @@ import (
 	"sync"
 	"time"
 
-	lru "github.com/hashicorp/golang-lru/v2"
+	"github.com/hashicorp/golang-lru/arc/v2"
 	block "github.com/ipfs/go-block-format"
 	"github.com/ipfs/go-cid"
 	dstore "github.com/ipfs/go-datastore"
@@ -120,8 +120,8 @@ type ChainStore struct {
 	reorgCh        chan<- reorg
 	reorgNotifeeCh chan ReorgNotifee
 
-	mmCache *lru.ARCCache[cid.Cid, mmCids]
-	tsCache *lru.ARCCache[types.TipSetKey, *types.TipSet]
+	mmCache *arc.ARCCache[cid.Cid, mmCids]
+	tsCache *arc.ARCCache[types.TipSetKey, *types.TipSet]
 
 	evtTypes [1]journal.EventType
 	journal  journal.Journal
@@ -133,8 +133,8 @@ type ChainStore struct {
 }
 
 func NewChainStore(chainBs bstore.Blockstore, stateBs bstore.Blockstore, ds dstore.Batching, weight WeightFunc, j journal.Journal) *ChainStore {
-	c, _ := lru.NewARC[cid.Cid, mmCids](DefaultMsgMetaCacheSize)
-	tsc, _ := lru.NewARC[types.TipSetKey, *types.TipSet](DefaultTipSetCacheSize)
+	c, _ := arc.NewARC[cid.Cid, mmCids](DefaultMsgMetaCacheSize)
+	tsc, _ := arc.NewARC[types.TipSetKey, *types.TipSet](DefaultTipSetCacheSize)
 	if j == nil {
 		j = journal.NilJournal()
 	}
diff --git a/chain/sync.go b/chain/sync.go
index 7830a977112..d8892a84ef8 100644
--- a/chain/sync.go
+++ b/chain/sync.go
@@ -1094,8 +1094,8 @@ func (syncer *Syncer) fetchMessages(ctx context.Context, headers []*types.TipSet
 						requestErr = multierror.Append(requestErr, err)
 					} else {
 						isGood := true
-						for index, ts := range headers[nextI:lastI] {
-							cm := result[index]
+						for index, cm := range result {
+							ts := headers[nextI+index]
 							if err := checkMsgMeta(ts, cm.Bls, cm.Secpk, cm.BlsIncludes, cm.SecpkIncludes); err != nil {
 								log.Errorf("fetched messages not as expected: %s", err)
 								isGood = false
diff --git a/chain/types/cbor_gen.go b/chain/types/cbor_gen.go
index 90d1a14c598..fe8e7e3fee2 100644
--- a/chain/types/cbor_gen.go
+++ b/chain/types/cbor_gen.go
@@ -91,9 +91,11 @@ func (t *BlockHeader) MarshalCBOR(w io.Writer) error {
 		return err
 	}
 	for _, v := range t.Parents {
-		if err := cbg.WriteCid(w, v); err != nil {
-			return xerrors.Errorf("failed writing cid field t.Parents: %w", err)
+
+		if err := cbg.WriteCid(cw, v); err != nil {
+			return xerrors.Errorf("failed to write cid field v: %w", err)
 		}
+
 	}
 
 	// t.ParentWeight (big.Int) (struct)
@@ -249,13 +251,22 @@ func (t *BlockHeader) UnmarshalCBOR(r io.Reader) (err error) {
 	}
 
 	for i := 0; i < int(extra); i++ {
+		{
+			var maj byte
+			var extra uint64
+			var err error
+			_ = maj
+			_ = extra
+			_ = err
 
-		var v BeaconEntry
-		if err := v.UnmarshalCBOR(cr); err != nil {
-			return err
-		}
+			{
+
+				if err := t.BeaconEntries[i].UnmarshalCBOR(cr); err != nil {
+					return xerrors.Errorf("unmarshaling t.BeaconEntries[i]: %w", err)
+				}
 
-		t.BeaconEntries[i] = v
+			}
+		}
 	}
 
 	// t.WinPoStProof ([]proof.PoStProof) (slice)
@@ -278,13 +289,22 @@ func (t *BlockHeader) UnmarshalCBOR(r io.Reader) (err error) {
 	}
 
 	for i := 0; i < int(extra); i++ {
+		{
+			var maj byte
+			var extra uint64
+			var err error
+			_ = maj
+			_ = extra
+			_ = err
 
-		var v proof.PoStProof
-		if err := v.UnmarshalCBOR(cr); err != nil {
-			return err
-		}
+			{
 
-		t.WinPoStProof[i] = v
+				if err := t.WinPoStProof[i].UnmarshalCBOR(cr); err != nil {
+					return xerrors.Errorf("unmarshaling t.WinPoStProof[i]: %w", err)
+				}
+
+			}
+		}
 	}
 
 	// t.Parents ([]cid.Cid) (slice)
@@ -307,12 +327,25 @@ func (t *BlockHeader) UnmarshalCBOR(r io.Reader) (err error) {
 	}
 
 	for i := 0; i < int(extra); i++ {
+		{
+			var maj byte
+			var extra uint64
+			var err error
+			_ = maj
+			_ = extra
+			_ = err
 
-		c, err := cbg.ReadCid(cr)
-		if err != nil {
-			return xerrors.Errorf("reading cid field t.Parents failed: %w", err)
+			{
+
+				c, err := cbg.ReadCid(cr)
+				if err != nil {
+					return xerrors.Errorf("failed to read cid field t.Parents[i]: %w", err)
+				}
+
+				t.Parents[i] = c
+
+			}
 		}
-		t.Parents[i] = c
 	}
 
 	// t.ParentWeight (big.Int) (struct)
@@ -1318,9 +1351,11 @@ func (t *BlockMsg) MarshalCBOR(w io.Writer) error {
 		return err
 	}
 	for _, v := range t.BlsMessages {
-		if err := cbg.WriteCid(w, v); err != nil {
-			return xerrors.Errorf("failed writing cid field t.BlsMessages: %w", err)
+
+		if err := cbg.WriteCid(cw, v); err != nil {
+			return xerrors.Errorf("failed to write cid field v: %w", err)
 		}
+
 	}
 
 	// t.SecpkMessages ([]cid.Cid) (slice)
@@ -1332,9 +1367,11 @@ func (t *BlockMsg) MarshalCBOR(w io.Writer) error {
 		return err
 	}
 	for _, v := range t.SecpkMessages {
-		if err := cbg.WriteCid(w, v); err != nil {
-			return xerrors.Errorf("failed writing cid field t.SecpkMessages: %w", err)
+
+		if err := cbg.WriteCid(cw, v); err != nil {
+			return xerrors.Errorf("failed to write cid field v: %w", err)
 		}
+
 	}
 	return nil
 }
@@ -1401,12 +1438,25 @@ func (t *BlockMsg) UnmarshalCBOR(r io.Reader) (err error) {
 	}
 
 	for i := 0; i < int(extra); i++ {
+		{
+			var maj byte
+			var extra uint64
+			var err error
+			_ = maj
+			_ = extra
+			_ = err
 
-		c, err := cbg.ReadCid(cr)
-		if err != nil {
-			return xerrors.Errorf("reading cid field t.BlsMessages failed: %w", err)
+			{
+
+				c, err := cbg.ReadCid(cr)
+				if err != nil {
+					return xerrors.Errorf("failed to read cid field t.BlsMessages[i]: %w", err)
+				}
+
+				t.BlsMessages[i] = c
+
+			}
 		}
-		t.BlsMessages[i] = c
 	}
 
 	// t.SecpkMessages ([]cid.Cid) (slice)
@@ -1429,12 +1479,25 @@ func (t *BlockMsg) UnmarshalCBOR(r io.Reader) (err error) {
 	}
 
 	for i := 0; i < int(extra); i++ {
+		{
+			var maj byte
+			var extra uint64
+			var err error
+			_ = maj
+			_ = extra
+			_ = err
 
-		c, err := cbg.ReadCid(cr)
-		if err != nil {
-			return xerrors.Errorf("reading cid field t.SecpkMessages failed: %w", err)
+			{
+
+				c, err := cbg.ReadCid(cr)
+				if err != nil {
+					return xerrors.Errorf("failed to read cid field t.SecpkMessages[i]: %w", err)
+				}
+
+				t.SecpkMessages[i] = c
+
+			}
 		}
-		t.SecpkMessages[i] = c
 	}
 
 	return nil
@@ -1463,9 +1526,11 @@ func (t *ExpTipSet) MarshalCBOR(w io.Writer) error {
 		return err
 	}
 	for _, v := range t.Cids {
-		if err := cbg.WriteCid(w, v); err != nil {
-			return xerrors.Errorf("failed writing cid field t.Cids: %w", err)
+
+		if err := cbg.WriteCid(cw, v); err != nil {
+			return xerrors.Errorf("failed to write cid field v: %w", err)
 		}
+
 	}
 
 	// t.Blocks ([]*types.BlockHeader) (slice)
@@ -1538,12 +1603,25 @@ func (t *ExpTipSet) UnmarshalCBOR(r io.Reader) (err error) {
 	}
 
 	for i := 0; i < int(extra); i++ {
+		{
+			var maj byte
+			var extra uint64
+			var err error
+			_ = maj
+			_ = extra
+			_ = err
 
-		c, err := cbg.ReadCid(cr)
-		if err != nil {
-			return xerrors.Errorf("reading cid field t.Cids failed: %w", err)
+			{
+
+				c, err := cbg.ReadCid(cr)
+				if err != nil {
+					return xerrors.Errorf("failed to read cid field t.Cids[i]: %w", err)
+				}
+
+				t.Cids[i] = c
+
+			}
 		}
-		t.Cids[i] = c
 	}
 
 	// t.Blocks ([]*types.BlockHeader) (slice)
@@ -1566,13 +1644,32 @@ func (t *ExpTipSet) UnmarshalCBOR(r io.Reader) (err error) {
 	}
 
 	for i := 0; i < int(extra); i++ {
+		{
+			var maj byte
+			var extra uint64
+			var err error
+			_ = maj
+			_ = extra
+			_ = err
+
+			{
+
+				b, err := cr.ReadByte()
+				if err != nil {
+					return err
+				}
+				if b != cbg.CborNull[0] {
+					if err := cr.UnreadByte(); err != nil {
+						return err
+					}
+					t.Blocks[i] = new(BlockHeader)
+					if err := t.Blocks[i].UnmarshalCBOR(cr); err != nil {
+						return xerrors.Errorf("unmarshaling t.Blocks[i] pointer: %w", err)
+					}
+				}
 
-		var v BlockHeader
-		if err := v.UnmarshalCBOR(cr); err != nil {
-			return err
+			}
 		}
-
-		t.Blocks[i] = &v
 	}
 
 	// t.Height (abi.ChainEpoch) (int64)
@@ -1933,13 +2030,22 @@ func (t *Event) UnmarshalCBOR(r io.Reader) (err error) {
 	}
 
 	for i := 0; i < int(extra); i++ {
+		{
+			var maj byte
+			var extra uint64
+			var err error
+			_ = maj
+			_ = extra
+			_ = err
 
-		var v EventEntry
-		if err := v.UnmarshalCBOR(cr); err != nil {
-			return err
-		}
+			{
+
+				if err := t.Entries[i].UnmarshalCBOR(cr); err != nil {
+					return xerrors.Errorf("unmarshaling t.Entries[i]: %w", err)
+				}
 
-		t.Entries[i] = v
+			}
+		}
 	}
 
 	return nil
@@ -1972,7 +2078,7 @@ func (t *EventEntry) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Key))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string(t.Key)); err != nil {
+	if _, err := cw.WriteString(string(t.Key)); err != nil {
 		return err
 	}
 
@@ -2103,7 +2209,7 @@ func (t *GasTrace) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Name))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string(t.Name)); err != nil {
+	if _, err := cw.WriteString(string(t.Name)); err != nil {
 		return err
 	}
 
@@ -2289,7 +2395,7 @@ func (t *GasTrace) UnmarshalCBOR(r io.Reader) (err error) {
 	return nil
 }
 
-var lengthBufMessageTrace = []byte{134}
+var lengthBufMessageTrace = []byte{137}
 
 func (t *MessageTrace) MarshalCBOR(w io.Writer) error {
 	if t == nil {
@@ -2343,6 +2449,23 @@ func (t *MessageTrace) MarshalCBOR(w io.Writer) error {
 		return err
 	}
 
+	// t.GasLimit (uint64) (uint64)
+
+	if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.GasLimit)); err != nil {
+		return err
+	}
+
+	// t.ReadOnly (bool) (bool)
+	if err := cbg.WriteBool(w, t.ReadOnly); err != nil {
+		return err
+	}
+
+	// t.CodeCid (cid.Cid) (struct)
+
+	if err := cbg.WriteCid(cw, t.CodeCid); err != nil {
+		return xerrors.Errorf("failed to write cid field t.CodeCid: %w", err)
+	}
+
 	return nil
 }
 
@@ -2365,7 +2488,7 @@ func (t *MessageTrace) UnmarshalCBOR(r io.Reader) (err error) {
 		return fmt.Errorf("cbor input should be of type array")
 	}
 
-	if extra != 6 {
+	if extra != 9 {
 		return fmt.Errorf("cbor input had wrong number of fields")
 	}
 
@@ -2444,6 +2567,49 @@ func (t *MessageTrace) UnmarshalCBOR(r io.Reader) (err error) {
 		}
 		t.ParamsCodec = uint64(extra)
 
+	}
+	// t.GasLimit (uint64) (uint64)
+
+	{
+
+		maj, extra, err = cr.ReadHeader()
+		if err != nil {
+			return err
+		}
+		if maj != cbg.MajUnsignedInt {
+			return fmt.Errorf("wrong type for uint64 field")
+		}
+		t.GasLimit = uint64(extra)
+
+	}
+	// t.ReadOnly (bool) (bool)
+
+	maj, extra, err = cr.ReadHeader()
+	if err != nil {
+		return err
+	}
+	if maj != cbg.MajOther {
+		return fmt.Errorf("booleans must be major type 7")
+	}
+	switch extra {
+	case 20:
+		t.ReadOnly = false
+	case 21:
+		t.ReadOnly = true
+	default:
+		return fmt.Errorf("booleans are either major type 7, value 20 or 21 (got %d)", extra)
+	}
+	// t.CodeCid (cid.Cid) (struct)
+
+	{
+
+		c, err := cbg.ReadCid(cr)
+		if err != nil {
+			return xerrors.Errorf("failed to read cid field t.CodeCid: %w", err)
+		}
+
+		t.CodeCid = c
+
 	}
 	return nil
 }
@@ -2696,13 +2862,32 @@ func (t *ExecutionTrace) UnmarshalCBOR(r io.Reader) (err error) {
 	}
 
 	for i := 0; i < int(extra); i++ {
+		{
+			var maj byte
+			var extra uint64
+			var err error
+			_ = maj
+			_ = extra
+			_ = err
+
+			{
+
+				b, err := cr.ReadByte()
+				if err != nil {
+					return err
+				}
+				if b != cbg.CborNull[0] {
+					if err := cr.UnreadByte(); err != nil {
+						return err
+					}
+					t.GasCharges[i] = new(GasTrace)
+					if err := t.GasCharges[i].UnmarshalCBOR(cr); err != nil {
+						return xerrors.Errorf("unmarshaling t.GasCharges[i] pointer: %w", err)
+					}
+				}
 
-		var v GasTrace
-		if err := v.UnmarshalCBOR(cr); err != nil {
-			return err
+			}
 		}
-
-		t.GasCharges[i] = &v
 	}
 
 	// t.Subcalls ([]types.ExecutionTrace) (slice)
@@ -2725,13 +2910,22 @@ func (t *ExecutionTrace) UnmarshalCBOR(r io.Reader) (err error) {
 	}
 
 	for i := 0; i < int(extra); i++ {
+		{
+			var maj byte
+			var extra uint64
+			var err error
+			_ = maj
+			_ = extra
+			_ = err
 
-		var v ExecutionTrace
-		if err := v.UnmarshalCBOR(cr); err != nil {
-			return err
-		}
+			{
 
-		t.Subcalls[i] = v
+				if err := t.Subcalls[i].UnmarshalCBOR(cr); err != nil {
+					return xerrors.Errorf("unmarshaling t.Subcalls[i]: %w", err)
+				}
+
+			}
+		}
 	}
 
 	return nil
diff --git a/chain/types/execresult.go b/chain/types/execresult.go
index 2a25d22e28a..4556f7b88ec 100644
--- a/chain/types/execresult.go
+++ b/chain/types/execresult.go
@@ -4,6 +4,8 @@ import (
 	"encoding/json"
 	"time"
 
+	"github.com/ipfs/go-cid"
+
 	"github.com/filecoin-project/go-address"
 	"github.com/filecoin-project/go-state-types/abi"
 	"github.com/filecoin-project/go-state-types/exitcode"
@@ -24,6 +26,9 @@ type MessageTrace struct {
 	Method      abi.MethodNum
 	Params      []byte
 	ParamsCodec uint64
+	GasLimit    uint64
+	ReadOnly    bool
+	CodeCid     cid.Cid
 }
 
 type ReturnTrace struct {
diff --git a/chain/vm/fvm.go b/chain/vm/fvm.go
index 08df7b2e0d2..47b4d3320ec 100644
--- a/chain/vm/fvm.go
+++ b/chain/vm/fvm.go
@@ -33,6 +33,7 @@ import (
 	"github.com/filecoin-project/lotus/chain/actors/aerrors"
 	"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
 	"github.com/filecoin-project/lotus/chain/actors/policy"
+	"github.com/filecoin-project/lotus/chain/rand"
 	"github.com/filecoin-project/lotus/chain/state"
 	"github.com/filecoin-project/lotus/chain/types"
 	"github.com/filecoin-project/lotus/lib/sigs"
@@ -43,7 +44,7 @@ var _ Interface = (*FVM)(nil)
 var _ ffi_cgo.Externs = (*FvmExtern)(nil)
 
 type FvmExtern struct {
-	Rand
+	rand.Rand
 	blockstore.Blockstore
 	epoch   abi.ChainEpoch
 	lbState LookbackStateGetter
@@ -91,6 +92,15 @@ func (x *FvmExtern) VerifyConsensusFault(ctx context.Context, a, b, extra []byte
 		log.Info("invalid consensus fault: submitted blocks are the same")
 		return ret, totalGas
 	}
+
+	// workaround chain halt
+	if build.IsNearUpgrade(blockA.Height, build.UpgradeWatermelonFixHeight) {
+		return ret, totalGas
+	}
+	if build.IsNearUpgrade(blockB.Height, build.UpgradeWatermelonFixHeight) {
+		return ret, totalGas
+	}
+
 	// (1) check conditions necessary to any consensus fault
 
 	// were blocks mined by same miner?
diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go
index a5b10823813..355fcea2b09 100644
--- a/chain/vm/runtime.go
+++ b/chain/vm/runtime.go
@@ -33,6 +33,7 @@ import (
 	"github.com/filecoin-project/lotus/chain/actors"
 	"github.com/filecoin-project/lotus/chain/actors/aerrors"
 	"github.com/filecoin-project/lotus/chain/actors/builtin"
+	"github.com/filecoin-project/lotus/chain/rand"
 	"github.com/filecoin-project/lotus/chain/state"
 	"github.com/filecoin-project/lotus/chain/types"
 )
@@ -229,21 +230,35 @@ func (rt *Runtime) GetActorCodeCID(addr address.Address) (ret cid.Cid, ok bool)
 }
 
 func (rt *Runtime) GetRandomnessFromTickets(personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) abi.Randomness {
-	res, err := rt.vm.rand.GetChainRandomness(rt.ctx, personalization, randEpoch, entropy)
+	digest, err := rt.vm.rand.GetChainRandomness(rt.ctx, randEpoch)
 
 	if err != nil {
 		panic(aerrors.Fatalf("could not get ticket randomness: %s", err))
 	}
-	return res
+
+	ret, err := rand.DrawRandomnessFromDigest(digest, personalization, randEpoch, entropy)
+
+	if err != nil {
+		panic(aerrors.Fatalf("could not draw ticket randomness: %s", err))
+	}
+
+	return ret
 }
 
 func (rt *Runtime) GetRandomnessFromBeacon(personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) abi.Randomness {
-	res, err := rt.vm.rand.GetBeaconRandomness(rt.ctx, personalization, randEpoch, entropy)
+	digest, err := rt.vm.rand.GetBeaconRandomness(rt.ctx, randEpoch)
 
 	if err != nil {
-		panic(aerrors.Fatalf("could not get beacon randomness: %s", err))
+		panic(aerrors.Fatalf("could not get ticket randomness: %s", err))
 	}
-	return res
+
+	ret, err := rand.DrawRandomnessFromDigest(digest, personalization, randEpoch, entropy)
+
+	if err != nil {
+		panic(aerrors.Fatalf("could not draw ticket randomness: %s", err))
+	}
+
+	return ret
 }
 
 func (rt *Runtime) NewActorAddress() address.Address {
diff --git a/chain/vm/vm.go b/chain/vm/vm.go
index 58afc14bc18..8f4c89e9232 100644
--- a/chain/vm/vm.go
+++ b/chain/vm/vm.go
@@ -21,7 +21,6 @@ import (
 	"github.com/filecoin-project/go-state-types/abi"
 	"github.com/filecoin-project/go-state-types/big"
 	builtin_types "github.com/filecoin-project/go-state-types/builtin"
-	"github.com/filecoin-project/go-state-types/crypto"
 	"github.com/filecoin-project/go-state-types/exitcode"
 	"github.com/filecoin-project/go-state-types/network"
 
@@ -32,6 +31,7 @@ import (
 	"github.com/filecoin-project/lotus/chain/actors/builtin"
 	"github.com/filecoin-project/lotus/chain/actors/builtin/account"
 	"github.com/filecoin-project/lotus/chain/actors/builtin/reward"
+	"github.com/filecoin-project/lotus/chain/rand"
 	"github.com/filecoin-project/lotus/chain/state"
 	"github.com/filecoin-project/lotus/chain/types"
 	"github.com/filecoin-project/lotus/metrics"
@@ -224,7 +224,7 @@ type LegacyVM struct {
 	buf            *blockstore.BufferedBlockstore
 	blockHeight    abi.ChainEpoch
 	areg           *ActorRegistry
-	rand           Rand
+	rand           rand.Rand
 	circSupplyCalc CircSupplyCalculator
 	networkVersion network.Version
 	baseFee        abi.TokenAmount
@@ -238,7 +238,7 @@ type VMOpts struct {
 	StateBase      cid.Cid
 	Epoch          abi.ChainEpoch
 	Timestamp      uint64
-	Rand           Rand
+	Rand           rand.Rand
 	Bstore         blockstore.Blockstore
 	Actors         *ActorRegistry
 	Syscalls       SyscallBuilder
@@ -287,11 +287,6 @@ func NewLegacyVM(ctx context.Context, opts *VMOpts) (*LegacyVM, error) {
 	}, nil
 }
 
-type Rand interface {
-	GetChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error)
-	GetBeaconRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error)
-}
-
 type ApplyRet struct {
 	types.MessageReceipt
 	ActorErr       aerrors.ActorError
diff --git a/cmd/lotus-bench/main.go b/cmd/lotus-bench/main.go
index 6e7e274f218..303dd52c901 100644
--- a/cmd/lotus-bench/main.go
+++ b/cmd/lotus-bench/main.go
@@ -334,7 +334,7 @@ var sealBenchCmd = &cli.Command{
 
 		if !skipc2 {
 			log.Info("generating winning post candidates")
-			wipt, err := spt(sectorSize).RegisteredWinningPoStProof()
+			wipt, err := spt(sectorSize, false).RegisteredWinningPoStProof()
 			if err != nil {
 				return err
 			}
@@ -552,7 +552,7 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, par
 				Miner:  mid,
 				Number: i,
 			},
-			ProofType: spt(sectorSize),
+			ProofType: spt(sectorSize, false),
 		}
 
 		start := time.Now()
@@ -584,7 +584,7 @@ func runSeals(sb *ffiwrapper.Sealer, sbfs *basicfs.Provider, numSectors int, par
 							Miner:  mid,
 							Number: i,
 						},
-						ProofType: spt(sectorSize),
+						ProofType: spt(sectorSize, false),
 					}
 
 					start := time.Now()
@@ -795,7 +795,7 @@ var proveCmd = &cli.Command{
 				Miner:  abi.ActorID(mid),
 				Number: abi.SectorNumber(c2in.SectorNum),
 			},
-			ProofType: spt(abi.SectorSize(c2in.SectorSize)),
+			ProofType: spt(abi.SectorSize(c2in.SectorSize), false),
 		}
 
 		fmt.Printf("----\nstart proof computation\n")
@@ -826,8 +826,8 @@ func bps(sectorSize abi.SectorSize, sectorNum int, d time.Duration) string {
 	return types.SizeStr(types.BigInt{Int: bps}) + "/s"
 }
 
-func spt(ssize abi.SectorSize) abi.RegisteredSealProof {
-	spt, err := miner.SealProofTypeFromSectorSize(ssize, build.TestNetworkVersion)
+func spt(ssize abi.SectorSize, synth bool) abi.RegisteredSealProof {
+	spt, err := miner.SealProofTypeFromSectorSize(ssize, build.TestNetworkVersion, synth)
 	if err != nil {
 		panic(err)
 	}
diff --git a/cmd/lotus-bench/simple.go b/cmd/lotus-bench/simple.go
index a742b0fb38c..d19c37bc960 100644
--- a/cmd/lotus-bench/simple.go
+++ b/cmd/lotus-bench/simple.go
@@ -181,7 +181,7 @@ var simpleAddPiece = &cli.Command{
 				Miner:  mid,
 				Number: 1,
 			},
-			ProofType: spt(sectorSize),
+			ProofType: spt(sectorSize, false),
 		}
 
 		data, err := os.Open(cctx.Args().First())
@@ -218,6 +218,10 @@ var simplePreCommit1 = &cli.Command{
 			Usage: "pass miner address (only necessary if using existing sectorbuilder)",
 			Value: "t01000",
 		},
+		&cli.BoolFlag{
+			Name:  "synthetic",
+			Usage: "generate synthetic PoRep proofs",
+		},
 	},
 	ArgsUsage: "[unsealed] [sealed] [cache] [[piece cid] [piece size]]...",
 	Action: func(cctx *cli.Context) error {
@@ -254,7 +258,7 @@ var simplePreCommit1 = &cli.Command{
 				Miner:  mid,
 				Number: 1,
 			},
-			ProofType: spt(sectorSize),
+			ProofType: spt(sectorSize, cctx.Bool("synthetic")),
 		}
 
 		var ticket [32]byte // all zero
@@ -292,6 +296,10 @@ var simplePreCommit2 = &cli.Command{
 			Usage: "pass miner address (only necessary if using existing sectorbuilder)",
 			Value: "t01000",
 		},
+		&cli.BoolFlag{
+			Name:  "synthetic",
+			Usage: "generate synthetic PoRep proofs",
+		},
 	},
 	ArgsUsage: "[sealed] [cache] [pc1 out]",
 	Action: func(cctx *cli.Context) error {
@@ -332,7 +340,7 @@ var simplePreCommit2 = &cli.Command{
 				Miner:  mid,
 				Number: 1,
 			},
-			ProofType: spt(sectorSize),
+			ProofType: spt(sectorSize, cctx.Bool("synthetic")),
 		}
 
 		start := time.Now()
@@ -363,6 +371,10 @@ var simpleCommit1 = &cli.Command{
 			Usage: "pass miner address (only necessary if using existing sectorbuilder)",
 			Value: "t01000",
 		},
+		&cli.BoolFlag{
+			Name:  "synthetic",
+			Usage: "generate synthetic PoRep proofs",
+		},
 	},
 	ArgsUsage: "[sealed] [cache] [comm D] [comm R] [c1out.json]",
 	Action: func(cctx *cli.Context) error {
@@ -398,7 +410,7 @@ var simpleCommit1 = &cli.Command{
 				Miner:  mid,
 				Number: 1,
 			},
-			ProofType: spt(sectorSize),
+			ProofType: spt(sectorSize, cctx.Bool("synthetic")),
 		}
 
 		start := time.Now()
@@ -464,6 +476,10 @@ var simpleCommit2 = &cli.Command{
 			Usage: "pass miner address (only necessary if using existing sectorbuilder)",
 			Value: "t01000",
 		},
+		&cli.BoolFlag{
+			Name:  "synthetic",
+			Usage: "generate synthetic PoRep proofs",
+		},
 	},
 	Action: func(c *cli.Context) error {
 		if c.Bool("no-gpu") {
@@ -510,7 +526,7 @@ var simpleCommit2 = &cli.Command{
 				Miner:  abi.ActorID(mid),
 				Number: abi.SectorNumber(c2in.SectorNum),
 			},
-			ProofType: spt(abi.SectorSize(c2in.SectorSize)),
+			ProofType: spt(abi.SectorSize(c2in.SectorSize), c.Bool("synthetic")),
 		}
 
 		start := time.Now()
@@ -568,7 +584,7 @@ var simpleWindowPost = &cli.Command{
 			return xerrors.Errorf("parse commr: %w", err)
 		}
 
-		wpt, err := spt(sectorSize).RegisteredWindowPoStProof()
+		wpt, err := spt(sectorSize, false).RegisteredWindowPoStProof()
 		if err != nil {
 			return err
 		}
@@ -588,7 +604,7 @@ var simpleWindowPost = &cli.Command{
 
 		vp, err := ffi.GenerateSingleVanillaProof(ffi.PrivateSectorInfo{
 			SectorInfo: prf.SectorInfo{
-				SealProof:    spt(sectorSize),
+				SealProof:    spt(sectorSize, false),
 				SectorNumber: sn,
 				SealedCID:    commr,
 			},
@@ -655,7 +671,7 @@ var simpleWinningPost = &cli.Command{
 			return xerrors.Errorf("parse commr: %w", err)
 		}
 
-		wpt, err := spt(sectorSize).RegisteredWinningPoStProof()
+		wpt, err := spt(sectorSize, false).RegisteredWinningPoStProof()
 		if err != nil {
 			return err
 		}
@@ -675,7 +691,7 @@ var simpleWinningPost = &cli.Command{
 
 		vp, err := ffi.GenerateSingleVanillaProof(ffi.PrivateSectorInfo{
 			SectorInfo: prf.SectorInfo{
-				SealProof:    spt(sectorSize),
+				SealProof:    spt(sectorSize, false),
 				SectorNumber: sn,
 				SealedCID:    commr,
 			},
@@ -758,7 +774,7 @@ var simpleReplicaUpdate = &cli.Command{
 				Miner:  mid,
 				Number: 1,
 			},
-			ProofType: spt(sectorSize),
+			ProofType: spt(sectorSize, false),
 		}
 
 		start := time.Now()
@@ -826,7 +842,7 @@ var simpleProveReplicaUpdate1 = &cli.Command{
 				Miner:  mid,
 				Number: 1,
 			},
-			ProofType: spt(sectorSize),
+			ProofType: spt(sectorSize, false),
 		}
 
 		start := time.Now()
@@ -913,7 +929,7 @@ var simpleProveReplicaUpdate2 = &cli.Command{
 				Miner:  mid,
 				Number: 1,
 			},
-			ProofType: spt(sectorSize),
+			ProofType: spt(sectorSize, false),
 		}
 
 		start := time.Now()
diff --git a/cmd/lotus-miner/actor.go b/cmd/lotus-miner/actor.go
index f0c52278a61..6d76cc07fdc 100644
--- a/cmd/lotus-miner/actor.go
+++ b/cmd/lotus-miner/actor.go
@@ -1292,7 +1292,7 @@ var actorCompactAllocatedCmd = &cli.Command{
 	Flags: []cli.Flag{
 		&cli.Uint64Flag{
 			Name:  "mask-last-offset",
-			Usage: "Mask sector IDs from 0 to 'higest_allocated - offset'",
+			Usage: "Mask sector IDs from 0 to 'highest_allocated - offset'",
 		},
 		&cli.Uint64Flag{
 			Name:  "mask-upto-n",
diff --git a/cmd/lotus-miner/precommits-info.go b/cmd/lotus-miner/precommits-info.go
index 0ce7575377d..3f9e8c92742 100644
--- a/cmd/lotus-miner/precommits-info.go
+++ b/cmd/lotus-miner/precommits-info.go
@@ -7,7 +7,6 @@ import (
 	cbor "github.com/ipfs/go-ipld-cbor"
 	"github.com/urfave/cli/v2"
 
-	minertypes "github.com/filecoin-project/go-state-types/builtin/v9/miner"
 	"github.com/filecoin-project/specs-actors/v7/actors/util/adt"
 
 	"github.com/filecoin-project/lotus/blockstore"
@@ -39,8 +38,8 @@ var sectorPreCommitsCmd = &cli.Command{
 		if err != nil {
 			return err
 		}
-		preCommitSector := make([]minertypes.SectorPreCommitOnChainInfo, 0)
-		err = mst.ForEachPrecommittedSector(func(info minertypes.SectorPreCommitOnChainInfo) error {
+		preCommitSector := make([]miner.SectorPreCommitOnChainInfo, 0)
+		err = mst.ForEachPrecommittedSector(func(info miner.SectorPreCommitOnChainInfo) error {
 			preCommitSector = append(preCommitSector, info)
 			return err
 		})
diff --git a/cmd/lotus-miner/sectors.go b/cmd/lotus-miner/sectors.go
index 3993ecf7566..6fd0fd70957 100644
--- a/cmd/lotus-miner/sectors.go
+++ b/cmd/lotus-miner/sectors.go
@@ -24,14 +24,13 @@ import (
 	"github.com/filecoin-project/go-state-types/abi"
 	"github.com/filecoin-project/go-state-types/big"
 	"github.com/filecoin-project/go-state-types/builtin"
-	"github.com/filecoin-project/go-state-types/builtin/v9/miner"
 	"github.com/filecoin-project/go-state-types/network"
 
 	"github.com/filecoin-project/lotus/api"
 	"github.com/filecoin-project/lotus/blockstore"
 	"github.com/filecoin-project/lotus/chain/actors"
 	"github.com/filecoin-project/lotus/chain/actors/adt"
-	lminer "github.com/filecoin-project/lotus/chain/actors/builtin/miner"
+	"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
 	"github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
 	"github.com/filecoin-project/lotus/chain/actors/policy"
 	"github.com/filecoin-project/lotus/chain/types"
@@ -193,14 +192,14 @@ var sectorsStatusCmd = &cli.Command{
 			}
 
 			tbs := blockstore.NewTieredBstore(blockstore.NewAPIBlockstore(fullApi), blockstore.NewMemory())
-			mas, err := lminer.Load(adt.WrapStore(ctx, cbor.NewCborStore(tbs)), mact)
+			mas, err := miner.Load(adt.WrapStore(ctx, cbor.NewCborStore(tbs)), mact)
 			if err != nil {
 				return err
 			}
 
 			errFound := errors.New("found")
-			if err := mas.ForEachDeadline(func(dlIdx uint64, dl lminer.Deadline) error {
-				return dl.ForEachPartition(func(partIdx uint64, part lminer.Partition) error {
+			if err := mas.ForEachDeadline(func(dlIdx uint64, dl miner.Deadline) error {
+				return dl.ForEachPartition(func(partIdx uint64, part miner.Partition) error {
 					pas, err := part.AllSectors()
 					if err != nil {
 						return err
@@ -847,7 +846,12 @@ var sectorsCheckExpireCmd = &cli.Command{
 
 		for _, sector := range sectors {
 			MaxExpiration := sector.Activation + policy.GetSectorMaxLifetime(sector.SealProof, nv)
-			MaxExtendNow := currEpoch + policy.GetMaxSectorExpirationExtension()
+			maxExtension, err := policy.GetMaxSectorExpirationExtension(nv)
+			if err != nil {
+				return xerrors.Errorf("failed to get max extension: %w", err)
+			}
+
+			MaxExtendNow := currEpoch + maxExtension
 
 			if MaxExtendNow > MaxExpiration {
 				MaxExtendNow = MaxExpiration
@@ -1075,22 +1079,22 @@ var sectorsExtendCmd = &cli.Command{
 
 		tbs := blockstore.NewTieredBstore(blockstore.NewAPIBlockstore(fullApi), blockstore.NewMemory())
 		adtStore := adt.WrapStore(ctx, cbor.NewCborStore(tbs))
-		mas, err := lminer.Load(adtStore, mact)
+		mas, err := miner.Load(adtStore, mact)
 		if err != nil {
 			return err
 		}
 
-		activeSectorsLocation := make(map[abi.SectorNumber]*lminer.SectorLocation, len(activeSet))
+		activeSectorsLocation := make(map[abi.SectorNumber]*miner.SectorLocation, len(activeSet))
 
-		if err := mas.ForEachDeadline(func(dlIdx uint64, dl lminer.Deadline) error {
-			return dl.ForEachPartition(func(partIdx uint64, part lminer.Partition) error {
+		if err := mas.ForEachDeadline(func(dlIdx uint64, dl miner.Deadline) error {
+			return dl.ForEachPartition(func(partIdx uint64, part miner.Partition) error {
 				pas, err := part.ActiveSectors()
 				if err != nil {
 					return err
 				}
 
 				return pas.ForEach(func(i uint64) error {
-					activeSectorsLocation[abi.SectorNumber(i)] = &lminer.SectorLocation{
+					activeSectorsLocation[abi.SectorNumber(i)] = &miner.SectorLocation{
 						Deadline:  dlIdx,
 						Partition: partIdx,
 					}
@@ -1177,7 +1181,7 @@ var sectorsExtendCmd = &cli.Command{
 			return diff <= abi.ChainEpoch(cctx.Int64("tolerance"))
 		}
 
-		extensions := map[lminer.SectorLocation]map[abi.ChainEpoch][]abi.SectorNumber{}
+		extensions := map[miner.SectorLocation]map[abi.ChainEpoch][]abi.SectorNumber{}
 		for _, si := range sis {
 			extension := abi.ChainEpoch(cctx.Int64("extension"))
 			newExp := si.Expiration + extension
@@ -1186,7 +1190,12 @@ var sectorsExtendCmd = &cli.Command{
 				newExp = abi.ChainEpoch(cctx.Int64("new-expiration"))
 			}
 
-			maxExtendNow := currEpoch + policy.GetMaxSectorExpirationExtension()
+			maxExtension, err := policy.GetMaxSectorExpirationExtension(nv)
+			if err != nil {
+				return xerrors.Errorf("failed to get max extension: %w", err)
+			}
+
+			maxExtendNow := currEpoch + maxExtension
 			if newExp > maxExtendNow {
 				newExp = maxExtendNow
 			}
@@ -1741,7 +1750,7 @@ var sectorsCapacityCollateralCmd = &cli.Command{
 			return err
 		}
 
-		spt, err := lminer.PreferredSealProofTypeFromWindowPoStType(nv, mi.WindowPoStProofType)
+		spt, err := miner.PreferredSealProofTypeFromWindowPoStType(nv, mi.WindowPoStProofType, false)
 		if err != nil {
 			return err
 		}
@@ -1756,7 +1765,12 @@ var sectorsCapacityCollateralCmd = &cli.Command{
 				return err
 			}
 
-			pci.Expiration = policy.GetMaxSectorExpirationExtension() + h.Height()
+			maxExtension, err := policy.GetMaxSectorExpirationExtension(nv)
+			if err != nil {
+				return xerrors.Errorf("failed to get max extension: %w", err)
+			}
+
+			pci.Expiration = maxExtension + h.Height()
 		}
 
 		pc, err := nApi.StateMinerInitialPledgeCollateral(ctx, maddr, pci, types.EmptyTSK)
@@ -1910,7 +1924,7 @@ var sectorsExpiredCmd = &cli.Command{
 		}
 
 		tbs := blockstore.NewTieredBstore(blockstore.NewAPIBlockstore(fullApi), blockstore.NewMemory())
-		mas, err := lminer.Load(adt.WrapStore(ctx, cbor.NewCborStore(tbs)), mact)
+		mas, err := miner.Load(adt.WrapStore(ctx, cbor.NewCborStore(tbs)), mact)
 		if err != nil {
 			return err
 		}
@@ -1926,8 +1940,8 @@ var sectorsExpiredCmd = &cli.Command{
 			return xerrors.Errorf("intersecting bitfields: %w", err)
 		}
 
-		if err := mas.ForEachDeadline(func(dlIdx uint64, dl lminer.Deadline) error {
-			return dl.ForEachPartition(func(partIdx uint64, part lminer.Partition) error {
+		if err := mas.ForEachDeadline(func(dlIdx uint64, dl miner.Deadline) error {
+			return dl.ForEachPartition(func(partIdx uint64, part miner.Partition) error {
 				live, err := part.LiveSectors()
 				if err != nil {
 					return err
diff --git a/cmd/lotus-seed/main.go b/cmd/lotus-seed/main.go
index 863a508f228..d362804c95d 100644
--- a/cmd/lotus-seed/main.go
+++ b/cmd/lotus-seed/main.go
@@ -137,7 +137,9 @@ var preSealCmd = &cli.Command{
 			nv = network.Version(c.Uint64("network-version"))
 		}
 
-		spt, err := miner.SealProofTypeFromSectorSize(sectorSize, nv)
+		var synthetic = false // there's little reason to have this for a seed.
+
+		spt, err := miner.SealProofTypeFromSectorSize(sectorSize, nv, synthetic)
 		if err != nil {
 			return err
 		}
diff --git a/cmd/lotus-shed/invariants.go b/cmd/lotus-shed/invariants.go
index 51d746f79d0..e74a0dd24c2 100644
--- a/cmd/lotus-shed/invariants.go
+++ b/cmd/lotus-shed/invariants.go
@@ -16,6 +16,7 @@ import (
 	"github.com/filecoin-project/go-state-types/builtin"
 	v10 "github.com/filecoin-project/go-state-types/builtin/v10"
 	v11 "github.com/filecoin-project/go-state-types/builtin/v11"
+	v12 "github.com/filecoin-project/go-state-types/builtin/v12"
 	v8 "github.com/filecoin-project/go-state-types/builtin/v8"
 	v9 "github.com/filecoin-project/go-state-types/builtin/v9"
 
@@ -149,6 +150,13 @@ var invariantsCmd = &cli.Command{
 			if err != nil {
 				return xerrors.Errorf("checking state invariants: %w", err)
 			}
+		case actorstypes.Version12:
+			messages, err = v12.CheckStateInvariants(actorTree, abi.ChainEpoch(epoch), actorCodeCids)
+			if err != nil {
+				return xerrors.Errorf("checking state invariants: %w", err)
+			}
+		default:
+			return xerrors.Errorf("unsupported actor version: %v", av)
 		}
 
 		fmt.Println("completed, took ", time.Since(startTime))
diff --git a/cmd/lotus-shed/main.go b/cmd/lotus-shed/main.go
index 13ab6af0da6..12f52c68f57 100644
--- a/cmd/lotus-shed/main.go
+++ b/cmd/lotus-shed/main.go
@@ -5,6 +5,7 @@ import (
 	"fmt"
 	"os"
 	"os/signal"
+	"runtime/pprof"
 
 	logging "github.com/ipfs/go-log/v2"
 	"github.com/urfave/cli/v2"
@@ -114,10 +115,31 @@ func main() {
 				Name:  "log-level",
 				Value: "info",
 			},
+			&cli.StringFlag{
+				Name:  "pprof",
+				Usage: "specify name of file for writing cpu profile to",
+			},
 		},
 		Before: func(cctx *cli.Context) error {
+			if prof := cctx.String("pprof"); prof != "" {
+				profile, err := os.Create(prof)
+				if err != nil {
+					return err
+				}
+
+				if err := pprof.StartCPUProfile(profile); err != nil {
+					return err
+				}
+			}
+
 			return logging.SetLogLevel("lotus-shed", cctx.String("log-level"))
 		},
+		After: func(cctx *cli.Context) error {
+			if prof := cctx.String("pprof"); prof != "" {
+				pprof.StopCPUProfile()
+			}
+			return nil
+		},
 	}
 
 	// terminate early on ctrl+c
diff --git a/cmd/lotus-shed/migrations.go b/cmd/lotus-shed/migrations.go
index 82a1afddf4a..96e4747b7ef 100644
--- a/cmd/lotus-shed/migrations.go
+++ b/cmd/lotus-shed/migrations.go
@@ -21,6 +21,7 @@ import (
 	"github.com/filecoin-project/go-state-types/builtin"
 	v10 "github.com/filecoin-project/go-state-types/builtin/v10"
 	v11 "github.com/filecoin-project/go-state-types/builtin/v11"
+	v12 "github.com/filecoin-project/go-state-types/builtin/v12"
 	market8 "github.com/filecoin-project/go-state-types/builtin/v8/market"
 	adt8 "github.com/filecoin-project/go-state-types/builtin/v8/util/adt"
 	v9 "github.com/filecoin-project/go-state-types/builtin/v9"
@@ -243,6 +244,8 @@ func getMigrationFuncsForNetwork(nv network.Version) (UpgradeActorsFunc, PreUpgr
 		return filcns.UpgradeActorsV10, filcns.PreUpgradeActorsV10, checkNv18Invariants, nil
 	case network.Version19:
 		return filcns.UpgradeActorsV11, filcns.PreUpgradeActorsV11, checkNv19Invariants, nil
+	case network.Version21:
+		return filcns.UpgradeActorsV12, filcns.PreUpgradeActorsV12, checkNv21Invariants, nil
 	default:
 		return nil, nil, nil, xerrors.Errorf("migration not implemented for nv%d", nv)
 	}
@@ -252,6 +255,38 @@ type UpgradeActorsFunc = func(context.Context, *stmgr.StateManager, stmgr.Migrat
 type PreUpgradeActorsFunc = func(context.Context, *stmgr.StateManager, stmgr.MigrationCache, cid.Cid, abi.ChainEpoch, *types.TipSet) error
 type CheckInvariantsFunc = func(context.Context, cid.Cid, cid.Cid, blockstore.Blockstore, abi.ChainEpoch) error
 
+func checkNv21Invariants(ctx context.Context, oldStateRootCid cid.Cid, newStateRootCid cid.Cid, bs blockstore.Blockstore, epoch abi.ChainEpoch) error {
+
+	actorStore := store.ActorStore(ctx, bs)
+	startTime := time.Now()
+
+	// Load the new state root.
+	var newStateRoot types.StateRoot
+	if err := actorStore.Get(ctx, newStateRootCid, &newStateRoot); err != nil {
+		return xerrors.Errorf("failed to decode state root: %w", err)
+	}
+
+	actorCodeCids, err := actors.GetActorCodeIDs(actorstypes.Version12)
+	if err != nil {
+		return err
+	}
+	newActorTree, err := builtin.LoadTree(actorStore, newStateRoot.Actors)
+	if err != nil {
+		return err
+	}
+	messages, err := v12.CheckStateInvariants(newActorTree, epoch, actorCodeCids)
+	if err != nil {
+		return xerrors.Errorf("checking state invariants: %w", err)
+	}
+
+	for _, message := range messages.Messages() {
+		fmt.Println("got the following error: ", message)
+	}
+
+	fmt.Println("completed invariant checks, took ", time.Since(startTime))
+
+	return nil
+}
 func checkNv19Invariants(ctx context.Context, oldStateRootCid cid.Cid, newStateRootCid cid.Cid, bs blockstore.Blockstore, epoch abi.ChainEpoch) error {
 
 	actorStore := store.ActorStore(ctx, bs)
diff --git a/cmd/lotus-shed/shedgen/cbor_gen.go b/cmd/lotus-shed/shedgen/cbor_gen.go
index a04d52c8e14..f2a79fe7dce 100644
--- a/cmd/lotus-shed/shedgen/cbor_gen.go
+++ b/cmd/lotus-shed/shedgen/cbor_gen.go
@@ -38,7 +38,7 @@ func (t *CarbNode) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Sub"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Sub")); err != nil {
+	if _, err := cw.WriteString(string("Sub")); err != nil {
 		return err
 	}
 
@@ -50,9 +50,11 @@ func (t *CarbNode) MarshalCBOR(w io.Writer) error {
 		return err
 	}
 	for _, v := range t.Sub {
-		if err := cbg.WriteCid(w, v); err != nil {
-			return xerrors.Errorf("failed writing cid field t.Sub: %w", err)
+
+		if err := cbg.WriteCid(cw, v); err != nil {
+			return xerrors.Errorf("failed to write cid field v: %w", err)
 		}
+
 	}
 	return nil
 }
@@ -116,12 +118,25 @@ func (t *CarbNode) UnmarshalCBOR(r io.Reader) (err error) {
 			}
 
 			for i := 0; i < int(extra); i++ {
+				{
+					var maj byte
+					var extra uint64
+					var err error
+					_ = maj
+					_ = extra
+					_ = err
+
+					{
+
+						c, err := cbg.ReadCid(cr)
+						if err != nil {
+							return xerrors.Errorf("failed to read cid field t.Sub[i]: %w", err)
+						}
+
+						t.Sub[i] = c
 
-				c, err := cbg.ReadCid(cr)
-				if err != nil {
-					return xerrors.Errorf("reading cid field t.Sub failed: %w", err)
+					}
 				}
-				t.Sub[i] = c
 			}
 
 		default:
diff --git a/cmd/lotus-sim/simulation/stages/precommit_stage.go b/cmd/lotus-sim/simulation/stages/precommit_stage.go
index 8f82d898857..1a89413d72c 100644
--- a/cmd/lotus-sim/simulation/stages/precommit_stage.go
+++ b/cmd/lotus-sim/simulation/stages/precommit_stage.go
@@ -165,7 +165,7 @@ func (stage *PreCommitStage) packMiner(
 
 	// Generate pre-commits.
 	sealType, err := miner.PreferredSealProofTypeFromWindowPoStType(
-		nv, minerInfo.WindowPoStProofType,
+		nv, minerInfo.WindowPoStProofType, false,
 	)
 	if err != nil {
 		return 0, false, err
@@ -176,7 +176,12 @@ func (stage *PreCommitStage) packMiner(
 		return 0, false, err
 	}
 
-	expiration := epoch + policy.GetMaxSectorExpirationExtension()
+	maxExtension, err := policy.GetMaxSectorExpirationExtension(nv)
+	if err != nil {
+		return 0, false, xerrors.Errorf("failed to get max extension: %w", err)
+	}
+
+	expiration := epoch + maxExtension
 	infos := make([]minertypes.PreCommitSectorParams, len(sectorNos))
 	for i, sno := range sectorNos {
 		infos[i] = minertypes.PreCommitSectorParams{
diff --git a/cmd/tvx/extract_message.go b/cmd/tvx/extract_message.go
index 8ff8a2b794e..95711414bcc 100644
--- a/cmd/tvx/extract_message.go
+++ b/cmd/tvx/extract_message.go
@@ -15,7 +15,8 @@ import (
 	"github.com/filecoin-project/test-vectors/schema"
 
 	"github.com/filecoin-project/lotus/api"
-	"github.com/filecoin-project/lotus/api/v0api"
+	lapi "github.com/filecoin-project/lotus/api"
+	"github.com/filecoin-project/lotus/api/v1api"
 	"github.com/filecoin-project/lotus/chain/actors/builtin"
 	init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
 	"github.com/filecoin-project/lotus/chain/actors/builtin/reward"
@@ -207,7 +208,7 @@ func doExtractMessage(opts extractOpts) error {
 	// TODO sometimes this returns a nil receipt and no error ¯\_(ツ)_/¯
 	//  ex: https://filfox.info/en/message/bafy2bzacebpxw3yiaxzy2bako62akig46x3imji7fewszen6fryiz6nymu2b2
 	//  This code is lenient and skips receipt comparison in case of a nil receipt.
-	rec, err := FullAPI.StateGetReceipt(ctx, mcid, execTs.Key())
+	rec, err := FullAPI.StateSearchMsg(ctx, execTs.Key(), mcid, api.LookbackNoLimit, false)
 	if err != nil {
 		return fmt.Errorf("failed to find receipt on chain: %w", err)
 	}
@@ -217,9 +218,9 @@ func doExtractMessage(opts extractOpts) error {
 	var receipt *schema.Receipt
 	if rec != nil {
 		receipt = &schema.Receipt{
-			ExitCode:    int64(rec.ExitCode),
-			ReturnValue: rec.Return,
-			GasUsed:     rec.GasUsed,
+			ExitCode:    int64(rec.Receipt.ExitCode),
+			ReturnValue: rec.Receipt.Return,
+			GasUsed:     rec.Receipt.GasUsed,
 		}
 
 		reporter := new(conformance.LogReporter)
@@ -326,7 +327,7 @@ func doExtractMessage(opts extractOpts) error {
 
 // resolveFromChain queries the chain for the provided message, using the block CID to
 // speed up the query, if provided
-func resolveFromChain(ctx context.Context, api v0api.FullNode, mcid cid.Cid, block string) (msg *types.Message, execTs *types.TipSet, incTs *types.TipSet, err error) {
+func resolveFromChain(ctx context.Context, api lapi.FullNode, mcid cid.Cid, block string) (msg *types.Message, execTs *types.TipSet, incTs *types.TipSet, err error) {
 	// Extract the full message.
 	msg, err = api.ChainGetMessage(ctx, mcid)
 	if err != nil {
@@ -339,7 +340,7 @@ func resolveFromChain(ctx context.Context, api v0api.FullNode, mcid cid.Cid, blo
 		log.Printf("locating message in blockchain")
 
 		// Locate the message.
-		msgInfo, err := api.StateSearchMsg(ctx, mcid)
+		msgInfo, err := api.StateSearchMsg(ctx, types.EmptyTSK, mcid, lapi.LookbackNoLimit, false)
 		if err != nil {
 			return nil, nil, nil, fmt.Errorf("failed to locate message: %w", err)
 		}
@@ -384,7 +385,7 @@ func resolveFromChain(ctx context.Context, api v0api.FullNode, mcid cid.Cid, blo
 // as the previous tipset. In the context of vector generation, the target
 // tipset is the one where a message was executed, and the previous tipset is
 // the one where the message was included.
-func fetchThisAndPrevTipset(ctx context.Context, api v0api.FullNode, target types.TipSetKey) (targetTs *types.TipSet, prevTs *types.TipSet, err error) {
+func fetchThisAndPrevTipset(ctx context.Context, api v1api.FullNode, target types.TipSetKey) (targetTs *types.TipSet, prevTs *types.TipSet, err error) {
 	// get the tipset on which this message was "executed" on.
 	// https://github.com/filecoin-project/lotus/issues/2847
 	targetTs, err = api.ChainGetTipSet(ctx, target)
diff --git a/cmd/tvx/main.go b/cmd/tvx/main.go
index b1541e4e11d..5021dd64b25 100644
--- a/cmd/tvx/main.go
+++ b/cmd/tvx/main.go
@@ -10,13 +10,13 @@ import (
 
 	"github.com/filecoin-project/go-jsonrpc"
 
-	"github.com/filecoin-project/lotus/api/v0api"
+	"github.com/filecoin-project/lotus/api/v1api"
 	lcli "github.com/filecoin-project/lotus/cli"
 )
 
 // FullAPI is a JSON-RPC client targeting a full node. It's initialized in a
 // cli.BeforeFunc.
-var FullAPI v0api.FullNode
+var FullAPI v1api.FullNode
 
 // Closer is the closer for the JSON-RPC client, which must be called on
 // cli.AfterFunc.
@@ -102,7 +102,7 @@ func initialize(c *cli.Context) error {
 
 	// Make the API client.
 	var err error
-	if FullAPI, Closer, err = lcli.GetFullNodeAPI(c); err != nil {
+	if FullAPI, Closer, err = lcli.GetFullNodeAPIV1(c); err != nil {
 		err = fmt.Errorf("failed to locate Lotus node; err: %w", err)
 	}
 	return err
diff --git a/cmd/tvx/state.go b/cmd/tvx/state.go
index 120eddd6b14..9674bf17ed6 100644
--- a/cmd/tvx/state.go
+++ b/cmd/tvx/state.go
@@ -14,7 +14,8 @@ import (
 	"github.com/filecoin-project/go-address"
 	"github.com/filecoin-project/go-state-types/abi"
 
-	"github.com/filecoin-project/lotus/api/v0api"
+	"github.com/filecoin-project/lotus/api"
+	"github.com/filecoin-project/lotus/api/v1api"
 	init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
 	"github.com/filecoin-project/lotus/chain/state"
 	"github.com/filecoin-project/lotus/chain/types"
@@ -24,13 +25,13 @@ import (
 // StateSurgeon is an object used to fetch and manipulate state.
 type StateSurgeon struct {
 	ctx    context.Context
-	api    v0api.FullNode
+	api    v1api.FullNode
 	stores *Stores
 }
 
 // NewSurgeon returns a state surgeon, an object used to fetch and manipulate
 // state.
-func NewSurgeon(ctx context.Context, api v0api.FullNode, stores *Stores) *StateSurgeon {
+func NewSurgeon(ctx context.Context, api v1api.FullNode, stores *Stores) *StateSurgeon {
 	return &StateSurgeon{
 		ctx:    ctx,
 		api:    api,
@@ -86,9 +87,9 @@ func (sg *StateSurgeon) GetMaskedStateTree(previousRoot cid.Cid, retain []addres
 
 // GetAccessedActors identifies the actors that were accessed during the
 // execution of a message.
-func (sg *StateSurgeon) GetAccessedActors(ctx context.Context, a v0api.FullNode, mid cid.Cid) ([]address.Address, error) {
+func (sg *StateSurgeon) GetAccessedActors(ctx context.Context, a v1api.FullNode, mid cid.Cid) ([]address.Address, error) {
 	log.Printf("calculating accessed actors during execution of message: %s", mid)
-	msgInfo, err := a.StateSearchMsg(ctx, mid)
+	msgInfo, err := a.StateSearchMsg(ctx, types.EmptyTSK, mid, api.LookbackNoLimit, false)
 	if err != nil {
 		return nil, err
 	}
diff --git a/cmd/tvx/stores.go b/cmd/tvx/stores.go
index d4431a145a6..0ced4481761 100644
--- a/cmd/tvx/stores.go
+++ b/cmd/tvx/stores.go
@@ -18,7 +18,7 @@ import (
 	format "github.com/ipfs/go-ipld-format"
 	"golang.org/x/xerrors"
 
-	"github.com/filecoin-project/lotus/api/v0api"
+	"github.com/filecoin-project/lotus/api/v1api"
 	"github.com/filecoin-project/lotus/blockstore"
 	"github.com/filecoin-project/lotus/chain/actors/adt"
 )
@@ -39,7 +39,7 @@ type Stores struct {
 // NewProxyingStores is a set of Stores backed by a proxying Blockstore that
 // proxies Get requests for unknown CIDs to a Filecoin node, via the
 // ChainReadObj RPC.
-func NewProxyingStores(ctx context.Context, api v0api.FullNode) *Stores {
+func NewProxyingStores(ctx context.Context, api v1api.FullNode) *Stores {
 	ds := dssync.MutexWrap(ds.NewMapDatastore())
 	bs := &proxyingBlockstore{
 		ctx:        ctx,
@@ -84,7 +84,7 @@ type TracingBlockstore interface {
 // a Filecoin node via JSON-RPC.
 type proxyingBlockstore struct {
 	ctx context.Context
-	api v0api.FullNode
+	api v1api.FullNode
 
 	lk      sync.Mutex
 	tracing bool
diff --git a/conformance/chaos/cbor_gen.go b/conformance/chaos/cbor_gen.go
index 5da16e16ff5..d74ae0946a1 100644
--- a/conformance/chaos/cbor_gen.go
+++ b/conformance/chaos/cbor_gen.go
@@ -44,7 +44,7 @@ func (t *State) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Value))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string(t.Value)); err != nil {
+	if _, err := cw.WriteString(string(t.Value)); err != nil {
 		return err
 	}
 
@@ -117,13 +117,32 @@ func (t *State) UnmarshalCBOR(r io.Reader) (err error) {
 	}
 
 	for i := 0; i < int(extra); i++ {
+		{
+			var maj byte
+			var extra uint64
+			var err error
+			_ = maj
+			_ = extra
+			_ = err
+
+			{
+
+				b, err := cr.ReadByte()
+				if err != nil {
+					return err
+				}
+				if b != cbg.CborNull[0] {
+					if err := cr.UnreadByte(); err != nil {
+						return err
+					}
+					t.Unmarshallable[i] = new(UnmarshallableCBOR)
+					if err := t.Unmarshallable[i].UnmarshalCBOR(cr); err != nil {
+						return xerrors.Errorf("unmarshaling t.Unmarshallable[i] pointer: %w", err)
+					}
+				}
 
-		var v UnmarshallableCBOR
-		if err := v.UnmarshalCBOR(cr); err != nil {
-			return err
+			}
 		}
-
-		t.Unmarshallable[i] = &v
 	}
 
 	return nil
@@ -177,9 +196,11 @@ func (t *CallerValidationArgs) MarshalCBOR(w io.Writer) error {
 		return err
 	}
 	for _, v := range t.Types {
-		if err := cbg.WriteCid(w, v); err != nil {
-			return xerrors.Errorf("failed writing cid field t.Types: %w", err)
+
+		if err := cbg.WriteCid(cw, v); err != nil {
+			return xerrors.Errorf("failed to write cid field v: %w", err)
 		}
+
 	}
 	return nil
 }
@@ -252,13 +273,22 @@ func (t *CallerValidationArgs) UnmarshalCBOR(r io.Reader) (err error) {
 	}
 
 	for i := 0; i < int(extra); i++ {
+		{
+			var maj byte
+			var extra uint64
+			var err error
+			_ = maj
+			_ = extra
+			_ = err
 
-		var v address.Address
-		if err := v.UnmarshalCBOR(cr); err != nil {
-			return err
-		}
+			{
+
+				if err := t.Addrs[i].UnmarshalCBOR(cr); err != nil {
+					return xerrors.Errorf("unmarshaling t.Addrs[i]: %w", err)
+				}
 
-		t.Addrs[i] = v
+			}
+		}
 	}
 
 	// t.Types ([]cid.Cid) (slice)
@@ -281,12 +311,25 @@ func (t *CallerValidationArgs) UnmarshalCBOR(r io.Reader) (err error) {
 	}
 
 	for i := 0; i < int(extra); i++ {
+		{
+			var maj byte
+			var extra uint64
+			var err error
+			_ = maj
+			_ = extra
+			_ = err
 
-		c, err := cbg.ReadCid(cr)
-		if err != nil {
-			return xerrors.Errorf("reading cid field t.Types failed: %w", err)
+			{
+
+				c, err := cbg.ReadCid(cr)
+				if err != nil {
+					return xerrors.Errorf("failed to read cid field t.Types[i]: %w", err)
+				}
+
+				t.Types[i] = c
+
+			}
 		}
-		t.Types[i] = c
 	}
 
 	return nil
@@ -746,7 +789,7 @@ func (t *MutateStateArgs) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Value))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string(t.Value)); err != nil {
+	if _, err := cw.WriteString(string(t.Value)); err != nil {
 		return err
 	}
 
@@ -857,7 +900,7 @@ func (t *AbortWithArgs) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Message))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string(t.Message)); err != nil {
+	if _, err := cw.WriteString(string(t.Message)); err != nil {
 		return err
 	}
 
diff --git a/conformance/driver.go b/conformance/driver.go
index eb5973f72b3..3c62ca7b9ef 100644
--- a/conformance/driver.go
+++ b/conformance/driver.go
@@ -23,6 +23,7 @@ import (
 	"github.com/filecoin-project/lotus/chain/consensus"
 	"github.com/filecoin-project/lotus/chain/consensus/filcns"
 	"github.com/filecoin-project/lotus/chain/index"
+	"github.com/filecoin-project/lotus/chain/rand"
 	"github.com/filecoin-project/lotus/chain/state"
 	"github.com/filecoin-project/lotus/chain/stmgr"
 	"github.com/filecoin-project/lotus/chain/store"
@@ -89,9 +90,9 @@ type ExecuteTipsetParams struct {
 	ParentEpoch abi.ChainEpoch
 	Tipset      *schema.Tipset
 	ExecEpoch   abi.ChainEpoch
-	// Rand is an optional vm.Rand implementation to use. If nil, the driver
-	// will use a vm.Rand that returns a fixed value for all calls.
-	Rand vm.Rand
+	// Rand is an optional rand.Rand implementation to use. If nil, the driver
+	// will use a rand.Rand that returns a fixed value for all calls.
+	Rand rand.Rand
 	// BaseFee if not nil or zero, will override the basefee of the tipset.
 	BaseFee abi.TokenAmount
 }
@@ -200,9 +201,9 @@ type ExecuteMessageParams struct {
 	BaseFee        abi.TokenAmount
 	NetworkVersion network.Version
 
-	// Rand is an optional vm.Rand implementation to use. If nil, the driver
-	// will use a vm.Rand that returns a fixed value for all calls.
-	Rand vm.Rand
+	// Rand is an optional rand.Rand implementation to use. If nil, the driver
+	// will use a rand.Rand that returns a fixed value for all calls.
+	Rand rand.Rand
 
 	// Lookback is the LookbackStateGetter; returns the state tree at a given epoch.
 	Lookback vm.LookbackStateGetter
diff --git a/conformance/rand_fixed.go b/conformance/rand_fixed.go
index d356b53d049..f35f05cd4ff 100644
--- a/conformance/rand_fixed.go
+++ b/conformance/rand_fixed.go
@@ -4,25 +4,24 @@ import (
 	"context"
 
 	"github.com/filecoin-project/go-state-types/abi"
-	"github.com/filecoin-project/go-state-types/crypto"
 
-	"github.com/filecoin-project/lotus/chain/vm"
+	"github.com/filecoin-project/lotus/chain/rand"
 )
 
 type fixedRand struct{}
 
-var _ vm.Rand = (*fixedRand)(nil)
+var _ rand.Rand = (*fixedRand)(nil)
 
 // NewFixedRand creates a test vm.Rand that always returns fixed bytes value
 // of utf-8 string 'i_am_random_____i_am_random_____'.
-func NewFixedRand() vm.Rand {
+func NewFixedRand() rand.Rand {
 	return &fixedRand{}
 }
 
-func (r *fixedRand) GetChainRandomness(_ context.Context, _ crypto.DomainSeparationTag, _ abi.ChainEpoch, _ []byte) ([]byte, error) {
-	return []byte("i_am_random_____i_am_random_____"), nil // 32 bytes.
+func (r *fixedRand) GetChainRandomness(_ context.Context, _ abi.ChainEpoch) ([32]byte, error) {
+	return *(*[32]byte)([]byte("i_am_random_____i_am_random_____")), nil
 }
 
-func (r *fixedRand) GetBeaconRandomness(_ context.Context, _ crypto.DomainSeparationTag, _ abi.ChainEpoch, _ []byte) ([]byte, error) {
-	return []byte("i_am_random_____i_am_random_____"), nil // 32 bytes.
+func (r *fixedRand) GetBeaconRandomness(_ context.Context, _ abi.ChainEpoch) ([32]byte, error) {
+	return *(*[32]byte)([]byte("i_am_random_____i_am_random_____")), nil // 32 bytes.
 }
diff --git a/conformance/rand_record.go b/conformance/rand_record.go
index 277c984a770..4dc30b28ebf 100644
--- a/conformance/rand_record.go
+++ b/conformance/rand_record.go
@@ -6,17 +6,16 @@ import (
 	"sync"
 
 	"github.com/filecoin-project/go-state-types/abi"
-	"github.com/filecoin-project/go-state-types/crypto"
 	"github.com/filecoin-project/test-vectors/schema"
 
-	"github.com/filecoin-project/lotus/api/v0api"
+	"github.com/filecoin-project/lotus/api/v1api"
+	"github.com/filecoin-project/lotus/chain/rand"
 	"github.com/filecoin-project/lotus/chain/types"
-	"github.com/filecoin-project/lotus/chain/vm"
 )
 
 type RecordingRand struct {
 	reporter Reporter
-	api      v0api.FullNode
+	api      v1api.FullNode
 
 	// once guards the loading of the head tipset.
 	// can be removed when https://github.com/filecoin-project/lotus/issues/4223
@@ -27,12 +26,12 @@ type RecordingRand struct {
 	recorded schema.Randomness
 }
 
-var _ vm.Rand = (*RecordingRand)(nil)
+var _ rand.Rand = (*RecordingRand)(nil)
 
 // NewRecordingRand returns a vm.Rand implementation that proxies calls to a
 // full Lotus node via JSON-RPC, and records matching rules and responses so
 // they can later be embedded in test vectors.
-func NewRecordingRand(reporter Reporter, api v0api.FullNode) *RecordingRand {
+func NewRecordingRand(reporter Reporter, api v1api.FullNode) *RecordingRand {
 	return &RecordingRand{reporter: reporter, api: api}
 }
 
@@ -44,22 +43,20 @@ func (r *RecordingRand) loadHead() {
 	r.head = head.Key()
 }
 
-func (r *RecordingRand) GetChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
+func (r *RecordingRand) GetChainRandomness(ctx context.Context, round abi.ChainEpoch) ([32]byte, error) {
 	r.once.Do(r.loadHead)
-	// FullNode's v0 ChainGetRandomnessFromTickets handles whether we should be looking forward or back
-	ret, err := r.api.ChainGetRandomnessFromTickets(ctx, r.head, pers, round, entropy)
+	// FullNode's v1 ChainGetRandomnessFromTickets handles whether we should be looking forward or back
+	ret, err := r.api.StateGetRandomnessDigestFromTickets(ctx, round, r.head)
 	if err != nil {
-		return ret, err
+		return [32]byte{}, err
 	}
 
-	r.reporter.Logf("fetched and recorded chain randomness for: dst=%d, epoch=%d, entropy=%x, result=%x", pers, round, entropy, ret)
+	r.reporter.Logf("fetched and recorded chain randomness for: epoch=%d, result=%x", round, ret)
 
 	match := schema.RandomnessMatch{
 		On: schema.RandomnessRule{
-			Kind:                schema.RandomnessChain,
-			DomainSeparationTag: int64(pers),
-			Epoch:               int64(round),
-			Entropy:             entropy,
+			Kind:  schema.RandomnessChain,
+			Epoch: int64(round),
 		},
 		Return: []byte(ret),
 	}
@@ -67,24 +64,22 @@ func (r *RecordingRand) GetChainRandomness(ctx context.Context, pers crypto.Doma
 	r.recorded = append(r.recorded, match)
 	r.lk.Unlock()
 
-	return ret, err
+	return *(*[32]byte)(ret), err
 }
 
-func (r *RecordingRand) GetBeaconRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
+func (r *RecordingRand) GetBeaconRandomness(ctx context.Context, round abi.ChainEpoch) ([32]byte, error) {
 	r.once.Do(r.loadHead)
-	ret, err := r.api.StateGetRandomnessFromBeacon(ctx, pers, round, entropy, r.head)
+	ret, err := r.api.StateGetRandomnessDigestFromBeacon(ctx, round, r.head)
 	if err != nil {
-		return ret, err
+		return [32]byte{}, err
 	}
 
-	r.reporter.Logf("fetched and recorded beacon randomness for: dst=%d, epoch=%d, entropy=%x, result=%x", pers, round, entropy, ret)
+	r.reporter.Logf("fetched and recorded beacon randomness for: epoch=%d,  result=%x", round, ret)
 
 	match := schema.RandomnessMatch{
 		On: schema.RandomnessRule{
-			Kind:                schema.RandomnessBeacon,
-			DomainSeparationTag: int64(pers),
-			Epoch:               int64(round),
-			Entropy:             entropy,
+			Kind:  schema.RandomnessBeacon,
+			Epoch: int64(round),
 		},
 		Return: []byte(ret),
 	}
@@ -92,7 +87,7 @@ func (r *RecordingRand) GetBeaconRandomness(ctx context.Context, pers crypto.Dom
 	r.recorded = append(r.recorded, match)
 	r.lk.Unlock()
 
-	return ret, err
+	return *(*[32]byte)(ret), err
 }
 
 func (r *RecordingRand) Recorded() schema.Randomness {
diff --git a/conformance/rand_replay.go b/conformance/rand_replay.go
index ef19e41bb7b..6d78d813b8a 100644
--- a/conformance/rand_replay.go
+++ b/conformance/rand_replay.go
@@ -1,23 +1,21 @@
 package conformance
 
 import (
-	"bytes"
 	"context"
 
 	"github.com/filecoin-project/go-state-types/abi"
-	"github.com/filecoin-project/go-state-types/crypto"
 	"github.com/filecoin-project/test-vectors/schema"
 
-	"github.com/filecoin-project/lotus/chain/vm"
+	"github.com/filecoin-project/lotus/chain/rand"
 )
 
 type ReplayingRand struct {
 	reporter Reporter
 	recorded schema.Randomness
-	fallback vm.Rand
+	fallback rand.Rand
 }
 
-var _ vm.Rand = (*ReplayingRand)(nil)
+var _ rand.Rand = (*ReplayingRand)(nil)
 
 // NewReplayingRand replays recorded randomness when requested, falling back to
 // fixed randomness if the value cannot be found; hence this is a safe
@@ -30,50 +28,44 @@ func NewReplayingRand(reporter Reporter, recorded schema.Randomness) *ReplayingR
 	}
 }
 
-func (r *ReplayingRand) match(requested schema.RandomnessRule) ([]byte, bool) {
+func (r *ReplayingRand) match(requested schema.RandomnessRule) ([32]byte, bool) {
 	for _, other := range r.recorded {
 		if other.On.Kind == requested.Kind &&
-			other.On.Epoch == requested.Epoch &&
-			other.On.DomainSeparationTag == requested.DomainSeparationTag &&
-			bytes.Equal(other.On.Entropy, requested.Entropy) {
-			return other.Return, true
+			other.On.Epoch == requested.Epoch {
+			return *(*[32]byte)(other.Return), true
 		}
 	}
-	return nil, false
+	return [32]byte{}, false
 }
 
-func (r *ReplayingRand) GetChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
+func (r *ReplayingRand) GetChainRandomness(ctx context.Context, round abi.ChainEpoch) ([32]byte, error) {
 	rule := schema.RandomnessRule{
-		Kind:                schema.RandomnessChain,
-		DomainSeparationTag: int64(pers),
-		Epoch:               int64(round),
-		Entropy:             entropy,
+		Kind:  schema.RandomnessChain,
+		Epoch: int64(round),
 	}
 
 	if ret, ok := r.match(rule); ok {
-		r.reporter.Logf("returning saved chain randomness: dst=%d, epoch=%d, entropy=%x, result=%x", pers, round, entropy, ret)
+		r.reporter.Logf("returning saved chain randomness: epoch=%d, result=%x", round, ret)
 		return ret, nil
 	}
 
-	r.reporter.Logf("returning fallback chain randomness: dst=%d, epoch=%d, entropy=%x", pers, round, entropy)
+	r.reporter.Logf("returning fallback chain randomness: epoch=%d", round)
 
-	return r.fallback.GetChainRandomness(ctx, pers, round, entropy)
+	return r.fallback.GetChainRandomness(ctx, round)
 }
 
-func (r *ReplayingRand) GetBeaconRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
+func (r *ReplayingRand) GetBeaconRandomness(ctx context.Context, round abi.ChainEpoch) ([32]byte, error) {
 	rule := schema.RandomnessRule{
-		Kind:                schema.RandomnessBeacon,
-		DomainSeparationTag: int64(pers),
-		Epoch:               int64(round),
-		Entropy:             entropy,
+		Kind:  schema.RandomnessBeacon,
+		Epoch: int64(round),
 	}
 
 	if ret, ok := r.match(rule); ok {
-		r.reporter.Logf("returning saved beacon randomness: dst=%d, epoch=%d, entropy=%x, result=%x", pers, round, entropy, ret)
+		r.reporter.Logf("returning saved beacon randomness:  epoch=%d, result=%x", round, ret)
 		return ret, nil
 	}
 
-	r.reporter.Logf("returning fallback beacon randomness: dst=%d, epoch=%d, entropy=%x", pers, round, entropy)
+	r.reporter.Logf("returning fallback beacon randomness: epoch=%d, ", round)
 
-	return r.fallback.GetBeaconRandomness(ctx, pers, round, entropy)
+	return r.fallback.GetBeaconRandomness(ctx, round)
 }
diff --git a/documentation/en/api-v0-methods-miner.md b/documentation/en/api-v0-methods-miner.md
index 997778069b5..57070caedf5 100644
--- a/documentation/en/api-v0-methods-miner.md
+++ b/documentation/en/api-v0-methods-miner.md
@@ -475,7 +475,7 @@ Inputs:
   ],
   "Bw==",
   10101,
-  20
+  21
 ]
 ```
 
@@ -4213,6 +4213,51 @@ Response:
               "BaseMinMemory": 8388608,
               "MaxConcurrent": 0
             },
+            "10": {
+              "MinMemory": 2048,
+              "MaxMemory": 2048,
+              "GPUUtilization": 1,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 2048,
+              "MaxConcurrent": 0
+            },
+            "11": {
+              "MinMemory": 8388608,
+              "MaxMemory": 8388608,
+              "GPUUtilization": 1,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 8388608,
+              "MaxConcurrent": 0
+            },
+            "12": {
+              "MinMemory": 1073741824,
+              "MaxMemory": 1610612736,
+              "GPUUtilization": 1,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 10737418240,
+              "MaxConcurrent": 0
+            },
+            "13": {
+              "MinMemory": 32212254720,
+              "MaxMemory": 103079215104,
+              "GPUUtilization": 1,
+              "MaxParallelism": -1,
+              "MaxParallelismGPU": 6,
+              "BaseMinMemory": 34359738368,
+              "MaxConcurrent": 0
+            },
+            "14": {
+              "MinMemory": 64424509440,
+              "MaxMemory": 128849018880,
+              "GPUUtilization": 1,
+              "MaxParallelism": -1,
+              "MaxParallelismGPU": 6,
+              "BaseMinMemory": 68719476736,
+              "MaxConcurrent": 0
+            },
             "2": {
               "MinMemory": 1073741824,
               "MaxMemory": 1610612736,
@@ -4305,6 +4350,51 @@ Response:
               "BaseMinMemory": 8388608,
               "MaxConcurrent": 0
             },
+            "10": {
+              "MinMemory": 2048,
+              "MaxMemory": 2048,
+              "GPUUtilization": 1,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 2048,
+              "MaxConcurrent": 0
+            },
+            "11": {
+              "MinMemory": 8388608,
+              "MaxMemory": 8388608,
+              "GPUUtilization": 1,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 8388608,
+              "MaxConcurrent": 0
+            },
+            "12": {
+              "MinMemory": 2048,
+              "MaxMemory": 2048,
+              "GPUUtilization": 1,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 10737418240,
+              "MaxConcurrent": 0
+            },
+            "13": {
+              "MinMemory": 1073741824,
+              "MaxMemory": 1073741824,
+              "GPUUtilization": 1,
+              "MaxParallelism": -1,
+              "MaxParallelismGPU": 6,
+              "BaseMinMemory": 34359738368,
+              "MaxConcurrent": 0
+            },
+            "14": {
+              "MinMemory": 1073741824,
+              "MaxMemory": 1073741824,
+              "GPUUtilization": 1,
+              "MaxParallelism": -1,
+              "MaxParallelismGPU": 6,
+              "BaseMinMemory": 68719476736,
+              "MaxConcurrent": 0
+            },
             "2": {
               "MinMemory": 2048,
               "MaxMemory": 2048,
@@ -4397,6 +4487,51 @@ Response:
               "BaseMinMemory": 8388608,
               "MaxConcurrent": 0
             },
+            "10": {
+              "MinMemory": 2048,
+              "MaxMemory": 2048,
+              "GPUUtilization": 0,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 2048,
+              "MaxConcurrent": 0
+            },
+            "11": {
+              "MinMemory": 8388608,
+              "MaxMemory": 8388608,
+              "GPUUtilization": 0,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 8388608,
+              "MaxConcurrent": 0
+            },
+            "12": {
+              "MinMemory": 1073741824,
+              "MaxMemory": 1073741824,
+              "GPUUtilization": 0,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 1073741824,
+              "MaxConcurrent": 0
+            },
+            "13": {
+              "MinMemory": 4294967296,
+              "MaxMemory": 4294967296,
+              "GPUUtilization": 0,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 1073741824,
+              "MaxConcurrent": 0
+            },
+            "14": {
+              "MinMemory": 8589934592,
+              "MaxMemory": 8589934592,
+              "GPUUtilization": 0,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 1073741824,
+              "MaxConcurrent": 0
+            },
             "2": {
               "MinMemory": 1073741824,
               "MaxMemory": 1073741824,
@@ -4489,6 +4624,51 @@ Response:
               "BaseMinMemory": 8388608,
               "MaxConcurrent": 0
             },
+            "10": {
+              "MinMemory": 2048,
+              "MaxMemory": 2048,
+              "GPUUtilization": 0,
+              "MaxParallelism": 0,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 2048,
+              "MaxConcurrent": 0
+            },
+            "11": {
+              "MinMemory": 8388608,
+              "MaxMemory": 8388608,
+              "GPUUtilization": 0,
+              "MaxParallelism": 0,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 8388608,
+              "MaxConcurrent": 0
+            },
+            "12": {
+              "MinMemory": 1073741824,
+              "MaxMemory": 1073741824,
+              "GPUUtilization": 0,
+              "MaxParallelism": 0,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 1073741824,
+              "MaxConcurrent": 0
+            },
+            "13": {
+              "MinMemory": 1073741824,
+              "MaxMemory": 1073741824,
+              "GPUUtilization": 0,
+              "MaxParallelism": 0,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 1073741824,
+              "MaxConcurrent": 0
+            },
+            "14": {
+              "MinMemory": 1073741824,
+              "MaxMemory": 1073741824,
+              "GPUUtilization": 0,
+              "MaxParallelism": 0,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 1073741824,
+              "MaxConcurrent": 0
+            },
             "2": {
               "MinMemory": 1073741824,
               "MaxMemory": 1073741824,
@@ -4581,6 +4761,51 @@ Response:
               "BaseMinMemory": 8388608,
               "MaxConcurrent": 0
             },
+            "10": {
+              "MinMemory": 2048,
+              "MaxMemory": 2048,
+              "GPUUtilization": 1,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 2048,
+              "MaxConcurrent": 0
+            },
+            "11": {
+              "MinMemory": 8388608,
+              "MaxMemory": 8388608,
+              "GPUUtilization": 1,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 8388608,
+              "MaxConcurrent": 0
+            },
+            "12": {
+              "MinMemory": 1073741824,
+              "MaxMemory": 1610612736,
+              "GPUUtilization": 1,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 10737418240,
+              "MaxConcurrent": 0
+            },
+            "13": {
+              "MinMemory": 32212254720,
+              "MaxMemory": 161061273600,
+              "GPUUtilization": 1,
+              "MaxParallelism": -1,
+              "MaxParallelismGPU": 6,
+              "BaseMinMemory": 34359738368,
+              "MaxConcurrent": 0
+            },
+            "14": {
+              "MinMemory": 64424509440,
+              "MaxMemory": 204010946560,
+              "GPUUtilization": 1,
+              "MaxParallelism": -1,
+              "MaxParallelismGPU": 6,
+              "BaseMinMemory": 68719476736,
+              "MaxConcurrent": 0
+            },
             "2": {
               "MinMemory": 1073741824,
               "MaxMemory": 1610612736,
@@ -4673,6 +4898,51 @@ Response:
               "BaseMinMemory": 1073741824,
               "MaxConcurrent": 0
             },
+            "10": {
+              "MinMemory": 4294967296,
+              "MaxMemory": 4294967296,
+              "GPUUtilization": 0,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 1073741824,
+              "MaxConcurrent": 0
+            },
+            "11": {
+              "MinMemory": 4294967296,
+              "MaxMemory": 4294967296,
+              "GPUUtilization": 0,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 1073741824,
+              "MaxConcurrent": 0
+            },
+            "12": {
+              "MinMemory": 4294967296,
+              "MaxMemory": 4294967296,
+              "GPUUtilization": 0,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 1073741824,
+              "MaxConcurrent": 0
+            },
+            "13": {
+              "MinMemory": 4294967296,
+              "MaxMemory": 4294967296,
+              "GPUUtilization": 0,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 1073741824,
+              "MaxConcurrent": 0
+            },
+            "14": {
+              "MinMemory": 4294967296,
+              "MaxMemory": 4294967296,
+              "GPUUtilization": 0,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 1073741824,
+              "MaxConcurrent": 0
+            },
             "2": {
               "MinMemory": 4294967296,
               "MaxMemory": 4294967296,
@@ -4765,7 +5035,7 @@ Response:
               "BaseMinMemory": 0,
               "MaxConcurrent": 0
             },
-            "2": {
+            "10": {
               "MinMemory": 1048576,
               "MaxMemory": 1048576,
               "GPUUtilization": 0,
@@ -4774,7 +5044,7 @@ Response:
               "BaseMinMemory": 0,
               "MaxConcurrent": 0
             },
-            "3": {
+            "11": {
               "MinMemory": 1048576,
               "MaxMemory": 1048576,
               "GPUUtilization": 0,
@@ -4783,7 +5053,7 @@ Response:
               "BaseMinMemory": 0,
               "MaxConcurrent": 0
             },
-            "4": {
+            "12": {
               "MinMemory": 1048576,
               "MaxMemory": 1048576,
               "GPUUtilization": 0,
@@ -4792,7 +5062,7 @@ Response:
               "BaseMinMemory": 0,
               "MaxConcurrent": 0
             },
-            "5": {
+            "13": {
               "MinMemory": 1048576,
               "MaxMemory": 1048576,
               "GPUUtilization": 0,
@@ -4801,7 +5071,7 @@ Response:
               "BaseMinMemory": 0,
               "MaxConcurrent": 0
             },
-            "6": {
+            "14": {
               "MinMemory": 1048576,
               "MaxMemory": 1048576,
               "GPUUtilization": 0,
@@ -4810,7 +5080,7 @@ Response:
               "BaseMinMemory": 0,
               "MaxConcurrent": 0
             },
-            "7": {
+            "2": {
               "MinMemory": 1048576,
               "MaxMemory": 1048576,
               "GPUUtilization": 0,
@@ -4819,7 +5089,7 @@ Response:
               "BaseMinMemory": 0,
               "MaxConcurrent": 0
             },
-            "8": {
+            "3": {
               "MinMemory": 1048576,
               "MaxMemory": 1048576,
               "GPUUtilization": 0,
@@ -4828,7 +5098,7 @@ Response:
               "BaseMinMemory": 0,
               "MaxConcurrent": 0
             },
-            "9": {
+            "4": {
               "MinMemory": 1048576,
               "MaxMemory": 1048576,
               "GPUUtilization": 0,
@@ -4836,11 +5106,56 @@ Response:
               "MaxParallelismGPU": 0,
               "BaseMinMemory": 0,
               "MaxConcurrent": 0
-            }
-          },
-          "seal/v0/precommit/1": {
-            "0": {
-              "MinMemory": 2048,
+            },
+            "5": {
+              "MinMemory": 1048576,
+              "MaxMemory": 1048576,
+              "GPUUtilization": 0,
+              "MaxParallelism": 0,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 0,
+              "MaxConcurrent": 0
+            },
+            "6": {
+              "MinMemory": 1048576,
+              "MaxMemory": 1048576,
+              "GPUUtilization": 0,
+              "MaxParallelism": 0,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 0,
+              "MaxConcurrent": 0
+            },
+            "7": {
+              "MinMemory": 1048576,
+              "MaxMemory": 1048576,
+              "GPUUtilization": 0,
+              "MaxParallelism": 0,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 0,
+              "MaxConcurrent": 0
+            },
+            "8": {
+              "MinMemory": 1048576,
+              "MaxMemory": 1048576,
+              "GPUUtilization": 0,
+              "MaxParallelism": 0,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 0,
+              "MaxConcurrent": 0
+            },
+            "9": {
+              "MinMemory": 1048576,
+              "MaxMemory": 1048576,
+              "GPUUtilization": 0,
+              "MaxParallelism": 0,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 0,
+              "MaxConcurrent": 0
+            }
+          },
+          "seal/v0/precommit/1": {
+            "0": {
+              "MinMemory": 2048,
               "MaxMemory": 2048,
               "GPUUtilization": 0,
               "MaxParallelism": 1,
@@ -4857,6 +5172,51 @@ Response:
               "BaseMinMemory": 8388608,
               "MaxConcurrent": 0
             },
+            "10": {
+              "MinMemory": 2048,
+              "MaxMemory": 2048,
+              "GPUUtilization": 0,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 2048,
+              "MaxConcurrent": 0
+            },
+            "11": {
+              "MinMemory": 8388608,
+              "MaxMemory": 8388608,
+              "GPUUtilization": 0,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 8388608,
+              "MaxConcurrent": 0
+            },
+            "12": {
+              "MinMemory": 805306368,
+              "MaxMemory": 1073741824,
+              "GPUUtilization": 0,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 1048576,
+              "MaxConcurrent": 0
+            },
+            "13": {
+              "MinMemory": 60129542144,
+              "MaxMemory": 68719476736,
+              "GPUUtilization": 0,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 10485760,
+              "MaxConcurrent": 0
+            },
+            "14": {
+              "MinMemory": 120259084288,
+              "MaxMemory": 137438953472,
+              "GPUUtilization": 0,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 10485760,
+              "MaxConcurrent": 0
+            },
             "2": {
               "MinMemory": 805306368,
               "MaxMemory": 1073741824,
@@ -4949,6 +5309,51 @@ Response:
               "BaseMinMemory": 8388608,
               "MaxConcurrent": 0
             },
+            "10": {
+              "MinMemory": 2048,
+              "MaxMemory": 2048,
+              "GPUUtilization": 0,
+              "MaxParallelism": -1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 2048,
+              "MaxConcurrent": 0
+            },
+            "11": {
+              "MinMemory": 8388608,
+              "MaxMemory": 8388608,
+              "GPUUtilization": 0,
+              "MaxParallelism": -1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 8388608,
+              "MaxConcurrent": 0
+            },
+            "12": {
+              "MinMemory": 1073741824,
+              "MaxMemory": 1610612736,
+              "GPUUtilization": 0,
+              "MaxParallelism": -1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 1073741824,
+              "MaxConcurrent": 0
+            },
+            "13": {
+              "MinMemory": 16106127360,
+              "MaxMemory": 16106127360,
+              "GPUUtilization": 1,
+              "MaxParallelism": -1,
+              "MaxParallelismGPU": 6,
+              "BaseMinMemory": 1073741824,
+              "MaxConcurrent": 0
+            },
+            "14": {
+              "MinMemory": 32212254720,
+              "MaxMemory": 32212254720,
+              "GPUUtilization": 1,
+              "MaxParallelism": -1,
+              "MaxParallelismGPU": 6,
+              "BaseMinMemory": 1073741824,
+              "MaxConcurrent": 0
+            },
             "2": {
               "MinMemory": 1073741824,
               "MaxMemory": 1610612736,
@@ -5041,6 +5446,51 @@ Response:
               "BaseMinMemory": 8388608,
               "MaxConcurrent": 0
             },
+            "10": {
+              "MinMemory": 2048,
+              "MaxMemory": 2048,
+              "GPUUtilization": 0,
+              "MaxParallelism": 0,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 2048,
+              "MaxConcurrent": 0
+            },
+            "11": {
+              "MinMemory": 8388608,
+              "MaxMemory": 8388608,
+              "GPUUtilization": 0,
+              "MaxParallelism": 0,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 8388608,
+              "MaxConcurrent": 0
+            },
+            "12": {
+              "MinMemory": 1073741824,
+              "MaxMemory": 1073741824,
+              "GPUUtilization": 0,
+              "MaxParallelism": 0,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 1073741824,
+              "MaxConcurrent": 0
+            },
+            "13": {
+              "MinMemory": 1073741824,
+              "MaxMemory": 1073741824,
+              "GPUUtilization": 0,
+              "MaxParallelism": 0,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 1073741824,
+              "MaxConcurrent": 0
+            },
+            "14": {
+              "MinMemory": 1073741824,
+              "MaxMemory": 1073741824,
+              "GPUUtilization": 0,
+              "MaxParallelism": 0,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 1073741824,
+              "MaxConcurrent": 0
+            },
             "2": {
               "MinMemory": 1073741824,
               "MaxMemory": 1073741824,
@@ -5133,6 +5583,51 @@ Response:
               "BaseMinMemory": 8388608,
               "MaxConcurrent": 0
             },
+            "10": {
+              "MinMemory": 2048,
+              "MaxMemory": 2048,
+              "GPUUtilization": 1,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 2048,
+              "MaxConcurrent": 0
+            },
+            "11": {
+              "MinMemory": 8388608,
+              "MaxMemory": 8388608,
+              "GPUUtilization": 1,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 8388608,
+              "MaxConcurrent": 0
+            },
+            "12": {
+              "MinMemory": 1073741824,
+              "MaxMemory": 1610612736,
+              "GPUUtilization": 1,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 10737418240,
+              "MaxConcurrent": 0
+            },
+            "13": {
+              "MinMemory": 32212254720,
+              "MaxMemory": 161061273600,
+              "GPUUtilization": 1,
+              "MaxParallelism": -1,
+              "MaxParallelismGPU": 6,
+              "BaseMinMemory": 34359738368,
+              "MaxConcurrent": 0
+            },
+            "14": {
+              "MinMemory": 64424509440,
+              "MaxMemory": 204010946560,
+              "GPUUtilization": 1,
+              "MaxParallelism": -1,
+              "MaxParallelismGPU": 6,
+              "BaseMinMemory": 68719476736,
+              "MaxConcurrent": 0
+            },
             "2": {
               "MinMemory": 1073741824,
               "MaxMemory": 1610612736,
@@ -5225,6 +5720,51 @@ Response:
               "BaseMinMemory": 8388608,
               "MaxConcurrent": 0
             },
+            "10": {
+              "MinMemory": 2048,
+              "MaxMemory": 2048,
+              "GPUUtilization": 1,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 2048,
+              "MaxConcurrent": 0
+            },
+            "11": {
+              "MinMemory": 8388608,
+              "MaxMemory": 8388608,
+              "GPUUtilization": 1,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 8388608,
+              "MaxConcurrent": 0
+            },
+            "12": {
+              "MinMemory": 1073741824,
+              "MaxMemory": 1073741824,
+              "GPUUtilization": 1,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 1073741824,
+              "MaxConcurrent": 0
+            },
+            "13": {
+              "MinMemory": 4294967296,
+              "MaxMemory": 4294967296,
+              "GPUUtilization": 1,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 6,
+              "BaseMinMemory": 1073741824,
+              "MaxConcurrent": 0
+            },
+            "14": {
+              "MinMemory": 8589934592,
+              "MaxMemory": 8589934592,
+              "GPUUtilization": 1,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 6,
+              "BaseMinMemory": 1073741824,
+              "MaxConcurrent": 0
+            },
             "2": {
               "MinMemory": 1073741824,
               "MaxMemory": 1073741824,
@@ -5317,6 +5857,51 @@ Response:
               "BaseMinMemory": 8388608,
               "MaxConcurrent": 0
             },
+            "10": {
+              "MinMemory": 2048,
+              "MaxMemory": 2048,
+              "GPUUtilization": 1,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 2048,
+              "MaxConcurrent": 0
+            },
+            "11": {
+              "MinMemory": 8388608,
+              "MaxMemory": 8388608,
+              "GPUUtilization": 1,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 8388608,
+              "MaxConcurrent": 0
+            },
+            "12": {
+              "MinMemory": 1073741824,
+              "MaxMemory": 1073741824,
+              "GPUUtilization": 1,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 1073741824,
+              "MaxConcurrent": 0
+            },
+            "13": {
+              "MinMemory": 4294967296,
+              "MaxMemory": 4294967296,
+              "GPUUtilization": 1,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 6,
+              "BaseMinMemory": 1073741824,
+              "MaxConcurrent": 0
+            },
+            "14": {
+              "MinMemory": 8589934592,
+              "MaxMemory": 8589934592,
+              "GPUUtilization": 1,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 6,
+              "BaseMinMemory": 1073741824,
+              "MaxConcurrent": 0
+            },
             "2": {
               "MinMemory": 1073741824,
               "MaxMemory": 1073741824,
@@ -5409,6 +5994,51 @@ Response:
               "BaseMinMemory": 8388608,
               "MaxConcurrent": 0
             },
+            "10": {
+              "MinMemory": 2048,
+              "MaxMemory": 2048,
+              "GPUUtilization": 0,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 2048,
+              "MaxConcurrent": 0
+            },
+            "11": {
+              "MinMemory": 8388608,
+              "MaxMemory": 8388608,
+              "GPUUtilization": 0,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 8388608,
+              "MaxConcurrent": 0
+            },
+            "12": {
+              "MinMemory": 805306368,
+              "MaxMemory": 1073741824,
+              "GPUUtilization": 0,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 1048576,
+              "MaxConcurrent": 0
+            },
+            "13": {
+              "MinMemory": 60129542144,
+              "MaxMemory": 68719476736,
+              "GPUUtilization": 0,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 10485760,
+              "MaxConcurrent": 0
+            },
+            "14": {
+              "MinMemory": 120259084288,
+              "MaxMemory": 137438953472,
+              "GPUUtilization": 0,
+              "MaxParallelism": 1,
+              "MaxParallelismGPU": 0,
+              "BaseMinMemory": 10485760,
+              "MaxConcurrent": 0
+            },
             "2": {
               "MinMemory": 805306368,
               "MaxMemory": 1073741824,
diff --git a/documentation/en/api-v0-methods-worker.md b/documentation/en/api-v0-methods-worker.md
index d7d0f092e06..1c2100c9c9e 100644
--- a/documentation/en/api-v0-methods-worker.md
+++ b/documentation/en/api-v0-methods-worker.md
@@ -138,6 +138,51 @@ Response:
           "BaseMinMemory": 8388608,
           "MaxConcurrent": 0
         },
+        "10": {
+          "MinMemory": 2048,
+          "MaxMemory": 2048,
+          "GPUUtilization": 1,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 2048,
+          "MaxConcurrent": 0
+        },
+        "11": {
+          "MinMemory": 8388608,
+          "MaxMemory": 8388608,
+          "GPUUtilization": 1,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 8388608,
+          "MaxConcurrent": 0
+        },
+        "12": {
+          "MinMemory": 1073741824,
+          "MaxMemory": 1610612736,
+          "GPUUtilization": 1,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 10737418240,
+          "MaxConcurrent": 0
+        },
+        "13": {
+          "MinMemory": 32212254720,
+          "MaxMemory": 103079215104,
+          "GPUUtilization": 1,
+          "MaxParallelism": -1,
+          "MaxParallelismGPU": 6,
+          "BaseMinMemory": 34359738368,
+          "MaxConcurrent": 0
+        },
+        "14": {
+          "MinMemory": 64424509440,
+          "MaxMemory": 128849018880,
+          "GPUUtilization": 1,
+          "MaxParallelism": -1,
+          "MaxParallelismGPU": 6,
+          "BaseMinMemory": 68719476736,
+          "MaxConcurrent": 0
+        },
         "2": {
           "MinMemory": 1073741824,
           "MaxMemory": 1610612736,
@@ -230,6 +275,51 @@ Response:
           "BaseMinMemory": 8388608,
           "MaxConcurrent": 0
         },
+        "10": {
+          "MinMemory": 2048,
+          "MaxMemory": 2048,
+          "GPUUtilization": 1,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 2048,
+          "MaxConcurrent": 0
+        },
+        "11": {
+          "MinMemory": 8388608,
+          "MaxMemory": 8388608,
+          "GPUUtilization": 1,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 8388608,
+          "MaxConcurrent": 0
+        },
+        "12": {
+          "MinMemory": 2048,
+          "MaxMemory": 2048,
+          "GPUUtilization": 1,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 10737418240,
+          "MaxConcurrent": 0
+        },
+        "13": {
+          "MinMemory": 1073741824,
+          "MaxMemory": 1073741824,
+          "GPUUtilization": 1,
+          "MaxParallelism": -1,
+          "MaxParallelismGPU": 6,
+          "BaseMinMemory": 34359738368,
+          "MaxConcurrent": 0
+        },
+        "14": {
+          "MinMemory": 1073741824,
+          "MaxMemory": 1073741824,
+          "GPUUtilization": 1,
+          "MaxParallelism": -1,
+          "MaxParallelismGPU": 6,
+          "BaseMinMemory": 68719476736,
+          "MaxConcurrent": 0
+        },
         "2": {
           "MinMemory": 2048,
           "MaxMemory": 2048,
@@ -322,6 +412,51 @@ Response:
           "BaseMinMemory": 8388608,
           "MaxConcurrent": 0
         },
+        "10": {
+          "MinMemory": 2048,
+          "MaxMemory": 2048,
+          "GPUUtilization": 0,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 2048,
+          "MaxConcurrent": 0
+        },
+        "11": {
+          "MinMemory": 8388608,
+          "MaxMemory": 8388608,
+          "GPUUtilization": 0,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 8388608,
+          "MaxConcurrent": 0
+        },
+        "12": {
+          "MinMemory": 1073741824,
+          "MaxMemory": 1073741824,
+          "GPUUtilization": 0,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 1073741824,
+          "MaxConcurrent": 0
+        },
+        "13": {
+          "MinMemory": 4294967296,
+          "MaxMemory": 4294967296,
+          "GPUUtilization": 0,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 1073741824,
+          "MaxConcurrent": 0
+        },
+        "14": {
+          "MinMemory": 8589934592,
+          "MaxMemory": 8589934592,
+          "GPUUtilization": 0,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 1073741824,
+          "MaxConcurrent": 0
+        },
         "2": {
           "MinMemory": 1073741824,
           "MaxMemory": 1073741824,
@@ -414,6 +549,51 @@ Response:
           "BaseMinMemory": 8388608,
           "MaxConcurrent": 0
         },
+        "10": {
+          "MinMemory": 2048,
+          "MaxMemory": 2048,
+          "GPUUtilization": 0,
+          "MaxParallelism": 0,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 2048,
+          "MaxConcurrent": 0
+        },
+        "11": {
+          "MinMemory": 8388608,
+          "MaxMemory": 8388608,
+          "GPUUtilization": 0,
+          "MaxParallelism": 0,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 8388608,
+          "MaxConcurrent": 0
+        },
+        "12": {
+          "MinMemory": 1073741824,
+          "MaxMemory": 1073741824,
+          "GPUUtilization": 0,
+          "MaxParallelism": 0,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 1073741824,
+          "MaxConcurrent": 0
+        },
+        "13": {
+          "MinMemory": 1073741824,
+          "MaxMemory": 1073741824,
+          "GPUUtilization": 0,
+          "MaxParallelism": 0,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 1073741824,
+          "MaxConcurrent": 0
+        },
+        "14": {
+          "MinMemory": 1073741824,
+          "MaxMemory": 1073741824,
+          "GPUUtilization": 0,
+          "MaxParallelism": 0,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 1073741824,
+          "MaxConcurrent": 0
+        },
         "2": {
           "MinMemory": 1073741824,
           "MaxMemory": 1073741824,
@@ -506,6 +686,51 @@ Response:
           "BaseMinMemory": 8388608,
           "MaxConcurrent": 0
         },
+        "10": {
+          "MinMemory": 2048,
+          "MaxMemory": 2048,
+          "GPUUtilization": 1,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 2048,
+          "MaxConcurrent": 0
+        },
+        "11": {
+          "MinMemory": 8388608,
+          "MaxMemory": 8388608,
+          "GPUUtilization": 1,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 8388608,
+          "MaxConcurrent": 0
+        },
+        "12": {
+          "MinMemory": 1073741824,
+          "MaxMemory": 1610612736,
+          "GPUUtilization": 1,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 10737418240,
+          "MaxConcurrent": 0
+        },
+        "13": {
+          "MinMemory": 32212254720,
+          "MaxMemory": 161061273600,
+          "GPUUtilization": 1,
+          "MaxParallelism": -1,
+          "MaxParallelismGPU": 6,
+          "BaseMinMemory": 34359738368,
+          "MaxConcurrent": 0
+        },
+        "14": {
+          "MinMemory": 64424509440,
+          "MaxMemory": 204010946560,
+          "GPUUtilization": 1,
+          "MaxParallelism": -1,
+          "MaxParallelismGPU": 6,
+          "BaseMinMemory": 68719476736,
+          "MaxConcurrent": 0
+        },
         "2": {
           "MinMemory": 1073741824,
           "MaxMemory": 1610612736,
@@ -598,6 +823,51 @@ Response:
           "BaseMinMemory": 1073741824,
           "MaxConcurrent": 0
         },
+        "10": {
+          "MinMemory": 4294967296,
+          "MaxMemory": 4294967296,
+          "GPUUtilization": 0,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 1073741824,
+          "MaxConcurrent": 0
+        },
+        "11": {
+          "MinMemory": 4294967296,
+          "MaxMemory": 4294967296,
+          "GPUUtilization": 0,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 1073741824,
+          "MaxConcurrent": 0
+        },
+        "12": {
+          "MinMemory": 4294967296,
+          "MaxMemory": 4294967296,
+          "GPUUtilization": 0,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 1073741824,
+          "MaxConcurrent": 0
+        },
+        "13": {
+          "MinMemory": 4294967296,
+          "MaxMemory": 4294967296,
+          "GPUUtilization": 0,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 1073741824,
+          "MaxConcurrent": 0
+        },
+        "14": {
+          "MinMemory": 4294967296,
+          "MaxMemory": 4294967296,
+          "GPUUtilization": 0,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 1073741824,
+          "MaxConcurrent": 0
+        },
         "2": {
           "MinMemory": 4294967296,
           "MaxMemory": 4294967296,
@@ -690,7 +960,7 @@ Response:
           "BaseMinMemory": 0,
           "MaxConcurrent": 0
         },
-        "2": {
+        "10": {
           "MinMemory": 1048576,
           "MaxMemory": 1048576,
           "GPUUtilization": 0,
@@ -699,7 +969,7 @@ Response:
           "BaseMinMemory": 0,
           "MaxConcurrent": 0
         },
-        "3": {
+        "11": {
           "MinMemory": 1048576,
           "MaxMemory": 1048576,
           "GPUUtilization": 0,
@@ -708,7 +978,7 @@ Response:
           "BaseMinMemory": 0,
           "MaxConcurrent": 0
         },
-        "4": {
+        "12": {
           "MinMemory": 1048576,
           "MaxMemory": 1048576,
           "GPUUtilization": 0,
@@ -717,7 +987,7 @@ Response:
           "BaseMinMemory": 0,
           "MaxConcurrent": 0
         },
-        "5": {
+        "13": {
           "MinMemory": 1048576,
           "MaxMemory": 1048576,
           "GPUUtilization": 0,
@@ -726,7 +996,7 @@ Response:
           "BaseMinMemory": 0,
           "MaxConcurrent": 0
         },
-        "6": {
+        "14": {
           "MinMemory": 1048576,
           "MaxMemory": 1048576,
           "GPUUtilization": 0,
@@ -735,7 +1005,7 @@ Response:
           "BaseMinMemory": 0,
           "MaxConcurrent": 0
         },
-        "7": {
+        "2": {
           "MinMemory": 1048576,
           "MaxMemory": 1048576,
           "GPUUtilization": 0,
@@ -744,7 +1014,7 @@ Response:
           "BaseMinMemory": 0,
           "MaxConcurrent": 0
         },
-        "8": {
+        "3": {
           "MinMemory": 1048576,
           "MaxMemory": 1048576,
           "GPUUtilization": 0,
@@ -753,7 +1023,7 @@ Response:
           "BaseMinMemory": 0,
           "MaxConcurrent": 0
         },
-        "9": {
+        "4": {
           "MinMemory": 1048576,
           "MaxMemory": 1048576,
           "GPUUtilization": 0,
@@ -761,11 +1031,56 @@ Response:
           "MaxParallelismGPU": 0,
           "BaseMinMemory": 0,
           "MaxConcurrent": 0
-        }
-      },
-      "seal/v0/precommit/1": {
-        "0": {
-          "MinMemory": 2048,
+        },
+        "5": {
+          "MinMemory": 1048576,
+          "MaxMemory": 1048576,
+          "GPUUtilization": 0,
+          "MaxParallelism": 0,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 0,
+          "MaxConcurrent": 0
+        },
+        "6": {
+          "MinMemory": 1048576,
+          "MaxMemory": 1048576,
+          "GPUUtilization": 0,
+          "MaxParallelism": 0,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 0,
+          "MaxConcurrent": 0
+        },
+        "7": {
+          "MinMemory": 1048576,
+          "MaxMemory": 1048576,
+          "GPUUtilization": 0,
+          "MaxParallelism": 0,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 0,
+          "MaxConcurrent": 0
+        },
+        "8": {
+          "MinMemory": 1048576,
+          "MaxMemory": 1048576,
+          "GPUUtilization": 0,
+          "MaxParallelism": 0,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 0,
+          "MaxConcurrent": 0
+        },
+        "9": {
+          "MinMemory": 1048576,
+          "MaxMemory": 1048576,
+          "GPUUtilization": 0,
+          "MaxParallelism": 0,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 0,
+          "MaxConcurrent": 0
+        }
+      },
+      "seal/v0/precommit/1": {
+        "0": {
+          "MinMemory": 2048,
           "MaxMemory": 2048,
           "GPUUtilization": 0,
           "MaxParallelism": 1,
@@ -782,6 +1097,51 @@ Response:
           "BaseMinMemory": 8388608,
           "MaxConcurrent": 0
         },
+        "10": {
+          "MinMemory": 2048,
+          "MaxMemory": 2048,
+          "GPUUtilization": 0,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 2048,
+          "MaxConcurrent": 0
+        },
+        "11": {
+          "MinMemory": 8388608,
+          "MaxMemory": 8388608,
+          "GPUUtilization": 0,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 8388608,
+          "MaxConcurrent": 0
+        },
+        "12": {
+          "MinMemory": 805306368,
+          "MaxMemory": 1073741824,
+          "GPUUtilization": 0,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 1048576,
+          "MaxConcurrent": 0
+        },
+        "13": {
+          "MinMemory": 60129542144,
+          "MaxMemory": 68719476736,
+          "GPUUtilization": 0,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 10485760,
+          "MaxConcurrent": 0
+        },
+        "14": {
+          "MinMemory": 120259084288,
+          "MaxMemory": 137438953472,
+          "GPUUtilization": 0,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 10485760,
+          "MaxConcurrent": 0
+        },
         "2": {
           "MinMemory": 805306368,
           "MaxMemory": 1073741824,
@@ -874,6 +1234,51 @@ Response:
           "BaseMinMemory": 8388608,
           "MaxConcurrent": 0
         },
+        "10": {
+          "MinMemory": 2048,
+          "MaxMemory": 2048,
+          "GPUUtilization": 0,
+          "MaxParallelism": -1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 2048,
+          "MaxConcurrent": 0
+        },
+        "11": {
+          "MinMemory": 8388608,
+          "MaxMemory": 8388608,
+          "GPUUtilization": 0,
+          "MaxParallelism": -1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 8388608,
+          "MaxConcurrent": 0
+        },
+        "12": {
+          "MinMemory": 1073741824,
+          "MaxMemory": 1610612736,
+          "GPUUtilization": 0,
+          "MaxParallelism": -1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 1073741824,
+          "MaxConcurrent": 0
+        },
+        "13": {
+          "MinMemory": 16106127360,
+          "MaxMemory": 16106127360,
+          "GPUUtilization": 1,
+          "MaxParallelism": -1,
+          "MaxParallelismGPU": 6,
+          "BaseMinMemory": 1073741824,
+          "MaxConcurrent": 0
+        },
+        "14": {
+          "MinMemory": 32212254720,
+          "MaxMemory": 32212254720,
+          "GPUUtilization": 1,
+          "MaxParallelism": -1,
+          "MaxParallelismGPU": 6,
+          "BaseMinMemory": 1073741824,
+          "MaxConcurrent": 0
+        },
         "2": {
           "MinMemory": 1073741824,
           "MaxMemory": 1610612736,
@@ -966,6 +1371,51 @@ Response:
           "BaseMinMemory": 8388608,
           "MaxConcurrent": 0
         },
+        "10": {
+          "MinMemory": 2048,
+          "MaxMemory": 2048,
+          "GPUUtilization": 0,
+          "MaxParallelism": 0,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 2048,
+          "MaxConcurrent": 0
+        },
+        "11": {
+          "MinMemory": 8388608,
+          "MaxMemory": 8388608,
+          "GPUUtilization": 0,
+          "MaxParallelism": 0,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 8388608,
+          "MaxConcurrent": 0
+        },
+        "12": {
+          "MinMemory": 1073741824,
+          "MaxMemory": 1073741824,
+          "GPUUtilization": 0,
+          "MaxParallelism": 0,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 1073741824,
+          "MaxConcurrent": 0
+        },
+        "13": {
+          "MinMemory": 1073741824,
+          "MaxMemory": 1073741824,
+          "GPUUtilization": 0,
+          "MaxParallelism": 0,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 1073741824,
+          "MaxConcurrent": 0
+        },
+        "14": {
+          "MinMemory": 1073741824,
+          "MaxMemory": 1073741824,
+          "GPUUtilization": 0,
+          "MaxParallelism": 0,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 1073741824,
+          "MaxConcurrent": 0
+        },
         "2": {
           "MinMemory": 1073741824,
           "MaxMemory": 1073741824,
@@ -1058,6 +1508,51 @@ Response:
           "BaseMinMemory": 8388608,
           "MaxConcurrent": 0
         },
+        "10": {
+          "MinMemory": 2048,
+          "MaxMemory": 2048,
+          "GPUUtilization": 1,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 2048,
+          "MaxConcurrent": 0
+        },
+        "11": {
+          "MinMemory": 8388608,
+          "MaxMemory": 8388608,
+          "GPUUtilization": 1,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 8388608,
+          "MaxConcurrent": 0
+        },
+        "12": {
+          "MinMemory": 1073741824,
+          "MaxMemory": 1610612736,
+          "GPUUtilization": 1,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 10737418240,
+          "MaxConcurrent": 0
+        },
+        "13": {
+          "MinMemory": 32212254720,
+          "MaxMemory": 161061273600,
+          "GPUUtilization": 1,
+          "MaxParallelism": -1,
+          "MaxParallelismGPU": 6,
+          "BaseMinMemory": 34359738368,
+          "MaxConcurrent": 0
+        },
+        "14": {
+          "MinMemory": 64424509440,
+          "MaxMemory": 204010946560,
+          "GPUUtilization": 1,
+          "MaxParallelism": -1,
+          "MaxParallelismGPU": 6,
+          "BaseMinMemory": 68719476736,
+          "MaxConcurrent": 0
+        },
         "2": {
           "MinMemory": 1073741824,
           "MaxMemory": 1610612736,
@@ -1150,6 +1645,51 @@ Response:
           "BaseMinMemory": 8388608,
           "MaxConcurrent": 0
         },
+        "10": {
+          "MinMemory": 2048,
+          "MaxMemory": 2048,
+          "GPUUtilization": 1,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 2048,
+          "MaxConcurrent": 0
+        },
+        "11": {
+          "MinMemory": 8388608,
+          "MaxMemory": 8388608,
+          "GPUUtilization": 1,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 8388608,
+          "MaxConcurrent": 0
+        },
+        "12": {
+          "MinMemory": 1073741824,
+          "MaxMemory": 1073741824,
+          "GPUUtilization": 1,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 1073741824,
+          "MaxConcurrent": 0
+        },
+        "13": {
+          "MinMemory": 4294967296,
+          "MaxMemory": 4294967296,
+          "GPUUtilization": 1,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 6,
+          "BaseMinMemory": 1073741824,
+          "MaxConcurrent": 0
+        },
+        "14": {
+          "MinMemory": 8589934592,
+          "MaxMemory": 8589934592,
+          "GPUUtilization": 1,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 6,
+          "BaseMinMemory": 1073741824,
+          "MaxConcurrent": 0
+        },
         "2": {
           "MinMemory": 1073741824,
           "MaxMemory": 1073741824,
@@ -1242,6 +1782,51 @@ Response:
           "BaseMinMemory": 8388608,
           "MaxConcurrent": 0
         },
+        "10": {
+          "MinMemory": 2048,
+          "MaxMemory": 2048,
+          "GPUUtilization": 1,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 2048,
+          "MaxConcurrent": 0
+        },
+        "11": {
+          "MinMemory": 8388608,
+          "MaxMemory": 8388608,
+          "GPUUtilization": 1,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 8388608,
+          "MaxConcurrent": 0
+        },
+        "12": {
+          "MinMemory": 1073741824,
+          "MaxMemory": 1073741824,
+          "GPUUtilization": 1,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 1073741824,
+          "MaxConcurrent": 0
+        },
+        "13": {
+          "MinMemory": 4294967296,
+          "MaxMemory": 4294967296,
+          "GPUUtilization": 1,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 6,
+          "BaseMinMemory": 1073741824,
+          "MaxConcurrent": 0
+        },
+        "14": {
+          "MinMemory": 8589934592,
+          "MaxMemory": 8589934592,
+          "GPUUtilization": 1,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 6,
+          "BaseMinMemory": 1073741824,
+          "MaxConcurrent": 0
+        },
         "2": {
           "MinMemory": 1073741824,
           "MaxMemory": 1073741824,
@@ -1334,6 +1919,51 @@ Response:
           "BaseMinMemory": 8388608,
           "MaxConcurrent": 0
         },
+        "10": {
+          "MinMemory": 2048,
+          "MaxMemory": 2048,
+          "GPUUtilization": 0,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 2048,
+          "MaxConcurrent": 0
+        },
+        "11": {
+          "MinMemory": 8388608,
+          "MaxMemory": 8388608,
+          "GPUUtilization": 0,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 8388608,
+          "MaxConcurrent": 0
+        },
+        "12": {
+          "MinMemory": 805306368,
+          "MaxMemory": 1073741824,
+          "GPUUtilization": 0,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 1048576,
+          "MaxConcurrent": 0
+        },
+        "13": {
+          "MinMemory": 60129542144,
+          "MaxMemory": 68719476736,
+          "GPUUtilization": 0,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 10485760,
+          "MaxConcurrent": 0
+        },
+        "14": {
+          "MinMemory": 120259084288,
+          "MaxMemory": 137438953472,
+          "GPUUtilization": 0,
+          "MaxParallelism": 1,
+          "MaxParallelismGPU": 0,
+          "BaseMinMemory": 10485760,
+          "MaxConcurrent": 0
+        },
         "2": {
           "MinMemory": 805306368,
           "MaxMemory": 1073741824,
diff --git a/documentation/en/api-v0-methods.md b/documentation/en/api-v0-methods.md
index 2acc969d307..f6e460a548e 100644
--- a/documentation/en/api-v0-methods.md
+++ b/documentation/en/api-v0-methods.md
@@ -4729,7 +4729,7 @@ Perms: read
 Inputs:
 ```json
 [
-  20
+  21
 ]
 ```
 
@@ -4744,7 +4744,7 @@ Perms: read
 Inputs:
 ```json
 [
-  20
+  21
 ]
 ```
 
@@ -4873,7 +4873,12 @@ Response:
       "Value": "0",
       "Method": 1,
       "Params": "Ynl0ZSBhcnJheQ==",
-      "ParamsCodec": 42
+      "ParamsCodec": 42,
+      "GasLimit": 42,
+      "ReadOnly": true,
+      "CodeCid": {
+        "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
+      }
     },
     "MsgRct": {
       "ExitCode": 0,
@@ -4897,7 +4902,12 @@ Response:
           "Value": "0",
           "Method": 1,
           "Params": "Ynl0ZSBhcnJheQ==",
-          "ParamsCodec": 42
+          "ParamsCodec": 42,
+          "GasLimit": 42,
+          "ReadOnly": true,
+          "CodeCid": {
+            "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
+          }
         },
         "MsgRct": {
           "ExitCode": 0,
@@ -5103,7 +5113,12 @@ Response:
           "Value": "0",
           "Method": 1,
           "Params": "Ynl0ZSBhcnJheQ==",
-          "ParamsCodec": 42
+          "ParamsCodec": 42,
+          "GasLimit": 42,
+          "ReadOnly": true,
+          "CodeCid": {
+            "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
+          }
         },
         "MsgRct": {
           "ExitCode": 0,
@@ -5127,7 +5142,12 @@ Response:
               "Value": "0",
               "Method": 1,
               "Params": "Ynl0ZSBhcnJheQ==",
-              "ParamsCodec": 42
+              "ParamsCodec": 42,
+              "GasLimit": 42,
+              "ReadOnly": true,
+              "CodeCid": {
+                "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
+              }
             },
             "MsgRct": {
               "ExitCode": 0,
@@ -5445,7 +5465,8 @@ Response:
     "UpgradeSharkHeight": 10101,
     "UpgradeHyggeHeight": 10101,
     "UpgradeLightningHeight": 10101,
-    "UpgradeThunderHeight": 10101
+    "UpgradeThunderHeight": 10101,
+    "UpgradeWatermelonHeight": 10101
   }
 }
 ```
@@ -6370,7 +6391,7 @@ Inputs:
 ]
 ```
 
-Response: `20`
+Response: `21`
 
 ### StateReadState
 StateReadState returns the indicated actor's state.
@@ -6491,7 +6512,12 @@ Response:
       "Value": "0",
       "Method": 1,
       "Params": "Ynl0ZSBhcnJheQ==",
-      "ParamsCodec": 42
+      "ParamsCodec": 42,
+      "GasLimit": 42,
+      "ReadOnly": true,
+      "CodeCid": {
+        "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
+      }
     },
     "MsgRct": {
       "ExitCode": 0,
@@ -6515,7 +6541,12 @@ Response:
           "Value": "0",
           "Method": 1,
           "Params": "Ynl0ZSBhcnJheQ==",
-          "ParamsCodec": 42
+          "ParamsCodec": 42,
+          "GasLimit": 42,
+          "ReadOnly": true,
+          "CodeCid": {
+            "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
+          }
         },
         "MsgRct": {
           "ExitCode": 0,
diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md
index e3c97eecf4d..31e4075b67b 100644
--- a/documentation/en/api-v1-unstable-methods.md
+++ b/documentation/en/api-v1-unstable-methods.md
@@ -235,6 +235,8 @@
   * [StateGetClaim](#StateGetClaim)
   * [StateGetClaims](#StateGetClaims)
   * [StateGetNetworkParams](#StateGetNetworkParams)
+  * [StateGetRandomnessDigestFromBeacon](#StateGetRandomnessDigestFromBeacon)
+  * [StateGetRandomnessDigestFromTickets](#StateGetRandomnessDigestFromTickets)
   * [StateGetRandomnessFromBeacon](#StateGetRandomnessFromBeacon)
   * [StateGetRandomnessFromTickets](#StateGetRandomnessFromTickets)
   * [StateListActors](#StateListActors)
@@ -6166,7 +6168,7 @@ Perms: read
 Inputs:
 ```json
 [
-  20
+  21
 ]
 ```
 
@@ -6181,7 +6183,7 @@ Perms: read
 Inputs:
 ```json
 [
-  20
+  21
 ]
 ```
 
@@ -6310,7 +6312,12 @@ Response:
       "Value": "0",
       "Method": 1,
       "Params": "Ynl0ZSBhcnJheQ==",
-      "ParamsCodec": 42
+      "ParamsCodec": 42,
+      "GasLimit": 42,
+      "ReadOnly": true,
+      "CodeCid": {
+        "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
+      }
     },
     "MsgRct": {
       "ExitCode": 0,
@@ -6334,7 +6341,12 @@ Response:
           "Value": "0",
           "Method": 1,
           "Params": "Ynl0ZSBhcnJheQ==",
-          "ParamsCodec": 42
+          "ParamsCodec": 42,
+          "GasLimit": 42,
+          "ReadOnly": true,
+          "CodeCid": {
+            "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
+          }
         },
         "MsgRct": {
           "ExitCode": 0,
@@ -6540,7 +6552,12 @@ Response:
           "Value": "0",
           "Method": 1,
           "Params": "Ynl0ZSBhcnJheQ==",
-          "ParamsCodec": 42
+          "ParamsCodec": 42,
+          "GasLimit": 42,
+          "ReadOnly": true,
+          "CodeCid": {
+            "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
+          }
         },
         "MsgRct": {
           "ExitCode": 0,
@@ -6564,7 +6581,12 @@ Response:
               "Value": "0",
               "Method": 1,
               "Params": "Ynl0ZSBhcnJheQ==",
-              "ParamsCodec": 42
+              "ParamsCodec": 42,
+              "GasLimit": 42,
+              "ReadOnly": true,
+              "CodeCid": {
+                "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
+              }
             },
             "MsgRct": {
               "ExitCode": 0,
@@ -6957,11 +6979,58 @@ Response:
     "UpgradeSharkHeight": 10101,
     "UpgradeHyggeHeight": 10101,
     "UpgradeLightningHeight": 10101,
-    "UpgradeThunderHeight": 10101
+    "UpgradeThunderHeight": 10101,
+    "UpgradeWatermelonHeight": 10101
   }
 }
 ```
 
+### StateGetRandomnessDigestFromBeacon
+StateGetRandomnessDigestFromBeacon is used to sample the beacon for randomness.
+
+
+Perms: read
+
+Inputs:
+```json
+[
+  10101,
+  [
+    {
+      "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
+    },
+    {
+      "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve"
+    }
+  ]
+]
+```
+
+Response: `"Bw=="`
+
+### StateGetRandomnessDigestFromTickets
+StateGetRandomnessDigestFromTickets. is used to sample the chain for randomness.
+
+
+Perms: read
+
+Inputs:
+```json
+[
+  10101,
+  [
+    {
+      "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
+    },
+    {
+      "/": "bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve"
+    }
+  ]
+]
+```
+
+Response: `"Bw=="`
+
 ### StateGetRandomnessFromBeacon
 StateGetRandomnessFromBeacon is used to sample the beacon for randomness.
 
@@ -7890,7 +7959,7 @@ Inputs:
 ]
 ```
 
-Response: `20`
+Response: `21`
 
 ### StateReadState
 StateReadState returns the indicated actor's state.
@@ -8011,7 +8080,12 @@ Response:
       "Value": "0",
       "Method": 1,
       "Params": "Ynl0ZSBhcnJheQ==",
-      "ParamsCodec": 42
+      "ParamsCodec": 42,
+      "GasLimit": 42,
+      "ReadOnly": true,
+      "CodeCid": {
+        "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
+      }
     },
     "MsgRct": {
       "ExitCode": 0,
@@ -8035,7 +8109,12 @@ Response:
           "Value": "0",
           "Method": 1,
           "Params": "Ynl0ZSBhcnJheQ==",
-          "ParamsCodec": 42
+          "ParamsCodec": 42,
+          "GasLimit": 42,
+          "ReadOnly": true,
+          "CodeCid": {
+            "/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
+          }
         },
         "MsgRct": {
           "ExitCode": 0,
diff --git a/documentation/en/cli-lotus-miner.md b/documentation/en/cli-lotus-miner.md
index 1c3ea0c8458..3cc8c77ecdf 100644
--- a/documentation/en/cli-lotus-miner.md
+++ b/documentation/en/cli-lotus-miner.md
@@ -7,7 +7,7 @@ USAGE:
    lotus-miner [global options] command [command options] [arguments...]
 
 VERSION:
-   1.23.3
+   1.24.0
 
 COMMANDS:
    init     Initialize a lotus miner repo
@@ -366,7 +366,7 @@ USAGE:
    lotus-miner actor compact-allocated [command options] [arguments...]
 
 OPTIONS:
-   --mask-last-offset value  Mask sector IDs from 0 to 'higest_allocated - offset' (default: 0)
+   --mask-last-offset value  Mask sector IDs from 0 to 'highest_allocated - offset' (default: 0)
    --mask-upto-n value       Mask sector IDs from 0 to 'n' (default: 0)
    --really-do-it            Actually send transaction performing the action (default: false)
    --help, -h                show help
diff --git a/documentation/en/cli-lotus-worker.md b/documentation/en/cli-lotus-worker.md
index cb5ba125a86..fd950847271 100644
--- a/documentation/en/cli-lotus-worker.md
+++ b/documentation/en/cli-lotus-worker.md
@@ -7,7 +7,7 @@ USAGE:
    lotus-worker [global options] command [command options] [arguments...]
 
 VERSION:
-   1.23.3
+   1.24.0
 
 COMMANDS:
    run        Start lotus worker
diff --git a/documentation/en/cli-lotus.md b/documentation/en/cli-lotus.md
index 0a28cb42024..c6b0d6f4478 100644
--- a/documentation/en/cli-lotus.md
+++ b/documentation/en/cli-lotus.md
@@ -7,7 +7,7 @@ USAGE:
    lotus [global options] command [command options] [arguments...]
 
 VERSION:
-   1.23.3
+   1.24.0
 
 COMMANDS:
    daemon   Start a lotus daemon process
diff --git a/documentation/en/default-lotus-miner-config.toml b/documentation/en/default-lotus-miner-config.toml
index c0a204bf1db..ff1ede45366 100644
--- a/documentation/en/default-lotus-miner-config.toml
+++ b/documentation/en/default-lotus-miner-config.toml
@@ -427,13 +427,10 @@
   # env var: LOTUS_PROVING_DISABLEWDPOSTPRECHECKS
   #DisableWDPoStPreChecks = false
 
-  # Maximum number of partitions to prove in a single SubmitWindowPoSt messace. 0 = network limit (10 in nv16)
+  # Maximum number of partitions to prove in a single SubmitWindowPoSt messace. 0 = network limit (3 in nv21)
   # 
   # A single partition may contain up to 2349 32GiB sectors, or 2300 64GiB sectors.
-  # 
-  # The maximum number of sectors which can be proven in a single PoSt message is 25000 in network version 16, which
-  # means that a single message can prove at most 10 partitions
-  # 
+  # //
   # Note that setting this value lower may result in less efficient gas use - more messages will be sent,
   # to prove each deadline, resulting in more total gas use (but each message will have lower gas limit)
   # 
@@ -523,7 +520,7 @@
 
   # CommittedCapacitySectorLifetime is the duration a Committed Capacity (CC) sector will
   # live before it must be extended or converted into sector containing deals before it is
-  # terminated. Value must be between 180-540 days inclusive
+  # terminated. Value must be between 180-1278 days (1278 in nv21, 540 before nv21).
   #
   # type: Duration
   # env var: LOTUS_SEALING_COMMITTEDCAPACITYSECTORLIFETIME
@@ -581,12 +578,6 @@
   # env var: LOTUS_SEALING_DISABLECOLLATERALFALLBACK
   #DisableCollateralFallback = false
 
-  # enable / disable precommit batching (takes effect after nv13)
-  #
-  # type: bool
-  # env var: LOTUS_SEALING_BATCHPRECOMMITS
-  #BatchPreCommits = true
-
   # maximum precommit batch size - batches will be sent immediately above this size
   #
   # type: int
@@ -636,7 +627,8 @@
   #CommitBatchSlack = "1h0m0s"
 
   # network BaseFee below which to stop doing precommit batching, instead
-  # sending precommit messages to the chain individually
+  # sending precommit messages to the chain individually. When the basefee is
+  # below this threshold, precommit messages will get sent out immediately.
   #
   # type: types.FIL
   # env var: LOTUS_SEALING_BATCHPRECOMMITABOVEBASEFEE
@@ -671,6 +663,12 @@
   # env var: LOTUS_SEALING_TERMINATEBATCHWAIT
   #TerminateBatchWait = "5m0s"
 
+  # UseSyntheticPoRep, when set to true, will reduce the amount of cache data held on disk after the completion of PreCommit 2 to 11GiB.
+  #
+  # type: bool
+  # env var: LOTUS_SEALING_USESYNTHETICPOREP
+  #UseSyntheticPoRep = false
+
 
 [Storage]
   # type: int
diff --git a/extern/filecoin-ffi b/extern/filecoin-ffi
index a458f638e3c..fa64b553732 160000
--- a/extern/filecoin-ffi
+++ b/extern/filecoin-ffi
@@ -1 +1 @@
-Subproject commit a458f638e3c8603c9b5a9ed9847c3af4597e46d4
+Subproject commit fa64b5537320dbdcf8456bb6ca9e82adb07b7747
diff --git a/extern/test-vectors b/extern/test-vectors
index 28b0c45eab4..195bc065973 160000
--- a/extern/test-vectors
+++ b/extern/test-vectors
@@ -1 +1 @@
-Subproject commit 28b0c45eab4c302864af0aeaaff813625cfafe97
+Subproject commit 195bc065973ec35826621823964a5c3cbe5fa56d
diff --git a/gen/inlinegen-data.json b/gen/inlinegen-data.json
index 5208f391263..cf72d24fa9c 100644
--- a/gen/inlinegen-data.json
+++ b/gen/inlinegen-data.json
@@ -1,7 +1,7 @@
 {
-  "actorVersions": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
-  "latestActorsVersion":  11,
+  "actorVersions": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
+  "latestActorsVersion":  12,
 
-  "networkVersions": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
-  "latestNetworkVersion":  20
+  "networkVersions": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21],
+  "latestNetworkVersion":  21
 }
diff --git a/go.mod b/go.mod
index 8ebfceebb66..75be445752a 100644
--- a/go.mod
+++ b/go.mod
@@ -33,7 +33,7 @@ require (
 	github.com/filecoin-project/dagstore v0.5.2
 	github.com/filecoin-project/filecoin-ffi v0.30.4-0.20220519234331-bfd1f5f9fe38
 	github.com/filecoin-project/go-address v1.1.0
-	github.com/filecoin-project/go-amt-ipld/v4 v4.0.0
+	github.com/filecoin-project/go-amt-ipld/v4 v4.2.0
 	github.com/filecoin-project/go-bitfield v0.2.4
 	github.com/filecoin-project/go-cbor-util v0.0.1
 	github.com/filecoin-project/go-commp-utils v0.1.3
@@ -45,7 +45,7 @@ require (
 	github.com/filecoin-project/go-jsonrpc v0.3.1
 	github.com/filecoin-project/go-padreader v0.0.1
 	github.com/filecoin-project/go-paramfetch v0.0.4
-	github.com/filecoin-project/go-state-types v0.11.1
+	github.com/filecoin-project/go-state-types v0.12.8
 	github.com/filecoin-project/go-statemachine v1.0.3
 	github.com/filecoin-project/go-statestore v0.2.0
 	github.com/filecoin-project/go-storedcounter v0.1.0
@@ -59,7 +59,7 @@ require (
 	github.com/filecoin-project/specs-actors/v6 v6.0.2
 	github.com/filecoin-project/specs-actors/v7 v7.0.1
 	github.com/filecoin-project/specs-actors/v8 v8.0.1
-	github.com/filecoin-project/test-vectors/schema v0.0.5
+	github.com/filecoin-project/test-vectors/schema v0.0.6-0.20230822140104-bed37e1ca04f
 	github.com/gbrlsnchs/jwt/v3 v3.0.1
 	github.com/gdamore/tcell/v2 v2.2.0
 	github.com/go-openapi/spec v0.19.11
@@ -72,7 +72,8 @@ require (
 	github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e
 	github.com/hashicorp/go-hclog v1.3.0
 	github.com/hashicorp/go-multierror v1.1.1
-	github.com/hashicorp/golang-lru/v2 v2.0.2
+	github.com/hashicorp/golang-lru/arc/v2 v2.0.5
+	github.com/hashicorp/golang-lru/v2 v2.0.5
 	github.com/hashicorp/raft v1.3.10
 	github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea
 	github.com/icza/backscanner v0.0.0-20210726202459-ac2ffc679f94
@@ -105,7 +106,7 @@ require (
 	github.com/kelseyhightower/envconfig v1.4.0
 	github.com/koalacxr/quantile v0.0.1
 	github.com/libp2p/go-buffer-pool v0.1.0
-	github.com/libp2p/go-libp2p v0.27.9
+	github.com/libp2p/go-libp2p v0.30.0
 	github.com/libp2p/go-libp2p-consensus v0.0.1
 	github.com/libp2p/go-libp2p-gorpc v0.5.0
 	github.com/libp2p/go-libp2p-kad-dht v0.24.0
@@ -120,7 +121,7 @@ require (
 	github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1
 	github.com/mitchellh/go-homedir v1.1.0
 	github.com/multiformats/go-base32 v0.1.0
-	github.com/multiformats/go-multiaddr v0.9.0
+	github.com/multiformats/go-multiaddr v0.11.0
 	github.com/multiformats/go-multiaddr-dns v0.3.1
 	github.com/multiformats/go-multibase v0.2.0
 	github.com/multiformats/go-multihash v0.2.3
@@ -135,7 +136,7 @@ require (
 	github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
 	github.com/urfave/cli/v2 v2.25.5
 	github.com/whyrusleeping/bencher v0.0.0-20190829221104-bb6607aa8bba
-	github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa
+	github.com/whyrusleeping/cbor-gen v0.0.0-20230923211252-36a87e1ba72f
 	github.com/whyrusleeping/ledger-filecoin-go v0.9.1-0.20201010031517-c3dcc1bddce4
 	github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7
 	github.com/xeipuuv/gojsonschema v1.2.0
@@ -147,17 +148,17 @@ require (
 	go.opentelemetry.io/otel/exporters/jaeger v1.14.0
 	go.opentelemetry.io/otel/sdk v1.16.0
 	go.uber.org/atomic v1.11.0
-	go.uber.org/fx v1.19.3
+	go.uber.org/fx v1.20.0
 	go.uber.org/multierr v1.11.0
-	go.uber.org/zap v1.24.0
-	golang.org/x/crypto v0.10.0
-	golang.org/x/exp v0.0.0-20230321023759-10a507213a29
-	golang.org/x/net v0.10.0
-	golang.org/x/sync v0.2.0
-	golang.org/x/sys v0.9.0
-	golang.org/x/term v0.9.0
+	go.uber.org/zap v1.25.0
+	golang.org/x/crypto v0.12.0
+	golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63
+	golang.org/x/net v0.14.0
+	golang.org/x/sync v0.3.0
+	golang.org/x/sys v0.11.0
+	golang.org/x/term v0.11.0
 	golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9
-	golang.org/x/tools v0.9.1
+	golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846
 	golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2
 	gopkg.in/cheggaaa/pb.v1 v1.0.28
 	gotest.tools v2.2.0+incompatible
@@ -218,7 +219,7 @@ require (
 	github.com/golang/snappy v0.0.4 // indirect
 	github.com/google/go-cmp v0.5.9 // indirect
 	github.com/google/gopacket v1.1.19 // indirect
-	github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect
+	github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b // indirect
 	github.com/hannahhoward/cbor-gen-for v0.0.0-20230214144701-5d17c9d5243c // indirect
 	github.com/hashicorp/errwrap v1.1.0 // indirect
 	github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
@@ -252,7 +253,7 @@ require (
 	github.com/josharian/intern v1.0.0 // indirect
 	github.com/jpillora/backoff v1.0.0 // indirect
 	github.com/kilic/bls12-381 v0.1.0 // indirect
-	github.com/klauspost/compress v1.16.5 // indirect
+	github.com/klauspost/compress v1.16.7 // indirect
 	github.com/klauspost/cpuid/v2 v2.2.5 // indirect
 	github.com/koron/go-ssdp v0.0.4 // indirect
 	github.com/libp2p/go-cidranger v1.1.0 // indirect
@@ -260,18 +261,18 @@ require (
 	github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect
 	github.com/libp2p/go-libp2p-gostream v0.6.0 // indirect
 	github.com/libp2p/go-libp2p-kbucket v0.6.1 // indirect
-	github.com/libp2p/go-nat v0.1.0 // indirect
+	github.com/libp2p/go-nat v0.2.0 // indirect
 	github.com/libp2p/go-netroute v0.2.1 // indirect
-	github.com/libp2p/go-reuseport v0.2.0 // indirect
-	github.com/libp2p/go-yamux/v4 v4.0.0 // indirect
+	github.com/libp2p/go-reuseport v0.4.0 // indirect
+	github.com/libp2p/go-yamux/v4 v4.0.1 // indirect
 	github.com/lucasb-eyer/go-colorful v1.0.3 // indirect
 	github.com/magefile/mage v1.9.0 // indirect
-	github.com/mailru/easyjson v0.7.6 // indirect
+	github.com/mailru/easyjson v0.7.7 // indirect
 	github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect
 	github.com/mattn/go-colorable v0.1.13 // indirect
 	github.com/mattn/go-runewidth v0.0.10 // indirect
 	github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
-	github.com/miekg/dns v1.1.54 // indirect
+	github.com/miekg/dns v1.1.55 // indirect
 	github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect
 	github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect
 	github.com/minio/sha256-simd v1.0.1 // indirect
@@ -282,8 +283,8 @@ require (
 	github.com/multiformats/go-multistream v0.4.1 // indirect
 	github.com/nikkolasg/hexjson v0.1.0 // indirect
 	github.com/nkovacs/streamquote v1.0.0 // indirect
-	github.com/onsi/ginkgo/v2 v2.9.7 // indirect
-	github.com/opencontainers/runtime-spec v1.0.2 // indirect
+	github.com/onsi/ginkgo/v2 v2.11.0 // indirect
+	github.com/opencontainers/runtime-spec v1.1.0 // indirect
 	github.com/opentracing/opentracing-go v1.2.0 // indirect
 	github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect
 	github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect
@@ -294,9 +295,8 @@ require (
 	github.com/prometheus/procfs v0.9.0 // indirect
 	github.com/prometheus/statsd_exporter v0.22.7 // indirect
 	github.com/quic-go/qpack v0.4.0 // indirect
-	github.com/quic-go/qtls-go1-19 v0.3.3 // indirect
-	github.com/quic-go/qtls-go1-20 v0.2.3 // indirect
-	github.com/quic-go/quic-go v0.33.1 // indirect
+	github.com/quic-go/qtls-go1-20 v0.3.2 // indirect
+	github.com/quic-go/quic-go v0.37.6 // indirect
 	github.com/quic-go/webtransport-go v0.5.3 // indirect
 	github.com/rivo/uniseg v0.1.0 // indirect
 	github.com/rs/cors v1.7.0 // indirect
@@ -322,8 +322,8 @@ require (
 	go.opentelemetry.io/otel/trace v1.16.0 // indirect
 	go.uber.org/dig v1.17.0 // indirect
 	go4.org v0.0.0-20230225012048-214862532bf5 // indirect
-	golang.org/x/mod v0.10.0 // indirect
-	golang.org/x/text v0.10.0 // indirect
+	golang.org/x/mod v0.12.0 // indirect
+	golang.org/x/text v0.12.0 // indirect
 	gonum.org/v1/gonum v0.13.0 // indirect
 	google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect
 	google.golang.org/grpc v1.55.0 // indirect
@@ -332,7 +332,6 @@ require (
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 	howett.net/plist v0.0.0-20181124034731-591f970eefbb // indirect
 	lukechampine.com/blake3 v1.2.1 // indirect
-	nhooyr.io/websocket v1.8.7 // indirect
 )
 
 replace github.com/filecoin-project/filecoin-ffi => ./extern/filecoin-ffi
diff --git a/go.sum b/go.sum
index 00cc035f524..1ea3ac44c43 100644
--- a/go.sum
+++ b/go.sum
@@ -288,8 +288,9 @@ github.com/filecoin-project/go-amt-ipld/v2 v2.1.0/go.mod h1:nfFPoGyX0CU9SkXX8EoC
 github.com/filecoin-project/go-amt-ipld/v3 v3.0.0/go.mod h1:Qa95YNAbtoVCTSVtX38aAC1ptBnJfPma1R/zZsKmx4o=
 github.com/filecoin-project/go-amt-ipld/v3 v3.1.0 h1:ZNJ9tEG5bE72vBWYiuh5bkxJVM3ViHNOmQ7qew9n6RE=
 github.com/filecoin-project/go-amt-ipld/v3 v3.1.0/go.mod h1:UjM2QhDFrrjD5s1CdnkJkat4ga+LqZBZgTMniypABRo=
-github.com/filecoin-project/go-amt-ipld/v4 v4.0.0 h1:XM81BJ4/6h3FV0WfFjh74cIDIgqMbJsMBLM0fIuLUUk=
 github.com/filecoin-project/go-amt-ipld/v4 v4.0.0/go.mod h1:gF053YQ4BIpzTNDoEwHZas7U3oAwncDVGvOHyY8oDpE=
+github.com/filecoin-project/go-amt-ipld/v4 v4.2.0 h1:DQTXQwMXxaetd+lhZGODjt5qC1WYT7tMAlYrWqI/fwI=
+github.com/filecoin-project/go-amt-ipld/v4 v4.2.0/go.mod h1:0eDVF7pROvxrsxvLJx+SJZXqRaXXcEPUcgb/rG0zGU4=
 github.com/filecoin-project/go-bitfield v0.2.0/go.mod h1:CNl9WG8hgR5mttCnUErjcQjGvuiZjRqK9rHVBsQF4oM=
 github.com/filecoin-project/go-bitfield v0.2.3/go.mod h1:CNl9WG8hgR5mttCnUErjcQjGvuiZjRqK9rHVBsQF4oM=
 github.com/filecoin-project/go-bitfield v0.2.4 h1:uZ7MeE+XfM5lqrHJZ93OnhQKc/rveW8p9au0C68JPgk=
@@ -336,8 +337,9 @@ github.com/filecoin-project/go-state-types v0.0.0-20201102161440-c8033295a1fc/go
 github.com/filecoin-project/go-state-types v0.1.0/go.mod h1:ezYnPf0bNkTsDibL/psSz5dy4B5awOJ/E7P2Saeep8g=
 github.com/filecoin-project/go-state-types v0.1.6/go.mod h1:UwGVoMsULoCK+bWjEdd/xLCvLAQFBC7EDT477SKml+Q=
 github.com/filecoin-project/go-state-types v0.1.10/go.mod h1:UwGVoMsULoCK+bWjEdd/xLCvLAQFBC7EDT477SKml+Q=
-github.com/filecoin-project/go-state-types v0.11.1 h1:GDtCN9V18bYVwXDZe+vJXc6Ck+qY9OUaQqpoVlp1FAk=
-github.com/filecoin-project/go-state-types v0.11.1/go.mod h1:SyNPwTsU7I22gL2r0OAPcImvLoTVfgRwdK/Y5rR1zz8=
+github.com/filecoin-project/go-state-types v0.11.2-0.20230712101859-8f37624fa540/go.mod h1:SyNPwTsU7I22gL2r0OAPcImvLoTVfgRwdK/Y5rR1zz8=
+github.com/filecoin-project/go-state-types v0.12.8 h1:W/UObdAsv+LbB9EfyLg92DSYoatzUWmlfV8FGyh30VA=
+github.com/filecoin-project/go-state-types v0.12.8/go.mod h1:gR2NV0CSGSQwopxF+3In9nDh1sqvoYukLcs5vK0AHCA=
 github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig=
 github.com/filecoin-project/go-statemachine v1.0.3 h1:N07o6alys+V1tNoSTi4WuuoeNC4erS/6jE74+NsgQuk=
 github.com/filecoin-project/go-statemachine v1.0.3/go.mod h1:jZdXXiHa61n4NmgWFG4w8tnqgvZVHYbJ3yW7+y8bF54=
@@ -368,8 +370,8 @@ github.com/filecoin-project/specs-actors/v7 v7.0.1 h1:w72xCxijK7xs1qzmJiw+WYJaVt
 github.com/filecoin-project/specs-actors/v7 v7.0.1/go.mod h1:tPLEYXoXhcpyLh69Ccq91SOuLXsPWjHiY27CzawjUEk=
 github.com/filecoin-project/specs-actors/v8 v8.0.1 h1:4u0tIRJeT5G7F05lwLRIsDnsrN+bJ5Ixj6h49Q7uE2Y=
 github.com/filecoin-project/specs-actors/v8 v8.0.1/go.mod h1:UYIPg65iPWoFw5NEftREdJwv9b/5yaLKdCgTvNI/2FA=
-github.com/filecoin-project/test-vectors/schema v0.0.5 h1:w3zHQhzM4pYxJDl21avXjOKBLF8egrvwUwjpT8TquDg=
-github.com/filecoin-project/test-vectors/schema v0.0.5/go.mod h1:iQ9QXLpYWL3m7warwvK1JC/pTri8mnfEmKygNDqqY6E=
+github.com/filecoin-project/test-vectors/schema v0.0.6-0.20230822140104-bed37e1ca04f h1:Ho3kK/WetJ7wco2VhR/pOZ9HD/WWL1BDEzYRTFQK8dw=
+github.com/filecoin-project/test-vectors/schema v0.0.6-0.20230822140104-bed37e1ca04f/go.mod h1:iQ9QXLpYWL3m7warwvK1JC/pTri8mnfEmKygNDqqY6E=
 github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
 github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ=
 github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag=
@@ -392,10 +394,6 @@ github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo
 github.com/gdamore/tcell/v2 v2.2.0 h1:vSyEgKwraXPSOkvCk7IwOSyX+Pv3V2cV9CikJMXg4U4=
 github.com/gdamore/tcell/v2 v2.2.0/go.mod h1:cTTuF84Dlj/RqmaCIV5p4w8uG1zWdk0SF6oBpwHp4fU=
 github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
-github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
-github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
-github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
-github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
 github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
 github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
 github.com/go-chi/chi v1.5.4 h1:QHdzF2szwjqVV4wmByUnTcsbIg7UGaQ0tPF2t5GcAIs=
@@ -439,13 +437,6 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh
 github.com/go-openapi/swag v0.19.8/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY=
 github.com/go-openapi/swag v0.19.11 h1:RFTu/dlFySpyVvJDfp/7674JY4SDglYWKztbiIGFpmc=
 github.com/go-openapi/swag v0.19.11/go.mod h1:Uc0gKkdR+ojzsEpjh39QChyu92vPgIr72POcgHMAgSY=
-github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
-github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
-github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
-github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
-github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
-github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY=
-github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
 github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
@@ -455,12 +446,6 @@ github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSC
 github.com/gobuffalo/logger v1.0.0/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs=
 github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q=
 github.com/gobuffalo/packr/v2 v2.6.0/go.mod h1:sgEE1xNZ6G0FNN5xn9pevVu4nywaxHvgup67xisti08=
-github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0=
-github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
-github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8=
-github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
-github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo=
-github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
 github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
 github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
 github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
@@ -552,8 +537,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf
 github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
 github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
 github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs=
-github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA=
+github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b h1:h9U78+dx9a4BKdQkBBos92HalKpaGKHrp+3Uo6yTodo=
+github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
 github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
 github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -631,8 +616,10 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
 github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
 github.com/hashicorp/golang-lru v0.6.0 h1:uL2shRDx7RTrOrTCUZEGP/wJUFiUI8QT6E7z5o8jga4=
 github.com/hashicorp/golang-lru v0.6.0/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
-github.com/hashicorp/golang-lru/v2 v2.0.2 h1:Dwmkdr5Nc/oBiXgJS3CDHNhJtIHkuZ3DZF5twqnfBdU=
-github.com/hashicorp/golang-lru/v2 v2.0.2/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
+github.com/hashicorp/golang-lru/arc/v2 v2.0.5 h1:l2zaLDubNhW4XO3LnliVj0GXO3+/CGNJAg1dcN2Fpfw=
+github.com/hashicorp/golang-lru/arc/v2 v2.0.5/go.mod h1:ny6zBSQZi2JxIeYcv7kt2sH2PXJtirBN7RDhRpxPkxU=
+github.com/hashicorp/golang-lru/v2 v2.0.5 h1:wW7h1TG88eUIJ2i69gaE3uNVtEPIagzhGvHgwfx2Vm4=
+github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
 github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
 github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
 github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
@@ -903,7 +890,6 @@ github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u
 github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
 github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
 github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
@@ -926,13 +912,13 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
 github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
-github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
 github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
-github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI=
-github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
+github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
+github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
 github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
 github.com/klauspost/cpuid/v2 v2.0.6/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
 github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
+github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
 github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
 github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
 github.com/koalacxr/quantile v0.0.1 h1:wAW+SQ286Erny9wOjVww96t8ws+x5Zj6AKHDULUK+o0=
@@ -956,8 +942,6 @@ github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
-github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
-github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
 github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ=
 github.com/libp2p/go-addr-util v0.0.2/go.mod h1:Ecd6Fb3yIuLzq4bD7VcywcVSBtefcAwnUISBM3WG15E=
 github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ=
@@ -982,8 +966,8 @@ github.com/libp2p/go-libp2p v0.7.0/go.mod h1:hZJf8txWeCduQRDC/WSqBGMxaTHCOYHt2xS
 github.com/libp2p/go-libp2p v0.7.4/go.mod h1:oXsBlTLF1q7pxr+9w6lqzS1ILpyHsaBPniVO7zIHGMw=
 github.com/libp2p/go-libp2p v0.8.1/go.mod h1:QRNH9pwdbEBpx5DTJYg+qxcVaDMAz3Ee/qDKwXujH5o=
 github.com/libp2p/go-libp2p v0.14.3/go.mod h1:d12V4PdKbpL0T1/gsUNN8DfgMuRPDX8bS2QxCZlwRH0=
-github.com/libp2p/go-libp2p v0.27.9 h1:n5p5bQD469v7I/1qncaHDq0BeSx4iT2fHF3NyNuKOmY=
-github.com/libp2p/go-libp2p v0.27.9/go.mod h1:Tdx7ZuJl9NE78PkB4FjPVbf6kaQNOh2ppU/OVvVB6Wc=
+github.com/libp2p/go-libp2p v0.30.0 h1:9EZwFtJPFBcs/yJTnP90TpN1hgrT/EsFfM+OZuwV87U=
+github.com/libp2p/go-libp2p v0.30.0/go.mod h1:nr2g5V7lfftwgiJ78/HrID+pwvayLyqKCEirT2Y3Byg=
 github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s=
 github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w=
 github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8=
@@ -1120,8 +1104,8 @@ github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbx
 github.com/libp2p/go-nat v0.0.3/go.mod h1:88nUEt0k0JD45Bk93NIwDqjlhiOwOoV36GchpcVc1yI=
 github.com/libp2p/go-nat v0.0.4/go.mod h1:Nmw50VAvKuk38jUBcmNh6p9lUJLoODbJRvYAa/+KSDo=
 github.com/libp2p/go-nat v0.0.5/go.mod h1:B7NxsVNPZmRLvMOwiEO1scOSyjA56zxYAGv1yQgRkEU=
-github.com/libp2p/go-nat v0.1.0 h1:MfVsH6DLcpa04Xr+p8hmVRG4juse0s3J8HyNWYHffXg=
-github.com/libp2p/go-nat v0.1.0/go.mod h1:X7teVkwRHNInVNWQiO/tAiAVRwSr5zoRz4YSTC3uRBM=
+github.com/libp2p/go-nat v0.2.0 h1:Tyz+bUFAYqGyJ/ppPPymMGbIgNRH+WqC5QrT5fKrrGk=
+github.com/libp2p/go-nat v0.2.0/go.mod h1:3MJr+GRpRkyT65EpVPBstXLvOlAPzUVlG6Pwg9ohLJk=
 github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk=
 github.com/libp2p/go-netroute v0.1.3/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk=
 github.com/libp2p/go-netroute v0.1.5/go.mod h1:V1SR3AaECRkEQCoFFzYwVYWvYIEtlxx89+O3qcpCl4A=
@@ -1135,8 +1119,8 @@ github.com/libp2p/go-openssl v0.0.5/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO
 github.com/libp2p/go-openssl v0.0.7/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc=
 github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA=
 github.com/libp2p/go-reuseport v0.0.2/go.mod h1:SPD+5RwGC7rcnzngoYC86GjPzjSywuQyMVAheVBD9nQ=
-github.com/libp2p/go-reuseport v0.2.0 h1:18PRvIMlpY6ZK85nIAicSBuXXvrYoSw3dsBAR7zc560=
-github.com/libp2p/go-reuseport v0.2.0/go.mod h1:bvVho6eLMm6Bz5hmU0LYN3ixd3nPPvtIlaURZZgOY4k=
+github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQscQm2s=
+github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU=
 github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs=
 github.com/libp2p/go-reuseport-transport v0.0.3/go.mod h1:Spv+MPft1exxARzP2Sruj2Wb5JSyHNncjf1Oi2dEbzM=
 github.com/libp2p/go-reuseport-transport v0.0.4/go.mod h1:trPa7r/7TJK/d+0hdBLOCGvpQQVOU74OXbNCIMkufGw=
@@ -1164,8 +1148,8 @@ github.com/libp2p/go-yamux v1.3.7/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/h
 github.com/libp2p/go-yamux v1.4.0/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE=
 github.com/libp2p/go-yamux v1.4.1/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE=
 github.com/libp2p/go-yamux/v2 v2.2.0/go.mod h1:3So6P6TV6r75R9jiBpiIKgU/66lOarCZjqROGxzPpPQ=
-github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ=
-github.com/libp2p/go-yamux/v4 v4.0.0/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4=
+github.com/libp2p/go-yamux/v4 v4.0.1 h1:FfDR4S1wj6Bw2Pqbc8Uz7pCxeRBPbwsBbEdfwiCypkQ=
+github.com/libp2p/go-yamux/v4 v4.0.1/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4=
 github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
 github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
 github.com/lucas-clemente/quic-go v0.19.3/go.mod h1:ADXpNbTQjq1hIzCpB+y/k5iz4n4z4IwqoLb94Kh5Hu8=
@@ -1181,8 +1165,9 @@ github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN
 github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
 github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
 github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
-github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
 github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
+github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
+github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
 github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc=
 github.com/marten-seemann/qtls v0.10.0/go.mod h1:UvMd1oaYDACI99/oZUYLzMCkBXQVT0aGm99sJhbT8hs=
 github.com/marten-seemann/qtls-go1-15 v0.1.1/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I=
@@ -1221,8 +1206,8 @@ github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3N
 github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
 github.com/miekg/dns v1.1.28/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
 github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
-github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI=
-github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
+github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo=
+github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
 github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8=
 github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms=
 github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc=
@@ -1249,11 +1234,9 @@ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0Qu
 github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
-github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
 github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
 github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8=
 github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8=
@@ -1279,8 +1262,8 @@ github.com/multiformats/go-multiaddr v0.2.2/go.mod h1:NtfXiOtHvghW9KojvtySjH5y0u
 github.com/multiformats/go-multiaddr v0.3.0/go.mod h1:dF9kph9wfJ+3VLAaeBqo9Of8x4fJxp6ggJGteB8HQTI=
 github.com/multiformats/go-multiaddr v0.3.1/go.mod h1:uPbspcUPd5AfaP6ql3ujFY+QWzmBD8uLLL4bXW0XfGc=
 github.com/multiformats/go-multiaddr v0.3.3/go.mod h1:lCKNGP1EQ1eZ35Za2wlqnabm9xQkib3fyB+nZXHLag0=
-github.com/multiformats/go-multiaddr v0.9.0 h1:3h4V1LHIk5w4hJHekMKWALPXErDfz/sggzwC/NcqbDQ=
-github.com/multiformats/go-multiaddr v0.9.0/go.mod h1:mI67Lb1EeTOYb8GQfL/7wpIZwc46ElrvzhYnoJOmTT0=
+github.com/multiformats/go-multiaddr v0.11.0 h1:XqGyJ8ufbCE0HmTDwx2kPdsrQ36AGPZNZX6s6xfJH10=
+github.com/multiformats/go-multiaddr v0.11.0/go.mod h1:gWUm0QLR4thQ6+ZF6SXUw8YjtwQSPapICM+NmCkxHSM=
 github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q=
 github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q=
 github.com/multiformats/go-multiaddr-dns v0.2.0/go.mod h1:TJ5pr5bBO7Y1B18djPuRsVkduhQH2YqYSbxWJzYGdK0=
@@ -1358,20 +1341,21 @@ github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0
 github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
 github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
 github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
-github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss=
-github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+M/1uw0=
+github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU=
+github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM=
 github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
 github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
 github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
 github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
 github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
 github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
-github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU=
+github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc=
 github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
 github.com/open-rpc/meta-schema v0.0.0-20201029221707-1b72ef2ea333 h1:CznVS40zms0Dj5he4ERo+fRPtO0qxUk8lA8Xu3ddet0=
 github.com/open-rpc/meta-schema v0.0.0-20201029221707-1b72ef2ea333/go.mod h1:Ag6rSXkHIckQmjFBCweJEEt1mrTPBv8b9W4aU/NQWfI=
-github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0=
 github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
+github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg=
+github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
 github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e h1:4cPxUYdgaGzZIT5/j0IfqOrrXmq6bG8AwvwisMXpdrg=
 github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
 github.com/opentracing-contrib/go-stdlib v1.0.0 h1:TBS7YuVotp8myLon4Pv7BtCBzOTo1DeZCld0Z63mW2w=
@@ -1469,12 +1453,10 @@ github.com/puzpuzpuz/xsync/v2 v2.4.0 h1:5sXAMHrtx1bg9nbRZTOn8T4MkWe5V+o8yKRH02Ez
 github.com/puzpuzpuz/xsync/v2 v2.4.0/go.mod h1:gD2H2krq/w52MfPLE+Uy64TzJDVY7lP2znR9qmR35kU=
 github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
 github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
-github.com/quic-go/qtls-go1-19 v0.3.3 h1:wznEHvJwd+2X3PqftRha0SUKmGsnb6dfArMhy9PeJVE=
-github.com/quic-go/qtls-go1-19 v0.3.3/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI=
-github.com/quic-go/qtls-go1-20 v0.2.3 h1:m575dovXn1y2ATOb1XrRFcrv0F+EQmlowTkoraNkDPI=
-github.com/quic-go/qtls-go1-20 v0.2.3/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM=
-github.com/quic-go/quic-go v0.33.1 h1:EVsG7O/7FVZI8Za71GzpHDoWpBTKdjDv1/x0KFcckho=
-github.com/quic-go/quic-go v0.33.1/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA=
+github.com/quic-go/qtls-go1-20 v0.3.2 h1:rRgN3WfnKbyik4dBV8A6girlJVxGand/d+jVKbQq5GI=
+github.com/quic-go/qtls-go1-20 v0.3.2/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
+github.com/quic-go/quic-go v0.37.6 h1:2IIUmQzT5YNxAiaPGjs++Z4hGOtIR0q79uS5qE9ccfY=
+github.com/quic-go/quic-go v0.37.6/go.mod h1:YsbH1r4mSHPJcLF4k4zruUkLBqctEMBDR6VPvcYjIsU=
 github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU=
 github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU=
 github.com/raulk/clock v1.1.0 h1:dpb29+UKMbLqiU/jqIJptgLR1nn23HLgMY0sTCDza5Y=
@@ -1609,10 +1591,8 @@ github.com/twmb/murmur3 v1.1.6 h1:mqrRot1BRxm+Yct+vavLMou2/iJt0tNVTTC0QoIjaZg=
 github.com/twmb/murmur3 v1.1.6/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ=
 github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o=
 github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg=
-github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
 github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn0=
 github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
-github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
 github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ=
 github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw=
 github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
@@ -1656,8 +1636,8 @@ github.com/whyrusleeping/cbor-gen v0.0.0-20200826160007-0b9f6c5fb163/go.mod h1:f
 github.com/whyrusleeping/cbor-gen v0.0.0-20210118024343-169e9d70c0c2/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
 github.com/whyrusleeping/cbor-gen v0.0.0-20210303213153-67a261a1d291/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
 github.com/whyrusleeping/cbor-gen v0.0.0-20220323183124-98fa8256a799/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
-github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa h1:EyA027ZAkuaCLoxVX4r1TZMPy1d31fM6hbfQ4OU4I5o=
-github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
+github.com/whyrusleeping/cbor-gen v0.0.0-20230923211252-36a87e1ba72f h1:SBuSxXJL0/ZJMtTxbXZgHZkThl9dNrzyaNhlyaqscRo=
+github.com/whyrusleeping/cbor-gen v0.0.0-20230923211252-36a87e1ba72f/go.mod h1:fgkXqYy7bV2cFeIEOkVTZS/WjXARfBqSH6Q2qHL33hQ=
 github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E=
 github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8=
 github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k=
@@ -1750,8 +1730,8 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
 go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
 go.uber.org/dig v1.17.0 h1:5Chju+tUvcC+N7N6EV08BJz41UZuO3BmHcN4A287ZLI=
 go.uber.org/dig v1.17.0/go.mod h1:rTxpf7l5I0eBTlE6/9RL+lDybC7WFwY2QH55ZSjy1mU=
-go.uber.org/fx v1.19.3 h1:YqMRE4+2IepTYCMOvXqQpRa+QAVdiSTnsHU4XNWBceA=
-go.uber.org/fx v1.19.3/go.mod h1:w2HrQg26ql9fLK7hlBiZ6JsRUKV+Lj/atT1KCjT8YhM=
+go.uber.org/fx v1.20.0 h1:ZMC/pnRvhsthOZh9MZjMq5U8Or3mA9zBSPaLnzs3ihQ=
+go.uber.org/fx v1.20.0/go.mod h1:qCUj0btiR3/JnanEr1TYEePfSw6o/4qYJscgvzQ5Ub0=
 go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
 go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
 go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
@@ -1770,8 +1750,8 @@ go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
 go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
 go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=
 go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
-go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
-go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
+go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c=
+go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk=
 go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
 go4.org v0.0.0-20200411211856-f5505b9728dd/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZMZXMSBGhxRdsvzbkg=
 go4.org v0.0.0-20230225012048-214862532bf5 h1:nifaUDeh+rPaBCMPMQHZmvJf+QdpLFnuQPwx+LxVmtc=
@@ -1816,8 +1796,8 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
-golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
-golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
+golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
+golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -1831,8 +1811,8 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH
 golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
 golang.org/x/exp v0.0.0-20210615023648-acb5c1269671/go.mod h1:DVyR6MI7P4kEQgvZJSj1fQGrWIi2RzIrfYWycwheUAc=
 golang.org/x/exp v0.0.0-20210714144626-1041f73d31d8/go.mod h1:DVyR6MI7P4kEQgvZJSj1fQGrWIi2RzIrfYWycwheUAc=
-golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug=
-golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
+golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ=
+golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8=
 golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
 golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
 golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -1858,8 +1838,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
-golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
+golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -1921,8 +1901,8 @@ golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
 golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
-golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
+golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -1946,8 +1926,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
-golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
+golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
 golang.org/x/sys v0.0.0-20180202135801-37707fdb30a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -2043,6 +2023,7 @@ golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -2051,16 +2032,16 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
-golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
+golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
-golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28=
-golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
+golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0=
+golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -2070,8 +2051,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
-golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
+golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -2138,8 +2119,8 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
 golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
-golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo=
-golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
+golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E=
+golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -2303,8 +2284,6 @@ lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R
 lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA=
 lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI=
 lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
-nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g=
-nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=
 rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
 rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
 rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
diff --git a/itests/batch_deal_test.go b/itests/batch_deal_test.go
index 68b276a0c36..21db9f08d0e 100644
--- a/itests/batch_deal_test.go
+++ b/itests/batch_deal_test.go
@@ -61,7 +61,6 @@ func TestBatchDealInput(t *testing.T) {
 						sc.MaxSealingSectorsForDeals = 3
 						sc.AlwaysKeepUnsealedCopy = true
 						sc.WaitDealsDelay = time.Hour
-						sc.BatchPreCommits = false
 						sc.AggregateCommits = false
 
 						return sc, nil
diff --git a/itests/ccupgrade_test.go b/itests/ccupgrade_test.go
deleted file mode 100644
index 030e115f83d..00000000000
--- a/itests/ccupgrade_test.go
+++ /dev/null
@@ -1,131 +0,0 @@
-// stm: #integration
-package itests
-
-import (
-	"context"
-	"fmt"
-	"testing"
-	"time"
-
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
-
-	"github.com/filecoin-project/go-state-types/abi"
-	"github.com/filecoin-project/go-state-types/network"
-
-	"github.com/filecoin-project/lotus/chain/types"
-	"github.com/filecoin-project/lotus/itests/kit"
-)
-
-func TestCCUpgrade(t *testing.T) {
-	//stm: @CHAIN_SYNCER_LOAD_GENESIS_001, @CHAIN_SYNCER_FETCH_TIPSET_001,
-	//stm: @CHAIN_SYNCER_START_001, @CHAIN_SYNCER_SYNC_001, @BLOCKCHAIN_BEACON_VALIDATE_BLOCK_VALUES_01
-	//stm: @CHAIN_SYNCER_COLLECT_CHAIN_001, @CHAIN_SYNCER_COLLECT_HEADERS_001, @CHAIN_SYNCER_VALIDATE_TIPSET_001
-	//stm: @CHAIN_SYNCER_NEW_PEER_HEAD_001, @CHAIN_SYNCER_VALIDATE_MESSAGE_META_001, @CHAIN_SYNCER_STOP_001
-
-	//stm: @CHAIN_STATE_MINER_GET_INFO_001
-	//stm: @CHAIN_INCOMING_HANDLE_INCOMING_BLOCKS_001, @CHAIN_INCOMING_VALIDATE_BLOCK_PUBSUB_001, @CHAIN_INCOMING_VALIDATE_MESSAGE_PUBSUB_001
-
-	//stm: @MINER_SECTOR_LIST_001
-	kit.QuietMiningLogs()
-
-	n := runTestCCUpgrade(t)
-
-	t.Run("post", func(t *testing.T) {
-		ctx := context.Background()
-		ts, err := n.ChainHead(ctx)
-		require.NoError(t, err)
-		start := ts.Height()
-		// wait for a full proving period
-		t.Log("waiting for chain")
-
-		n.WaitTillChain(ctx, func(ts *types.TipSet) bool {
-			if ts.Height() > start+abi.ChainEpoch(2880) {
-				return true
-			}
-			return false
-		})
-	})
-}
-
-func runTestCCUpgrade(t *testing.T) *kit.TestFullNode {
-	ctx := context.Background()
-	blockTime := 1 * time.Millisecond
-
-	client, miner, ens := kit.EnsembleMinimal(t, kit.GenesisNetworkVersion(network.Version15), kit.ThroughRPC())
-	ens.InterconnectAll().BeginMiningMustPost(blockTime)
-
-	maddr, err := miner.ActorAddress(ctx)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	CCUpgrade := abi.SectorNumber(kit.DefaultPresealsPerBootstrapMiner)
-	fmt.Printf("CCUpgrade: %d\n", CCUpgrade)
-
-	miner.PledgeSectors(ctx, 1, 0, nil)
-	sl, err := miner.SectorsListNonGenesis(ctx)
-	require.NoError(t, err)
-	require.Len(t, sl, 1, "expected 1 sector")
-	require.Equal(t, CCUpgrade, sl[0], "unexpected sector number")
-
-	si, err := client.StateSectorGetInfo(ctx, maddr, CCUpgrade, types.EmptyTSK)
-	require.NoError(t, err)
-	require.NotNil(t, si)
-	require.Less(t, 50000, int(si.Expiration))
-	require.True(t, si.ReplacedSectorAge == 0)
-
-	client.WaitForSectorActive(ctx, t, CCUpgrade, maddr)
-
-	//stm: @SECTOR_CC_UPGRADE_001
-	err = miner.SectorMarkForUpgrade(ctx, sl[0], true)
-	require.NoError(t, err)
-
-	sl, err = miner.SectorsListNonGenesis(ctx)
-	require.NoError(t, err)
-	require.Len(t, sl, 1, "expected 1 sector")
-
-	dh := kit.NewDealHarness(t, client, miner, miner)
-	deal, res, inPath := dh.MakeOnlineDeal(ctx, kit.MakeFullDealParams{
-		Rseed:                        6,
-		SuspendUntilCryptoeconStable: true,
-	})
-	outPath := dh.PerformRetrieval(context.Background(), deal, res.Root, false)
-	kit.AssertFilesEqual(t, inPath, outPath)
-
-	status, err := miner.SectorsStatus(ctx, CCUpgrade, true)
-	require.NoError(t, err)
-	assert.Equal(t, 1, len(status.Deals))
-
-	miner.WaitSectorsProving(ctx, map[abi.SectorNumber]struct{}{
-		CCUpgrade: {},
-	})
-
-	siUpdate, err := client.StateSectorGetInfo(ctx, maddr, CCUpgrade, types.EmptyTSK)
-	require.NoError(t, err)
-	require.NotNil(t, siUpdate)
-	require.True(t, siUpdate.SectorKeyCID != nil)
-	require.True(t, siUpdate.Activation > si.Activation)
-
-	return client
-}
-
-func TestCCUpgradeAndPoSt(t *testing.T) {
-	kit.QuietMiningLogs()
-	t.Run("upgrade and then post", func(t *testing.T) {
-		ctx := context.Background()
-		n := runTestCCUpgrade(t)
-		ts, err := n.ChainHead(ctx)
-		require.NoError(t, err)
-		start := ts.Height()
-		// wait for a full proving period
-		t.Log("waiting for chain")
-
-		n.WaitTillChain(ctx, func(ts *types.TipSet) bool {
-			if ts.Height() > start+abi.ChainEpoch(2880) {
-				return true
-			}
-			return false
-		})
-	})
-}
diff --git a/itests/deadlines_test.go b/itests/deadlines_test.go
index 472e66abc63..fb28f450974 100644
--- a/itests/deadlines_test.go
+++ b/itests/deadlines_test.go
@@ -18,7 +18,6 @@ import (
 	"github.com/filecoin-project/go-state-types/builtin"
 	minertypes "github.com/filecoin-project/go-state-types/builtin/v8/miner"
 	"github.com/filecoin-project/go-state-types/exitcode"
-	"github.com/filecoin-project/go-state-types/network"
 	miner2 "github.com/filecoin-project/specs-actors/v2/actors/builtin/miner"
 
 	"github.com/filecoin-project/lotus/api"
@@ -34,28 +33,6 @@ import (
 )
 
 // TestDeadlineToggling:
-// * spins up a v3 network (miner A)
-// * creates an inactive miner (miner B)
-// * creates another miner, pledges a sector, waits for power (miner C)
-//
-// * goes through v4 upgrade
-// * goes through PP
-// * creates minerD, minerE
-// * makes sure that miner B/D are inactive, A/C still are
-// * pledges sectors on miner B/D
-// * precommits a sector on minerE
-// * disables post on miner C
-// * goes through PP 0.5PP
-// * asserts that minerE is active
-// * goes through rest of PP (1.5)
-// * asserts that miner C loses power
-// * asserts that miner B/D is active and has power
-// * asserts that minerE is inactive
-// * disables post on miner B
-// * terminates sectors on miner D
-// * goes through another PP
-// * asserts that miner B loses power
-// * asserts that miner D loses power, is inactive
 func TestDeadlineToggling(t *testing.T) {
 	//stm: @CHAIN_SYNCER_LOAD_GENESIS_001, @CHAIN_SYNCER_FETCH_TIPSET_001,
 	//stm: @CHAIN_SYNCER_START_001, @CHAIN_SYNCER_SYNC_001, @BLOCKCHAIN_BEACON_VALIDATE_BLOCK_VALUES_01
@@ -71,7 +48,6 @@ func TestDeadlineToggling(t *testing.T) {
 	const sectorsC, sectorsD, sectorsB = 10, 9, 8
 
 	var (
-		upgradeH      abi.ChainEpoch = 4000
 		provingPeriod abi.ChainEpoch = 2880
 		blocktime                    = 2 * time.Millisecond
 	)
@@ -81,14 +57,14 @@ func TestDeadlineToggling(t *testing.T) {
 
 	var (
 		client kit.TestFullNode
-		minerA kit.TestMiner
-		minerB kit.TestMiner
-		minerC kit.TestMiner
-		minerD kit.TestMiner
-		minerE kit.TestMiner
+		minerA kit.TestMiner // A has some genesis sector, just keeps power
+		minerB kit.TestMiner // B pledges some sector, later fails some posts but stays alive
+		minerC kit.TestMiner // C pledges sectors, gains power, and later stops its PoSTs, but stays alive
+		minerD kit.TestMiner // D pledges sectors and later terminates them, losing all power, eventually deactivates cron
+		minerE kit.TestMiner // E pre-commits a sector but doesn't advance beyond that, cron should become inactive
 	)
 	opts := []kit.NodeOpt{kit.WithAllSubsystems()}
-	ens := kit.NewEnsemble(t, kit.MockProofs(), kit.TurboUpgradeAt(upgradeH)).
+	ens := kit.NewEnsemble(t, kit.MockProofs()).
 		FullNode(&client, opts...).
 		Miner(&minerA, &client, opts...).
 		Start().
@@ -116,6 +92,8 @@ func TestDeadlineToggling(t *testing.T) {
 	ssz, err := minerC.ActorSectorSize(ctx, maddrC)
 	require.NoError(t, err)
 
+	targetHeight := abi.ChainEpoch(0)
+
 	// pledge sectors on C, go through a PP, check for power
 	{
 		minerC.PledgeSectors(ctx, sectorsC, 0, nil)
@@ -127,11 +105,13 @@ func TestDeadlineToggling(t *testing.T) {
 		t.Log("Running one proving period (miner C)")
 		t.Logf("End for head.Height > %d", di.PeriodStart+di.WPoStProvingPeriod*2)
 
+		targetHeight = di.PeriodStart + provingPeriod*2
+
 		for {
 			head, err := client.ChainHead(ctx)
 			require.NoError(t, err)
 
-			if head.Height() > di.PeriodStart+provingPeriod*2 {
+			if head.Height() > targetHeight {
 				t.Logf("Now head.Height = %d", head.Height())
 				break
 			}
@@ -148,18 +128,6 @@ func TestDeadlineToggling(t *testing.T) {
 		require.Equal(t, p.MinerPower.RawBytePower, expectedPower)
 	}
 
-	// go through upgrade + PP
-	for {
-		head, err := client.ChainHead(ctx)
-		require.NoError(t, err)
-
-		if head.Height() > upgradeH+provingPeriod {
-			t.Logf("Now head.Height = %d", head.Height())
-			break
-		}
-		build.Clock.Sleep(blocktime)
-	}
-
 	checkMiner := func(ma address.Address, power abi.StoragePower, active bool, tsk types.TipSetKey) {
 		//stm: @CHAIN_STATE_MINER_POWER_001
 		p, err := client.StateMinerPower(ctx, ma, tsk)
@@ -181,18 +149,6 @@ func TestDeadlineToggling(t *testing.T) {
 		require.Equal(t, active, act)
 	}
 
-	// check that just after the upgrade minerB was still active
-	{
-		uts, err := client.ChainGetTipSetByHeight(ctx, upgradeH+2, types.EmptyTSK)
-		require.NoError(t, err)
-		checkMiner(maddrB, types.NewInt(0), true, uts.Key())
-	}
-
-	//stm: @CHAIN_STATE_NETWORK_VERSION_001
-	nv, err := client.StateNetworkVersion(ctx, types.EmptyTSK)
-	require.NoError(t, err)
-	require.GreaterOrEqual(t, nv, network.Version12)
-
 	ens.Miner(&minerD, &client, opts...).
 		Miner(&minerE, &client, opts...).
 		Start()
@@ -254,12 +210,14 @@ func TestDeadlineToggling(t *testing.T) {
 		require.Equal(t, exitcode.Ok, r.Receipt.ExitCode)
 	}
 
+	targetHeight = targetHeight + (provingPeriod / 2)
+
 	// go through 0.5 PP
 	for {
 		head, err := client.ChainHead(ctx)
 		require.NoError(t, err)
 
-		if head.Height() > upgradeH+provingPeriod+(provingPeriod/2) {
+		if head.Height() > targetHeight {
 			t.Logf("Now head.Height = %d", head.Height())
 			break
 		}
@@ -268,12 +226,14 @@ func TestDeadlineToggling(t *testing.T) {
 
 	checkMiner(maddrE, types.NewInt(0), true, types.EmptyTSK)
 
+	targetHeight = targetHeight + (provingPeriod/2)*5
+
 	// go through rest of the PP
 	for {
 		head, err := client.ChainHead(ctx)
 		require.NoError(t, err)
 
-		if head.Height() > upgradeH+(provingPeriod*3) {
+		if head.Height() > targetHeight {
 			t.Logf("Now head.Height = %d", head.Height())
 			break
 		}
@@ -285,7 +245,12 @@ func TestDeadlineToggling(t *testing.T) {
 	checkMiner(maddrC, types.NewInt(0), true, types.EmptyTSK)
 	checkMiner(maddrB, types.NewInt(uint64(ssz)*sectorsB), true, types.EmptyTSK)
 	checkMiner(maddrD, types.NewInt(uint64(ssz)*sectorsD), true, types.EmptyTSK)
-	checkMiner(maddrE, types.NewInt(0), false, types.EmptyTSK)
+
+	// Note: in the older version of this test `active` would be set to false
+	// this is now true because the time to commit a precommit a sector has
+	// increased to 30 days. We could keep the original assert and increase the
+	// wait above to 30 days, but that makes the test take 14 minutes to run..
+	checkMiner(maddrE, types.NewInt(0), true, types.EmptyTSK)
 
 	// disable post on minerB
 	minerB.StorageMiner.(*impl.StorageMinerAPI).IStorageMgr.(*mock.SectorMgr).Fail()
@@ -344,12 +309,14 @@ func TestDeadlineToggling(t *testing.T) {
 		require.True(t, p.MinerPower.RawBytePower.IsZero())
 	}
 
+	targetHeight = targetHeight + provingPeriod*2
+
 	// go through another PP
 	for {
 		head, err := client.ChainHead(ctx)
 		require.NoError(t, err)
 
-		if head.Height() > upgradeH+(provingPeriod*5) {
+		if head.Height() > targetHeight {
 			t.Logf("Now head.Height = %d", head.Height())
 			break
 		}
diff --git a/itests/eth_transactions_test.go b/itests/eth_transactions_test.go
index 8d836573da9..3c131a256f8 100644
--- a/itests/eth_transactions_test.go
+++ b/itests/eth_transactions_test.go
@@ -81,12 +81,16 @@ func TestValueTransferValidSignature(t *testing.T) {
 	receipt, err := waitForEthTxReceipt(ctx, client, hash)
 	require.NoError(t, err)
 	require.NotNil(t, receipt)
+	require.EqualValues(t, ethAddr, receipt.From)
+	require.EqualValues(t, ethAddr2, *receipt.To)
+	require.EqualValues(t, hash, receipt.TransactionHash)
 
 	// Success.
 	require.EqualValues(t, ethtypes.EthUint64(0x1), receipt.Status)
 
+	// Validate that we sent the expected transaction.
 	ethTx, err := client.EthGetTransactionByHash(ctx, &hash)
-	require.Nil(t, err)
+	require.NoError(t, err)
 	require.EqualValues(t, ethAddr, ethTx.From)
 	require.EqualValues(t, ethAddr2, *ethTx.To)
 	require.EqualValues(t, tx.ChainID, ethTx.ChainID)
@@ -269,6 +273,17 @@ func TestContractInvocation(t *testing.T) {
 
 	// Success.
 	require.EqualValues(t, ethtypes.EthUint64(0x1), receipt.Status)
+
+	// Validate that we correctly computed the gas outputs.
+	mCid, err := client.EthGetMessageCidByTransactionHash(ctx, &hash)
+	require.NoError(t, err)
+	require.NotNil(t, mCid)
+
+	invokResult, err := client.StateReplay(ctx, types.EmptyTSK, *mCid)
+	require.NoError(t, err)
+	require.EqualValues(t, invokResult.GasCost.GasUsed, big.NewInt(int64(receipt.GasUsed)))
+	effectiveGasPrice := big.Div(invokResult.GasCost.TotalCost, invokResult.GasCost.GasUsed)
+	require.EqualValues(t, effectiveGasPrice, big.Int(receipt.EffectiveGasPrice))
 }
 
 func TestGetBlockByNumber(t *testing.T) {
diff --git a/itests/fevm_test.go b/itests/fevm_test.go
index 1512c3277fa..cb69c036cad 100644
--- a/itests/fevm_test.go
+++ b/itests/fevm_test.go
@@ -618,9 +618,9 @@ func TestFEVMRecursiveActorCall(t *testing.T) {
 	t.Run("n=251,r=32", testN(251, 32, exitcode.Ok))
 
 	t.Run("n=0,r=252", testN(0, 252, exitcode.Ok))
-	t.Run("n=251,r=166", testN(251, 166, exitcode.Ok))
+	t.Run("n=251,r=164", testN(251, 164, exitcode.Ok))
 
-	t.Run("n=0,r=253-fails", testN(0, 254, exitcode.ExitCode(33))) // 33 means transaction reverted
+	t.Run("n=0,r=255-fails", testN(0, 255, exitcode.ExitCode(33))) // 33 means transaction reverted
 	t.Run("n=251,r=167-fails", testN(251, 167, exitcode.ExitCode(33)))
 }
 
diff --git a/itests/kit/ensemble.go b/itests/kit/ensemble.go
index 19cc163af5a..e55a6674383 100644
--- a/itests/kit/ensemble.go
+++ b/itests/kit/ensemble.go
@@ -258,7 +258,7 @@ func (n *Ensemble) MinerEnroll(minerNode *TestMiner, full *TestFullNode, opts ..
 		)
 
 		// Will use 2KiB sectors by default (default value of sectorSize).
-		proofType, err := miner.SealProofTypeFromSectorSize(options.sectorSize, n.genesis.version)
+		proofType, err := miner.SealProofTypeFromSectorSize(options.sectorSize, n.genesis.version, false)
 		require.NoError(n.t, err)
 
 		// Create the preseal commitment.
diff --git a/itests/kit/ensemble_opts_nv.go b/itests/kit/ensemble_opts_nv.go
index a30ed0e3280..d5bb1930ef0 100644
--- a/itests/kit/ensemble_opts_nv.go
+++ b/itests/kit/ensemble_opts_nv.go
@@ -23,20 +23,6 @@ func GenesisNetworkVersion(nv network.Version) EnsembleOpt {
 	})
 }
 
-func SDRUpgradeAt(calico, persian abi.ChainEpoch) EnsembleOpt {
-	return UpgradeSchedule(stmgr.Upgrade{
-		Network: network.Version6,
-		Height:  -1,
-	}, stmgr.Upgrade{
-		Network:   network.Version7,
-		Height:    calico,
-		Migration: filcns.UpgradeCalico,
-	}, stmgr.Upgrade{
-		Network: network.Version8,
-		Height:  persian,
-	})
-}
-
 func LatestActorsAt(upgradeHeight abi.ChainEpoch) EnsembleOpt {
 	/* inline-gen template
 		return UpgradeSchedule(stmgr.Upgrade{
@@ -49,23 +35,12 @@ func LatestActorsAt(upgradeHeight abi.ChainEpoch) EnsembleOpt {
 		})
 	/* inline-gen start */
 	return UpgradeSchedule(stmgr.Upgrade{
-		Network: network.Version19,
+		Network: network.Version20,
 		Height:  -1,
 	}, stmgr.Upgrade{
-		Network:   network.Version20,
+		Network:   network.Version21,
 		Height:    upgradeHeight,
-		Migration: filcns.UpgradeActorsV11,
+		Migration: filcns.UpgradeActorsV12,
 	})
 	/* inline-gen end */
 }
-
-func TurboUpgradeAt(upgradeHeight abi.ChainEpoch) EnsembleOpt {
-	return UpgradeSchedule(stmgr.Upgrade{
-		Network: network.Version11,
-		Height:  -1,
-	}, stmgr.Upgrade{
-		Network:   network.Version12,
-		Height:    upgradeHeight,
-		Migration: filcns.UpgradeActorsV4,
-	})
-}
diff --git a/itests/migration_test.go b/itests/migration_test.go
index 4082792ce3d..68991a579a9 100644
--- a/itests/migration_test.go
+++ b/itests/migration_test.go
@@ -34,6 +34,7 @@ import (
 	"github.com/filecoin-project/lotus/chain/actors/builtin/datacap"
 	"github.com/filecoin-project/lotus/chain/actors/builtin/market"
 	"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
+	"github.com/filecoin-project/lotus/chain/actors/builtin/system"
 	"github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
 	"github.com/filecoin-project/lotus/chain/consensus/filcns"
 	"github.com/filecoin-project/lotus/chain/state"
@@ -301,7 +302,7 @@ func TestMigrationNV17(t *testing.T) {
 	minerInfo, err := testClient.StateMinerInfo(ctx, testMiner.ActorAddr, types.EmptyTSK)
 	require.NoError(t, err)
 
-	spt, err := miner.SealProofTypeFromSectorSize(minerInfo.SectorSize, network.Version17)
+	spt, err := miner.SealProofTypeFromSectorSize(minerInfo.SectorSize, network.Version17, false)
 	require.NoError(t, err)
 
 	preCommitParams := miner9.PreCommitSectorParams{
@@ -762,3 +763,68 @@ waitForProof20:
 	require.Equal(t, v1proof, minerInfo.WindowPoStProofType)
 
 }
+
+func TestMigrationNV21(t *testing.T) {
+	kit.QuietMiningLogs()
+
+	nv21epoch := abi.ChainEpoch(100)
+	testClient, _, ens := kit.EnsembleMinimal(t, kit.MockProofs(),
+		kit.UpgradeSchedule(stmgr.Upgrade{
+			Network: network.Version20,
+			Height:  -1,
+		}, stmgr.Upgrade{
+			Network:   network.Version21,
+			Height:    nv21epoch,
+			Migration: filcns.UpgradeActorsV12,
+		},
+		))
+
+	ens.InterconnectAll().BeginMining(10 * time.Millisecond)
+
+	clientApi := testClient.FullNode.(*impl.FullNodeAPI)
+	ctx, cancel := context.WithCancel(context.Background())
+	defer cancel()
+
+	testClient.WaitTillChain(ctx, kit.HeightAtLeast(nv21epoch+5))
+
+	// Now that we have upgraded, we need to verify:
+	// - Sector info changes executed successfully
+	// - Direct data onboarding correct
+
+	bs := blockstore.NewAPIBlockstore(testClient)
+	ctxStore := gstStore.WrapBlockStore(ctx, bs)
+
+	currTs, err := clientApi.ChainHead(ctx)
+	require.NoError(t, err)
+
+	newStateTree, err := state.LoadStateTree(ctxStore, currTs.Blocks()[0].ParentStateRoot)
+	require.NoError(t, err)
+
+	require.Equal(t, types.StateTreeVersion5, newStateTree.Version())
+
+	// check the system actor
+	systemAct, err := newStateTree.GetActor(builtin.SystemActorAddr)
+	require.NoError(t, err)
+
+	systemCode, ok := actors.GetActorCodeID(actorstypes.Version12, manifest.SystemKey)
+	require.True(t, ok)
+
+	require.Equal(t, systemCode, systemAct.Code)
+
+	systemSt, err := system.Load(ctxStore, systemAct)
+	require.NoError(t, err)
+
+	manifest12Cid, ok := actors.GetManifest(actorstypes.Version12)
+	require.True(t, ok)
+
+	manifest12, err := actors.LoadManifest(ctx, manifest12Cid, ctxStore)
+	require.NoError(t, err)
+	require.Equal(t, manifest12.Data, systemSt.GetBuiltinActors())
+
+	// start post migration checks
+
+	//todo @aayush sector info changes
+
+	//todo @zen Direct data onboarding tests
+
+}
diff --git a/itests/sdr_upgrade_test.go b/itests/sdr_upgrade_test.go
deleted file mode 100644
index d92d4edc9b1..00000000000
--- a/itests/sdr_upgrade_test.go
+++ /dev/null
@@ -1,117 +0,0 @@
-// stm: #integration
-package itests
-
-import (
-	"context"
-	"sort"
-	"sync/atomic"
-	"testing"
-	"time"
-
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
-
-	"github.com/filecoin-project/go-state-types/abi"
-	"github.com/filecoin-project/go-state-types/network"
-
-	"github.com/filecoin-project/lotus/build"
-	"github.com/filecoin-project/lotus/itests/kit"
-	bminer "github.com/filecoin-project/lotus/miner"
-)
-
-func TestSDRUpgrade(t *testing.T) {
-	//stm: @CHAIN_SYNCER_LOAD_GENESIS_001, @CHAIN_SYNCER_FETCH_TIPSET_001,
-	//stm: @CHAIN_SYNCER_START_001, @CHAIN_SYNCER_SYNC_001, @BLOCKCHAIN_BEACON_VALIDATE_BLOCK_VALUES_01
-	//stm: @CHAIN_SYNCER_COLLECT_CHAIN_001, @CHAIN_SYNCER_COLLECT_HEADERS_001, @CHAIN_SYNCER_VALIDATE_TIPSET_001
-	//stm: @CHAIN_SYNCER_NEW_PEER_HEAD_001, @CHAIN_SYNCER_VALIDATE_MESSAGE_META_001, @CHAIN_SYNCER_STOP_001
-
-	//stm: @CHAIN_INCOMING_HANDLE_INCOMING_BLOCKS_001, @CHAIN_INCOMING_VALIDATE_BLOCK_PUBSUB_001, @CHAIN_INCOMING_VALIDATE_MESSAGE_PUBSUB_001
-	//stm: @CHAIN_STATE_NETWORK_VERSION_001
-
-	//stm: @MINER_SECTOR_LIST_001
-	kit.QuietMiningLogs()
-
-	// oldDelay := policy.GetPreCommitChallengeDelay()
-	// policy.SetPreCommitChallengeDelay(5)
-	// t.Cleanup(func() {
-	// 	policy.SetPreCommitChallengeDelay(oldDelay)
-	// })
-
-	blocktime := 50 * time.Millisecond
-
-	ctx, cancel := context.WithCancel(context.Background())
-	defer cancel()
-
-	client, miner, ens := kit.EnsembleMinimal(t,
-		kit.MockProofs(),
-		kit.SDRUpgradeAt(500, 1000),
-	)
-	ens.InterconnectAll()
-
-	build.Clock.Sleep(time.Second)
-
-	pledge := make(chan struct{})
-	mine := int64(1)
-	done := make(chan struct{})
-	go func() {
-		defer close(done)
-		round := 0
-		for atomic.LoadInt64(&mine) != 0 {
-			build.Clock.Sleep(blocktime)
-			if err := miner.MineOne(ctx, bminer.MineReq{Done: func(bool, abi.ChainEpoch, error) {
-
-			}}); err != nil {
-				t.Error(err)
-			}
-
-			// 3 sealing rounds: before, during after.
-			if round >= 3 {
-				continue
-			}
-
-			head, err := client.ChainHead(ctx)
-			assert.NoError(t, err)
-
-			// rounds happen every 100 blocks, with a 50 block offset.
-			if head.Height() >= abi.ChainEpoch(round*500+50) {
-				round++
-				pledge <- struct{}{}
-
-				ver, err := client.StateNetworkVersion(ctx, head.Key())
-				assert.NoError(t, err)
-				switch round {
-				case 1:
-					assert.Equal(t, network.Version6, ver)
-				case 2:
-					assert.Equal(t, network.Version7, ver)
-				case 3:
-					assert.Equal(t, network.Version8, ver)
-				}
-			}
-
-		}
-	}()
-
-	// before.
-	miner.PledgeSectors(ctx, 9, 0, pledge)
-
-	s, err := miner.SectorsListNonGenesis(ctx)
-	require.NoError(t, err)
-	sort.Slice(s, func(i, j int) bool {
-		return s[i] < s[j]
-	})
-
-	for i, id := range s {
-		info, err := miner.SectorsStatus(ctx, id, true)
-		require.NoError(t, err)
-		expectProof := abi.RegisteredSealProof_StackedDrg2KiBV1
-		if i >= 3 {
-			// after
-			expectProof = abi.RegisteredSealProof_StackedDrg2KiBV1_1
-		}
-		assert.Equal(t, expectProof, info.SealProof, "sector %d, id %d", i, id)
-	}
-
-	atomic.StoreInt64(&mine, 0)
-	<-done
-}
diff --git a/itests/sector_import_full_test.go b/itests/sector_import_full_test.go
index e4ec5e141f2..c9bd96afde1 100644
--- a/itests/sector_import_full_test.go
+++ b/itests/sector_import_full_test.go
@@ -88,7 +88,7 @@ func TestSectorImport(t *testing.T) {
 			require.NoError(t, err)
 			ver, err := client.StateNetworkVersion(ctx, types.EmptyTSK)
 			require.NoError(t, err)
-			spt, err := lminer.PreferredSealProofTypeFromWindowPoStType(ver, mi.WindowPoStProofType)
+			spt, err := lminer.PreferredSealProofTypeFromWindowPoStType(ver, mi.WindowPoStProofType, false)
 			require.NoError(t, err)
 
 			ssize, err := spt.SectorSize()
diff --git a/itests/sector_import_simple_test.go b/itests/sector_import_simple_test.go
index f344386945c..fb1a77a1410 100644
--- a/itests/sector_import_simple_test.go
+++ b/itests/sector_import_simple_test.go
@@ -63,7 +63,7 @@ func TestSectorImportAfterPC2(t *testing.T) {
 	require.NoError(t, err)
 	ver, err := client.StateNetworkVersion(ctx, types.EmptyTSK)
 	require.NoError(t, err)
-	spt, err := lminer.PreferredSealProofTypeFromWindowPoStType(ver, mi.WindowPoStProofType)
+	spt, err := lminer.PreferredSealProofTypeFromWindowPoStType(ver, mi.WindowPoStProofType, false)
 	require.NoError(t, err)
 
 	ssize, err := spt.SectorSize()
diff --git a/itests/sector_make_cc_avail_test.go b/itests/sector_make_cc_avail_test.go
deleted file mode 100644
index 524b3c70fc1..00000000000
--- a/itests/sector_make_cc_avail_test.go
+++ /dev/null
@@ -1,78 +0,0 @@
-package itests
-
-import (
-	"context"
-	"testing"
-	"time"
-
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
-
-	"github.com/filecoin-project/go-state-types/abi"
-	"github.com/filecoin-project/go-state-types/network"
-
-	"github.com/filecoin-project/lotus/api"
-	"github.com/filecoin-project/lotus/chain/types"
-	"github.com/filecoin-project/lotus/itests/kit"
-	"github.com/filecoin-project/lotus/node/config"
-	sealing "github.com/filecoin-project/lotus/storage/pipeline"
-)
-
-func TestMakeAvailable(t *testing.T) {
-	kit.QuietMiningLogs()
-
-	ctx := context.Background()
-	blockTime := 1 * time.Millisecond
-
-	client, miner, ens := kit.EnsembleMinimal(t, kit.GenesisNetworkVersion(network.Version15), kit.ThroughRPC(), kit.MutateSealingConfig(func(sc *config.SealingConfig) {
-		sc.MakeCCSectorsAvailable = true
-	}))
-	ens.InterconnectAll().BeginMiningMustPost(blockTime)
-
-	maddr, err := miner.ActorAddress(ctx)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	CCUpgrade := abi.SectorNumber(kit.DefaultPresealsPerBootstrapMiner)
-
-	miner.PledgeSectors(ctx, 1, 0, nil)
-	sl, err := miner.SectorsListNonGenesis(ctx)
-	require.NoError(t, err)
-	require.Len(t, sl, 1, "expected 1 sector")
-	require.Equal(t, CCUpgrade, sl[0], "unexpected sector number")
-	{
-		si, err := client.StateSectorGetInfo(ctx, maddr, CCUpgrade, types.EmptyTSK)
-		require.NoError(t, err)
-		require.NotNil(t, si)
-		require.Less(t, 50000, int(si.Expiration))
-	}
-	client.WaitForSectorActive(ctx, t, CCUpgrade, maddr)
-
-	sl, err = miner.SectorsListNonGenesis(ctx)
-	require.NoError(t, err)
-	require.Len(t, sl, 1, "expected 1 sector")
-
-	status, err := miner.SectorsStatus(ctx, CCUpgrade, true)
-	require.NoError(t, err)
-	assert.Equal(t, api.SectorState(sealing.Available), status.State)
-
-	dh := kit.NewDealHarness(t, client, miner, miner)
-	deal, res, inPath := dh.MakeOnlineDeal(ctx, kit.MakeFullDealParams{
-		Rseed:                        6,
-		SuspendUntilCryptoeconStable: true,
-	})
-	outPath := dh.PerformRetrieval(context.Background(), deal, res.Root, false)
-	kit.AssertFilesEqual(t, inPath, outPath)
-
-	sl, err = miner.SectorsListNonGenesis(ctx)
-	require.NoError(t, err)
-	require.Len(t, sl, 1, "expected 1 sector")
-
-	status, err = miner.SectorsStatus(ctx, CCUpgrade, true)
-	require.NoError(t, err)
-	assert.Equal(t, 1, len(status.Deals))
-	miner.WaitSectorsProving(ctx, map[abi.SectorNumber]struct{}{
-		CCUpgrade: {},
-	})
-}
diff --git a/itests/sector_miner_collateral_test.go b/itests/sector_miner_collateral_test.go
index 8d7abacee59..579b4e535a1 100644
--- a/itests/sector_miner_collateral_test.go
+++ b/itests/sector_miner_collateral_test.go
@@ -51,7 +51,6 @@ func TestMinerBalanceCollateral(t *testing.T) {
 					sc.AlwaysKeepUnsealedCopy = true
 					sc.WaitDealsDelay = time.Hour
 
-					sc.BatchPreCommits = batching
 					sc.AggregateCommits = batching
 
 					sc.PreCommitBatchWait = time.Hour
diff --git a/itests/sector_pledge_test.go b/itests/sector_pledge_test.go
index 2ac1298d088..1e045c79d7d 100644
--- a/itests/sector_pledge_test.go
+++ b/itests/sector_pledge_test.go
@@ -12,13 +12,13 @@ import (
 	"github.com/stretchr/testify/require"
 
 	"github.com/filecoin-project/go-state-types/abi"
-	"github.com/filecoin-project/go-state-types/network"
 	miner5 "github.com/filecoin-project/specs-actors/v5/actors/builtin/miner"
 
 	"github.com/filecoin-project/lotus/api"
 	"github.com/filecoin-project/lotus/build"
 	"github.com/filecoin-project/lotus/chain/types"
 	"github.com/filecoin-project/lotus/itests/kit"
+	"github.com/filecoin-project/lotus/node/config"
 	"github.com/filecoin-project/lotus/node/impl"
 	sealing "github.com/filecoin-project/lotus/storage/pipeline"
 )
@@ -197,48 +197,29 @@ func TestPledgeMaxBatching(t *testing.T) {
 	t.Run("Force max prove commit aggregate size", runTest)
 }
 
-func TestPledgeBeforeNv13(t *testing.T) {
-	//stm: @CHAIN_SYNCER_LOAD_GENESIS_001, @CHAIN_SYNCER_FETCH_TIPSET_001,
-	//stm: @CHAIN_SYNCER_START_001, @CHAIN_SYNCER_SYNC_001, @BLOCKCHAIN_BEACON_VALIDATE_BLOCK_VALUES_01
-	//stm: @CHAIN_SYNCER_COLLECT_CHAIN_001, @CHAIN_SYNCER_COLLECT_HEADERS_001, @CHAIN_SYNCER_VALIDATE_TIPSET_001
-	//stm: @CHAIN_SYNCER_NEW_PEER_HEAD_001, @CHAIN_SYNCER_VALIDATE_MESSAGE_META_001, @CHAIN_SYNCER_STOP_001
+func TestPledgeSynth(t *testing.T) {
+	kit.QuietMiningLogs()
 
-	//stm: @CHAIN_INCOMING_HANDLE_INCOMING_BLOCKS_001, @CHAIN_INCOMING_VALIDATE_BLOCK_PUBSUB_001, @CHAIN_INCOMING_VALIDATE_MESSAGE_PUBSUB_001
-	blocktime := 50 * time.Millisecond
+	blockTime := 50 * time.Millisecond
 
 	runTest := func(t *testing.T, nSectors int) {
 		ctx, cancel := context.WithCancel(context.Background())
 		defer cancel()
 
-		client, miner, ens := kit.EnsembleMinimal(t, kit.MockProofs(),
-			kit.GenesisNetworkVersion(network.Version12))
-		ens.InterconnectAll().BeginMining(blocktime)
-
-		client.WaitTillChain(ctx, kit.HeightAtLeast(10))
+		_, miner, ens := kit.EnsembleMinimal(t, kit.MutateSealingConfig(func(sc *config.SealingConfig) {
+			sc.UseSyntheticPoRep = true
+		})) // no mock proofs
 
-		toCheck := miner.StartPledge(ctx, nSectors, 0, nil)
-
-		for len(toCheck) > 0 {
-			states := map[api.SectorState]int{}
-
-			for n := range toCheck {
-				st, err := miner.SectorsStatus(ctx, n, false)
-				require.NoError(t, err)
-				states[st.State]++
-				if st.State == api.SectorState(sealing.Proving) {
-					delete(toCheck, n)
-				}
-				if strings.Contains(string(st.State), "Fail") {
-					t.Fatal("sector in a failed state", st.State)
-				}
-			}
+		ens.InterconnectAll().BeginMiningMustPost(blockTime)
 
-			build.Clock.Sleep(100 * time.Millisecond)
-			fmt.Printf("WaitSeal: %d %+v\n", len(toCheck), states)
-		}
+		miner.PledgeSectors(ctx, nSectors, 0, nil)
 	}
 
-	t.Run("100-before-nv13", func(t *testing.T) {
-		runTest(t, 100)
+	t.Run("1", func(t *testing.T) {
+		runTest(t, 1)
+	})
+
+	t.Run("3", func(t *testing.T) {
+		runTest(t, 3)
 	})
 }
diff --git a/itests/sector_prefer_no_upgrade_test.go b/itests/sector_prefer_no_upgrade_test.go
deleted file mode 100644
index 96f07f9e4f0..00000000000
--- a/itests/sector_prefer_no_upgrade_test.go
+++ /dev/null
@@ -1,90 +0,0 @@
-package itests
-
-import (
-	"context"
-	"testing"
-	"time"
-
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
-
-	"github.com/filecoin-project/go-state-types/abi"
-	"github.com/filecoin-project/go-state-types/network"
-
-	"github.com/filecoin-project/lotus/api"
-	"github.com/filecoin-project/lotus/chain/types"
-	"github.com/filecoin-project/lotus/itests/kit"
-	"github.com/filecoin-project/lotus/node/config"
-	sealing "github.com/filecoin-project/lotus/storage/pipeline"
-)
-
-func TestPreferNoUpgrade(t *testing.T) {
-	kit.QuietMiningLogs()
-
-	ctx := context.Background()
-	blockTime := 1 * time.Millisecond
-
-	client, miner, ens := kit.EnsembleMinimal(t, kit.GenesisNetworkVersion(network.Version15), kit.ThroughRPC(), kit.MutateSealingConfig(func(sc *config.SealingConfig) {
-		sc.PreferNewSectorsForDeals = true
-	}))
-	ens.InterconnectAll().BeginMiningMustPost(blockTime)
-
-	maddr, err := miner.ActorAddress(ctx)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	CCUpgrade := abi.SectorNumber(kit.DefaultPresealsPerBootstrapMiner)
-	Sealed := abi.SectorNumber(kit.DefaultPresealsPerBootstrapMiner + 1)
-
-	{
-		miner.PledgeSectors(ctx, 1, 0, nil)
-		sl, err := miner.SectorsListNonGenesis(ctx)
-		require.NoError(t, err)
-		require.Len(t, sl, 1, "expected 1 sector")
-		require.Equal(t, CCUpgrade, sl[0], "unexpected sector number")
-		{
-			si, err := client.StateSectorGetInfo(ctx, maddr, CCUpgrade, types.EmptyTSK)
-			require.NoError(t, err)
-			require.NotNil(t, si)
-			require.Less(t, 50000, int(si.Expiration))
-		}
-		client.WaitForSectorActive(ctx, t, CCUpgrade, maddr)
-
-		err = miner.SectorMarkForUpgrade(ctx, sl[0], true)
-		require.NoError(t, err)
-
-		sl, err = miner.SectorsListNonGenesis(ctx)
-		require.NoError(t, err)
-		require.Len(t, sl, 1, "expected 1 sector")
-	}
-
-	{
-		dh := kit.NewDealHarness(t, client, miner, miner)
-		deal, res, inPath := dh.MakeOnlineDeal(ctx, kit.MakeFullDealParams{
-			Rseed:                        6,
-			SuspendUntilCryptoeconStable: true,
-		})
-		outPath := dh.PerformRetrieval(context.Background(), deal, res.Root, false)
-		kit.AssertFilesEqual(t, inPath, outPath)
-	}
-
-	sl, err := miner.SectorsListNonGenesis(ctx)
-	require.NoError(t, err)
-	require.Len(t, sl, 2, "expected 2 sectors")
-
-	{
-		status, err := miner.SectorsStatus(ctx, CCUpgrade, true)
-		require.NoError(t, err)
-		assert.Equal(t, api.SectorState(sealing.Available), status.State)
-	}
-
-	{
-		status, err := miner.SectorsStatus(ctx, Sealed, true)
-		require.NoError(t, err)
-		assert.Equal(t, 1, len(status.Deals))
-		miner.WaitSectorsProving(ctx, map[abi.SectorNumber]struct{}{
-			Sealed: {},
-		})
-	}
-}
diff --git a/itests/sector_revert_available_test.go b/itests/sector_revert_available_test.go
deleted file mode 100644
index 41a46024f6f..00000000000
--- a/itests/sector_revert_available_test.go
+++ /dev/null
@@ -1,85 +0,0 @@
-package itests
-
-import (
-	"context"
-	"fmt"
-	"testing"
-	"time"
-
-	"github.com/stretchr/testify/require"
-
-	"github.com/filecoin-project/go-state-types/abi"
-	"github.com/filecoin-project/go-state-types/network"
-
-	"github.com/filecoin-project/lotus/api"
-	"github.com/filecoin-project/lotus/chain/types"
-	"github.com/filecoin-project/lotus/itests/kit"
-	sealing "github.com/filecoin-project/lotus/storage/pipeline"
-)
-
-func TestAbortUpgradeAvailable(t *testing.T) {
-	kit.QuietMiningLogs()
-
-	ctx := context.Background()
-	blockTime := 1 * time.Millisecond
-
-	client, miner, ens := kit.EnsembleMinimal(t, kit.GenesisNetworkVersion(network.Version15), kit.ThroughRPC())
-	ens.InterconnectAll().BeginMiningMustPost(blockTime)
-
-	maddr, err := miner.ActorAddress(ctx)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	CCUpgrade := abi.SectorNumber(kit.DefaultPresealsPerBootstrapMiner)
-	fmt.Printf("CCUpgrade: %d\n", CCUpgrade)
-
-	miner.PledgeSectors(ctx, 1, 0, nil)
-	sl, err := miner.SectorsListNonGenesis(ctx)
-	require.NoError(t, err)
-	require.Len(t, sl, 1, "expected 1 sector")
-	require.Equal(t, CCUpgrade, sl[0], "unexpected sector number")
-	{
-		si, err := client.StateSectorGetInfo(ctx, maddr, CCUpgrade, types.EmptyTSK)
-		require.NoError(t, err)
-		require.NotNil(t, si)
-		require.Less(t, 50000, int(si.Expiration))
-	}
-	client.WaitForSectorActive(ctx, t, CCUpgrade, maddr)
-
-	err = miner.SectorMarkForUpgrade(ctx, sl[0], true)
-	require.NoError(t, err)
-
-	sl, err = miner.SectorsListNonGenesis(ctx)
-	require.NoError(t, err)
-	require.Len(t, sl, 1, "expected 1 sector")
-
-	ss, err := miner.SectorsStatus(ctx, sl[0], false)
-	require.NoError(t, err)
-
-	for i := 0; i < 100; i++ {
-		ss, err = miner.SectorsStatus(ctx, sl[0], false)
-		require.NoError(t, err)
-		if ss.State == api.SectorState(sealing.Proving) {
-			time.Sleep(50 * time.Millisecond)
-			continue
-		}
-
-		require.Equal(t, api.SectorState(sealing.Available), ss.State)
-		break
-	}
-
-	require.NoError(t, miner.SectorAbortUpgrade(ctx, sl[0]))
-
-	for i := 0; i < 100; i++ {
-		ss, err = miner.SectorsStatus(ctx, sl[0], false)
-		require.NoError(t, err)
-		if ss.State == api.SectorState(sealing.Available) {
-			time.Sleep(50 * time.Millisecond)
-			continue
-		}
-
-		require.Equal(t, api.SectorState(sealing.Proving), ss.State)
-		break
-	}
-}
diff --git a/itests/tape_test.go b/itests/tape_test.go
deleted file mode 100644
index e0db4882c31..00000000000
--- a/itests/tape_test.go
+++ /dev/null
@@ -1,71 +0,0 @@
-// stm: #integration
-package itests
-
-import (
-	"context"
-	"testing"
-	"time"
-
-	"github.com/stretchr/testify/require"
-
-	"github.com/filecoin-project/go-state-types/network"
-
-	"github.com/filecoin-project/lotus/api"
-	"github.com/filecoin-project/lotus/build"
-	"github.com/filecoin-project/lotus/itests/kit"
-	sealing "github.com/filecoin-project/lotus/storage/pipeline"
-)
-
-func TestTapeFix(t *testing.T) {
-	//stm: @CHAIN_SYNCER_LOAD_GENESIS_001, @CHAIN_SYNCER_FETCH_TIPSET_001,
-	//stm: @CHAIN_SYNCER_START_001, @CHAIN_SYNCER_SYNC_001, @BLOCKCHAIN_BEACON_VALIDATE_BLOCK_VALUES_01
-	//stm: @CHAIN_SYNCER_COLLECT_CHAIN_001, @CHAIN_SYNCER_COLLECT_HEADERS_001, @CHAIN_SYNCER_VALIDATE_TIPSET_001
-	//stm: @CHAIN_SYNCER_NEW_PEER_HEAD_001, @CHAIN_SYNCER_VALIDATE_MESSAGE_META_001, @CHAIN_SYNCER_STOP_001
-
-	//stm: @CHAIN_INCOMING_HANDLE_INCOMING_BLOCKS_001, @CHAIN_INCOMING_VALIDATE_BLOCK_PUBSUB_001, @CHAIN_INCOMING_VALIDATE_MESSAGE_PUBSUB_001
-	kit.QuietMiningLogs()
-
-	var blocktime = 2 * time.Millisecond
-
-	// The "before" case is disabled, because we need the builder to mock 32 GiB sectors to accurately repro this case
-	// TODO: Make the mock sector size configurable and reenable this
-	// t.Run("before", func(t *testing.T) { testTapeFix(t, b, blocktime, false) })
-	t.Run("after", func(t *testing.T) { testTapeFix(t, blocktime, true) })
-}
-
-func testTapeFix(t *testing.T, blocktime time.Duration, after bool) {
-	ctx, cancel := context.WithCancel(context.Background())
-	defer cancel()
-
-	networkVersion := network.Version4
-	if after {
-		networkVersion = network.Version5
-	}
-
-	_, miner, ens := kit.EnsembleMinimal(t, kit.MockProofs(), kit.GenesisNetworkVersion(networkVersion))
-	ens.InterconnectAll().BeginMining(blocktime)
-
-	sid, err := miner.PledgeSector(ctx)
-	require.NoError(t, err)
-
-	t.Log("All sectors is fsm")
-
-	// If before, we expect the precommit to fail
-	successState := api.SectorState(sealing.CommitFailed)
-	failureState := api.SectorState(sealing.Proving)
-	if after {
-		// otherwise, it should succeed.
-		successState, failureState = failureState, successState
-	}
-
-	for {
-		st, err := miner.SectorsStatus(ctx, sid.Number, false)
-		require.NoError(t, err)
-		if st.State == successState {
-			break
-		}
-		require.NotEqual(t, failureState, st.State)
-		build.Clock.Sleep(100 * time.Millisecond)
-		t.Log("WaitSeal")
-	}
-}
diff --git a/itests/wdpost_test.go b/itests/wdpost_test.go
index c666538668b..2a6fc866ea8 100644
--- a/itests/wdpost_test.go
+++ b/itests/wdpost_test.go
@@ -224,70 +224,6 @@ func testWindowPostUpgrade(t *testing.T, blocktime time.Duration, nSectors int,
 	require.Equal(t, nSectors+kit.DefaultPresealsPerBootstrapMiner-2+1, int(sectors)) // -2 not recovered sectors + 1 just pledged
 }
 
-func TestWindowPostBaseFeeNoBurn(t *testing.T) {
-	//stm: @CHAIN_SYNCER_LOAD_GENESIS_001, @CHAIN_SYNCER_FETCH_TIPSET_001,
-	//stm: @CHAIN_SYNCER_START_001, @CHAIN_SYNCER_SYNC_001, @BLOCKCHAIN_BEACON_VALIDATE_BLOCK_VALUES_01
-	//stm: @CHAIN_SYNCER_COLLECT_CHAIN_001, @CHAIN_SYNCER_COLLECT_HEADERS_001, @CHAIN_SYNCER_VALIDATE_TIPSET_001
-	//stm: @CHAIN_SYNCER_NEW_PEER_HEAD_001, @CHAIN_SYNCER_VALIDATE_MESSAGE_META_001, @CHAIN_SYNCER_STOP_001
-
-	//stm: @CHAIN_INCOMING_HANDLE_INCOMING_BLOCKS_001, @CHAIN_INCOMING_VALIDATE_BLOCK_PUBSUB_001, @CHAIN_INCOMING_VALIDATE_MESSAGE_PUBSUB_001
-	kit.Expensive(t)
-
-	kit.QuietMiningLogs()
-
-	var (
-		blocktime = 2 * time.Millisecond
-		nSectors  = 10
-	)
-
-	ctx, cancel := context.WithCancel(context.Background())
-	defer cancel()
-
-	och := build.UpgradeClausHeight
-	build.UpgradeClausHeight = 0
-	t.Cleanup(func() { build.UpgradeClausHeight = och })
-
-	client, miner, ens := kit.EnsembleMinimal(t, kit.MockProofs(), kit.GenesisNetworkVersion(network.Version9))
-	ens.InterconnectAll().BeginMining(blocktime)
-
-	maddr, err := miner.ActorAddress(ctx)
-	require.NoError(t, err)
-
-	//stm: @CHAIN_STATE_MINER_INFO_001
-	mi, err := client.StateMinerInfo(ctx, maddr, types.EmptyTSK)
-	require.NoError(t, err)
-
-	miner.PledgeSectors(ctx, nSectors, 0, nil)
-	//stm: @CHAIN_STATE_GET_ACTOR_001
-	wact, err := client.StateGetActor(ctx, mi.Worker, types.EmptyTSK)
-	require.NoError(t, err)
-	en := wact.Nonce
-
-	// wait for a new message to be sent from worker address, it will be a PoSt
-
-waitForProof:
-	for {
-		//stm: @CHAIN_STATE_GET_ACTOR_001
-		wact, err := client.StateGetActor(ctx, mi.Worker, types.EmptyTSK)
-		require.NoError(t, err)
-		if wact.Nonce > en {
-			break waitForProof
-		}
-
-		build.Clock.Sleep(blocktime)
-	}
-
-	//stm: @CHAIN_STATE_LIST_MESSAGES_001
-	slm, err := client.StateListMessages(ctx, &api.MessageMatch{To: maddr}, types.EmptyTSK, 0)
-	require.NoError(t, err)
-
-	//stm: @CHAIN_STATE_REPLAY_001
-	pmr, err := client.StateReplay(ctx, types.EmptyTSK, slm[0])
-	require.NoError(t, err)
-
-	require.Equal(t, pmr.GasCost.BaseFeeBurn, big.Zero())
-}
-
 func TestWindowPostBaseFeeBurn(t *testing.T) {
 	//stm: @CHAIN_SYNCER_LOAD_GENESIS_001, @CHAIN_SYNCER_FETCH_TIPSET_001,
 	//stm: @CHAIN_SYNCER_START_001, @CHAIN_SYNCER_SYNC_001, @BLOCKCHAIN_BEACON_VALIDATE_BLOCK_VALUES_01
@@ -345,79 +281,6 @@ waitForProof:
 	require.NotEqual(t, pmr.GasCost.BaseFeeBurn, big.Zero())
 }
 
-// Tests that V1_1 proofs are generated and accepted in nv19, and V1 proofs are accepted
-func TestWindowPostV1P1NV19(t *testing.T) {
-	kit.QuietMiningLogs()
-
-	ctx, cancel := context.WithCancel(context.Background())
-	defer cancel()
-
-	blocktime := 2 * time.Millisecond
-
-	client, miner, ens := kit.EnsembleMinimal(t, kit.GenesisNetworkVersion(network.Version19))
-	ens.InterconnectAll().BeginMining(blocktime)
-
-	maddr, err := miner.ActorAddress(ctx)
-	require.NoError(t, err)
-
-	mi, err := client.StateMinerInfo(ctx, maddr, types.EmptyTSK)
-	require.NoError(t, err)
-
-	wact, err := client.StateGetActor(ctx, mi.Worker, types.EmptyTSK)
-	require.NoError(t, err)
-	en := wact.Nonce
-
-	// wait for a new message to be sent from worker address, it will be a PoSt
-
-waitForProof:
-	for {
-		wact, err := client.StateGetActor(ctx, mi.Worker, types.EmptyTSK)
-		require.NoError(t, err)
-		if wact.Nonce > en {
-			break waitForProof
-		}
-
-		build.Clock.Sleep(blocktime)
-	}
-
-	slm, err := client.StateListMessages(ctx, &api.MessageMatch{To: maddr}, types.EmptyTSK, 0)
-	require.NoError(t, err)
-
-	pmr, err := client.StateSearchMsg(ctx, types.EmptyTSK, slm[0], -1, false)
-	require.NoError(t, err)
-
-	inclTs, err := client.ChainGetTipSet(ctx, pmr.TipSet)
-	require.NoError(t, err)
-
-	inclTsParents, err := client.ChainGetTipSet(ctx, inclTs.Parents())
-	require.NoError(t, err)
-
-	nv, err := client.StateNetworkVersion(ctx, pmr.TipSet)
-	require.NoError(t, err)
-	require.Equal(t, network.Version19, nv)
-
-	require.True(t, pmr.Receipt.ExitCode.IsSuccess())
-
-	slmsg, err := client.ChainGetMessage(ctx, slm[0])
-	require.NoError(t, err)
-
-	var params miner11.SubmitWindowedPoStParams
-	require.NoError(t, params.UnmarshalCBOR(bytes.NewBuffer(slmsg.Params)))
-	require.Equal(t, abi.RegisteredPoStProof_StackedDrgWindow2KiBV1_1, params.Proofs[0].PoStProof)
-
-	// "Turn" this into a V1 proof -- the proof will be invalid, but won't be validated, and so the call should succeed
-	params.Proofs[0].PoStProof = abi.RegisteredPoStProof_StackedDrgWindow2KiBV1
-	v1PostParams := new(bytes.Buffer)
-	require.NoError(t, params.MarshalCBOR(v1PostParams))
-
-	slmsg.Params = v1PostParams.Bytes()
-
-	// Simulate call on inclTsParents's parents, so that the partition isn't already proven
-	call, err := client.StateCall(ctx, slmsg, inclTsParents.Parents())
-	require.NoError(t, err)
-	require.True(t, call.MsgRct.ExitCode.IsSuccess())
-}
-
 // Tests that V1_1 proofs are generated and accepted in nv20, and that V1 proofs are NOT
 func TestWindowPostV1P1NV20(t *testing.T) {
 	kit.QuietMiningLogs()
diff --git a/markets/storageadapter/ondealsectorcommitted.go b/markets/storageadapter/ondealsectorcommitted.go
index a8b22c62a37..54ddb73b334 100644
--- a/markets/storageadapter/ondealsectorcommitted.go
+++ b/markets/storageadapter/ondealsectorcommitted.go
@@ -13,6 +13,7 @@ import (
 	"github.com/filecoin-project/go-fil-markets/storagemarket"
 	"github.com/filecoin-project/go-state-types/abi"
 	"github.com/filecoin-project/go-state-types/builtin"
+	miner2 "github.com/filecoin-project/go-state-types/builtin/v11/miner"
 	"github.com/filecoin-project/go-state-types/builtin/v8/miner"
 	"github.com/filecoin-project/go-state-types/builtin/v9/market"
 
@@ -107,7 +108,10 @@ func (mgr *SectorCommittedManager) OnDealSectorPreCommitted(ctx context.Context,
 
 	// Watch for a pre-commit message to the provider.
 	matchEvent := func(msg *types.Message) (bool, error) {
-		matched := msg.To == provider && (msg.Method == builtin.MethodsMiner.PreCommitSector || msg.Method == builtin.MethodsMiner.PreCommitSectorBatch || msg.Method == builtin.MethodsMiner.ProveReplicaUpdates)
+		matched := msg.To == provider && (msg.Method == builtin.MethodsMiner.PreCommitSector ||
+			msg.Method == builtin.MethodsMiner.PreCommitSectorBatch ||
+			msg.Method == builtin.MethodsMiner.PreCommitSectorBatch2 ||
+			msg.Method == builtin.MethodsMiner.ProveReplicaUpdates)
 		return matched, nil
 	}
 
@@ -333,6 +337,21 @@ func dealSectorInPreCommitMsg(msg *types.Message, res pipeline.CurrentDealInfo)
 			return nil, xerrors.Errorf("unmarshal pre commit: %w", err)
 		}
 
+		for _, precommit := range params.Sectors {
+			// Check through the deal IDs associated with this message
+			for _, did := range precommit.DealIDs {
+				if did == res.DealID {
+					// Found the deal ID in this message. Callback with the sector ID.
+					return &precommit.SectorNumber, nil
+				}
+			}
+		}
+	case builtin.MethodsMiner.PreCommitSectorBatch2:
+		var params miner2.PreCommitSectorBatchParams2
+		if err := params.UnmarshalCBOR(bytes.NewReader(msg.Params)); err != nil {
+			return nil, xerrors.Errorf("unmarshal pre commit: %w", err)
+		}
+
 		for _, precommit := range params.Sectors {
 			// Check through the deal IDs associated with this message
 			for _, did := range precommit.DealIDs {
diff --git a/markets/storageadapter/provider.go b/markets/storageadapter/provider.go
index a5022613b6b..bdfce6f55af 100644
--- a/markets/storageadapter/provider.go
+++ b/markets/storageadapter/provider.go
@@ -186,7 +186,10 @@ func (n *ProviderNodeAdapter) GetProofType(ctx context.Context, maddr address.Ad
 		return 0, err
 	}
 
-	return miner.PreferredSealProofTypeFromWindowPoStType(nver, mi.WindowPoStProofType)
+	// false because this variance is not consumed.
+	const configWantSynthetic = false
+
+	return miner.PreferredSealProofTypeFromWindowPoStType(nver, mi.WindowPoStProofType, configWantSynthetic)
 }
 
 func (n *ProviderNodeAdapter) SignBytes(ctx context.Context, signer address.Address, b []byte) (*crypto.Signature, error) {
diff --git a/miner/miner.go b/miner/miner.go
index 9281854d7c2..63862ba0f59 100644
--- a/miner/miner.go
+++ b/miner/miner.go
@@ -10,7 +10,7 @@ import (
 	"sync"
 	"time"
 
-	lru "github.com/hashicorp/golang-lru/v2"
+	"github.com/hashicorp/golang-lru/arc/v2"
 	logging "github.com/ipfs/go-log/v2"
 	"go.opencensus.io/trace"
 	"golang.org/x/xerrors"
@@ -61,7 +61,7 @@ func randTimeOffset(width time.Duration) time.Duration {
 // NewMiner instantiates a miner with a concrete WinningPoStProver and a miner
 // address (which can be different from the worker's address).
 func NewMiner(api v1api.FullNode, epp gen.WinningPoStProver, addr address.Address, sf *slashfilter.SlashFilter, j journal.Journal) *Miner {
-	arc, err := lru.NewARC[abi.ChainEpoch, bool](10000)
+	arc, err := arc.NewARC[abi.ChainEpoch, bool](10000)
 	if err != nil {
 		panic(err)
 	}
@@ -122,7 +122,7 @@ type Miner struct {
 	// minedBlockHeights is a safeguard that caches the last heights we mined.
 	// It is consulted before publishing a newly mined block, for a sanity check
 	// intended to avoid slashings in case of a bug.
-	minedBlockHeights *lru.ARCCache[abi.ChainEpoch, bool]
+	minedBlockHeights *arc.ARCCache[abi.ChainEpoch, bool]
 
 	evtTypes [1]journal.EventType
 	journal  journal.Journal
@@ -324,7 +324,7 @@ minerLoop:
 					"block-time", btime, "time", build.Clock.Now(), "difference", build.Clock.Since(btime))
 			}
 
-			if os.Getenv("LOTUS_MINER_NO_SLASHFILTER") != "_yes_i_know_i_can_and_probably_will_lose_all_my_fil_and_power_" {
+			if os.Getenv("LOTUS_MINER_NO_SLASHFILTER") != "_yes_i_know_i_can_and_probably_will_lose_all_my_fil_and_power_" && !build.IsNearUpgrade(base.TipSet.Height(), build.UpgradeWatermelonFixHeight) {
 				witness, fault, err := m.sf.MinedBlock(ctx, b.Header, base.TipSet.Height()+base.NullRounds)
 				if err != nil {
 					log.Errorf("<!!> SLASH FILTER ERRORED: %s", err)
@@ -531,7 +531,7 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (minedBlock *type
 		return nil, err
 	}
 
-	rand, err := lrand.DrawRandomness(rbase.Data, crypto.DomainSeparationTag_WinningPoStChallengeSeed, round, buf.Bytes())
+	rand, err := lrand.DrawRandomnessFromBase(rbase.Data, crypto.DomainSeparationTag_WinningPoStChallengeSeed, round, buf.Bytes())
 	if err != nil {
 		err = xerrors.Errorf("failed to get randomness for winning post: %w", err)
 		return nil, err
@@ -600,7 +600,7 @@ func (m *Miner) computeTicket(ctx context.Context, brand *types.BeaconEntry, bas
 		buf.Write(base.TipSet.MinTicket().VRFProof)
 	}
 
-	input, err := lrand.DrawRandomness(brand.Data, crypto.DomainSeparationTag_TicketProduction, round-build.TicketRandomnessLookback, buf.Bytes())
+	input, err := lrand.DrawRandomnessFromBase(brand.Data, crypto.DomainSeparationTag_TicketProduction, round-build.TicketRandomnessLookback, buf.Bytes())
 	if err != nil {
 		return nil, err
 	}
diff --git a/miner/testminer.go b/miner/testminer.go
index deda89f420a..f1d11bae0a6 100644
--- a/miner/testminer.go
+++ b/miner/testminer.go
@@ -3,7 +3,7 @@ package miner
 import (
 	"context"
 
-	lru "github.com/hashicorp/golang-lru/v2"
+	"github.com/hashicorp/golang-lru/arc/v2"
 	ds "github.com/ipfs/go-datastore"
 
 	"github.com/filecoin-project/go-address"
@@ -22,7 +22,7 @@ type MineReq struct {
 
 func NewTestMiner(nextCh <-chan MineReq, addr address.Address) func(v1api.FullNode, gen.WinningPoStProver) *Miner {
 	return func(api v1api.FullNode, epp gen.WinningPoStProver) *Miner {
-		arc, err := lru.NewARC[abi.ChainEpoch, bool](10000)
+		arc, err := arc.NewARC[abi.ChainEpoch, bool](10000)
 		if err != nil {
 			panic(err)
 		}
diff --git a/node/bundle/bundle.go b/node/bundle/bundle.go
index a55cad9f124..716c9043bb6 100644
--- a/node/bundle/bundle.go
+++ b/node/bundle/bundle.go
@@ -69,7 +69,7 @@ func LoadBundles(ctx context.Context, bs blockstore.Blockstore, versions ...acto
 		)
 		if path, ok := build.BundleOverrides[av]; ok {
 			root, err = LoadBundleFromFile(ctx, bs, path)
-		} else if embedded, ok := build.GetEmbeddedBuiltinActorsBundle(av); ok {
+		} else if embedded, ok := build.GetEmbeddedBuiltinActorsBundle(av, build.NetworkBundle); ok {
 			root, err = LoadBundle(ctx, bs, bytes.NewReader(embedded))
 		} else {
 			err = xerrors.Errorf("bundle for actors version v%d not found", av)
diff --git a/node/config/def.go b/node/config/def.go
index 42b035c66ae..dd36803a0c6 100644
--- a/node/config/def.go
+++ b/node/config/def.go
@@ -10,6 +10,7 @@ import (
 
 	"github.com/filecoin-project/go-state-types/abi"
 	"github.com/filecoin-project/go-state-types/big"
+	"github.com/filecoin-project/go-state-types/network"
 	miner5 "github.com/filecoin-project/specs-actors/v5/actors/builtin/miner"
 
 	"github.com/filecoin-project/lotus/chain/actors/builtin"
@@ -122,6 +123,8 @@ func DefaultFullNode() *FullNode {
 }
 
 func DefaultStorageMiner() *StorageMiner {
+	// TODO: Should we increase this to nv21, which would push it to 3.5 years?
+	maxSectorExtentsion, _ := policy.GetMaxSectorExpirationExtension(network.Version20)
 	cfg := &StorageMiner{
 		Common: defCommon(),
 
@@ -138,13 +141,12 @@ func DefaultStorageMiner() *StorageMiner {
 			AvailableBalanceBuffer:     types.FIL(big.Zero()),
 			DisableCollateralFallback:  false,
 
-			BatchPreCommits:    true,
 			MaxPreCommitBatch:  miner5.PreCommitSectorBatchMaxSize, // up to 256 sectors
 			PreCommitBatchWait: Duration(24 * time.Hour),           // this should be less than 31.5 hours, which is the expiration of a precommit ticket
 			// XXX snap deals wait deals slack if first
 			PreCommitBatchSlack: Duration(3 * time.Hour), // time buffer for forceful batch submission before sectors/deals in batch would start expiring, higher value will lower the chances for message fail due to expiration
 
-			CommittedCapacitySectorLifetime: Duration(builtin.EpochDurationSeconds * uint64(policy.GetMaxSectorExpirationExtension()) * uint64(time.Second)),
+			CommittedCapacitySectorLifetime: Duration(builtin.EpochDurationSeconds * uint64(maxSectorExtentsion) * uint64(time.Second)),
 
 			AggregateCommits: true,
 			MinCommitBatch:   miner5.MinAggregatedSectors, // per FIP13, we must have at least four proofs to aggregate, where 4 is the cross over point where aggregation wins out on single provecommit gas costs
@@ -159,6 +161,7 @@ func DefaultStorageMiner() *StorageMiner {
 			TerminateBatchMax:                      100,
 			TerminateBatchWait:                     Duration(5 * time.Minute),
 			MaxSectorProveCommitsSubmittedPerEpoch: 20,
+			UseSyntheticPoRep:                      false,
 		},
 
 		Proving: ProvingConfig{
diff --git a/node/config/doc_gen.go b/node/config/doc_gen.go
index 28f713fc5fc..26eaef0d6df 100644
--- a/node/config/doc_gen.go
+++ b/node/config/doc_gen.go
@@ -853,13 +853,10 @@ After changing this option, confirm that the new value works in your setup by in
 			Name: "MaxPartitionsPerPoStMessage",
 			Type: "int",
 
-			Comment: `Maximum number of partitions to prove in a single SubmitWindowPoSt messace. 0 = network limit (10 in nv16)
+			Comment: `Maximum number of partitions to prove in a single SubmitWindowPoSt messace. 0 = network limit (3 in nv21)
 
 A single partition may contain up to 2349 32GiB sectors, or 2300 64GiB sectors.
-
-The maximum number of sectors which can be proven in a single PoSt message is 25000 in network version 16, which
-means that a single message can prove at most 10 partitions
-
+//
 Note that setting this value lower may result in less efficient gas use - more messages will be sent,
 to prove each deadline, resulting in more total gas use (but each message will have lower gas limit)
 
@@ -1150,7 +1147,7 @@ required to have expiration of at least the soonest-ending deal`,
 
 			Comment: `CommittedCapacitySectorLifetime is the duration a Committed Capacity (CC) sector will
 live before it must be extended or converted into sector containing deals before it is
-terminated. Value must be between 180-540 days inclusive`,
+terminated. Value must be between 180-1278 days (1278 in nv21, 540 before nv21).`,
 		},
 		{
 			Name: "WaitDealsDelay",
@@ -1204,12 +1201,6 @@ This is useful for forcing all deals to be assigned as snap deals to sectors mar
 
 			Comment: `Don't send collateral with messages even if there is no available balance in the miner actor`,
 		},
-		{
-			Name: "BatchPreCommits",
-			Type: "bool",
-
-			Comment: `enable / disable precommit batching (takes effect after nv13)`,
-		},
 		{
 			Name: "MaxPreCommitBatch",
 			Type: "int",
@@ -1263,7 +1254,8 @@ This is useful for forcing all deals to be assigned as snap deals to sectors mar
 			Type: "types.FIL",
 
 			Comment: `network BaseFee below which to stop doing precommit batching, instead
-sending precommit messages to the chain individually`,
+sending precommit messages to the chain individually. When the basefee is
+below this threshold, precommit messages will get sent out immediately.`,
 		},
 		{
 			Name: "AggregateAboveBaseFee",
@@ -1300,6 +1292,12 @@ Submitting a smaller number of prove commits per epoch would reduce the possibil
 
 			Comment: ``,
 		},
+		{
+			Name: "UseSyntheticPoRep",
+			Type: "bool",
+
+			Comment: `UseSyntheticPoRep, when set to true, will reduce the amount of cache data held on disk after the completion of PreCommit 2 to 11GiB.`,
+		},
 	},
 	"Splitstore": []DocField{
 		{
diff --git a/node/config/types.go b/node/config/types.go
index cfd7cf084bb..908140ed32d 100644
--- a/node/config/types.go
+++ b/node/config/types.go
@@ -290,13 +290,10 @@ type ProvingConfig struct {
 	// 'lotus-miner proving compute window-post 0'
 	DisableWDPoStPreChecks bool
 
-	// Maximum number of partitions to prove in a single SubmitWindowPoSt messace. 0 = network limit (10 in nv16)
+	// Maximum number of partitions to prove in a single SubmitWindowPoSt messace. 0 = network limit (3 in nv21)
 	//
 	// A single partition may contain up to 2349 32GiB sectors, or 2300 64GiB sectors.
-	//
-	// The maximum number of sectors which can be proven in a single PoSt message is 25000 in network version 16, which
-	// means that a single message can prove at most 10 partitions
-	//
+	//	//
 	// Note that setting this value lower may result in less efficient gas use - more messages will be sent,
 	// to prove each deadline, resulting in more total gas use (but each message will have lower gas limit)
 	//
@@ -358,7 +355,7 @@ type SealingConfig struct {
 
 	// CommittedCapacitySectorLifetime is the duration a Committed Capacity (CC) sector will
 	// live before it must be extended or converted into sector containing deals before it is
-	// terminated. Value must be between 180-540 days inclusive
+	// terminated. Value must be between 180-1278 days (1278 in nv21, 540 before nv21).
 	CommittedCapacitySectorLifetime Duration
 
 	// Period of time that a newly created sector will wait for more deals to be packed in to before it starts to seal.
@@ -387,8 +384,6 @@ type SealingConfig struct {
 	// Don't send collateral with messages even if there is no available balance in the miner actor
 	DisableCollateralFallback bool
 
-	// enable / disable precommit batching (takes effect after nv13)
-	BatchPreCommits bool
 	// maximum precommit batch size - batches will be sent immediately above this size
 	MaxPreCommitBatch int
 	// how long to wait before submitting a batch after crossing the minimum batch size
@@ -408,7 +403,8 @@ type SealingConfig struct {
 	CommitBatchSlack Duration
 
 	// network BaseFee below which to stop doing precommit batching, instead
-	// sending precommit messages to the chain individually
+	// sending precommit messages to the chain individually. When the basefee is
+	// below this threshold, precommit messages will get sent out immediately.
 	BatchPreCommitAboveBaseFee types.FIL
 
 	// network BaseFee below which to stop doing commit aggregation, instead
@@ -430,6 +426,9 @@ type SealingConfig struct {
 	// todo TargetSealingSectors uint64
 
 	// todo TargetSectors - stop auto-pleding new sectors after this many sectors are sealed, default CC upgrade for deals sectors if above
+
+	// UseSyntheticPoRep, when set to true, will reduce the amount of cache data held on disk after the completion of PreCommit 2 to 11GiB.
+	UseSyntheticPoRep bool
 }
 
 type SealerConfig struct {
diff --git a/node/hello/cbor_gen.go b/node/hello/cbor_gen.go
index 5b0697f556c..78e950f6f6e 100644
--- a/node/hello/cbor_gen.go
+++ b/node/hello/cbor_gen.go
@@ -43,9 +43,11 @@ func (t *HelloMessage) MarshalCBOR(w io.Writer) error {
 		return err
 	}
 	for _, v := range t.HeaviestTipSet {
-		if err := cbg.WriteCid(w, v); err != nil {
-			return xerrors.Errorf("failed writing cid field t.HeaviestTipSet: %w", err)
+
+		if err := cbg.WriteCid(cw, v); err != nil {
+			return xerrors.Errorf("failed to write cid field v: %w", err)
 		}
+
 	}
 
 	// t.HeaviestTipSetHeight (abi.ChainEpoch) (int64)
@@ -116,12 +118,25 @@ func (t *HelloMessage) UnmarshalCBOR(r io.Reader) (err error) {
 	}
 
 	for i := 0; i < int(extra); i++ {
+		{
+			var maj byte
+			var extra uint64
+			var err error
+			_ = maj
+			_ = extra
+			_ = err
 
-		c, err := cbg.ReadCid(cr)
-		if err != nil {
-			return xerrors.Errorf("reading cid field t.HeaviestTipSet failed: %w", err)
+			{
+
+				c, err := cbg.ReadCid(cr)
+				if err != nil {
+					return xerrors.Errorf("failed to read cid field t.HeaviestTipSet[i]: %w", err)
+				}
+
+				t.HeaviestTipSet[i] = c
+
+			}
 		}
-		t.HeaviestTipSet[i] = c
 	}
 
 	// t.HeaviestTipSetHeight (abi.ChainEpoch) (int64)
diff --git a/node/impl/client/client.go b/node/impl/client/client.go
index 3ed4a01a794..73ffeabe302 100644
--- a/node/impl/client/client.go
+++ b/node/impl/client/client.go
@@ -197,7 +197,7 @@ func (a *API) dealStarter(ctx context.Context, params *api.StartDealParams, isSt
 		return nil, xerrors.Errorf("failed to get network version: %w", err)
 	}
 
-	st, err := miner.PreferredSealProofTypeFromWindowPoStType(networkVersion, mi.WindowPoStProofType)
+	st, err := miner.PreferredSealProofTypeFromWindowPoStType(networkVersion, mi.WindowPoStProofType, false)
 	if err != nil {
 		return nil, xerrors.Errorf("failed to get seal proof type: %w", err)
 	}
diff --git a/node/impl/full/eth.go b/node/impl/full/eth.go
index 424756f8140..f4d9d837172 100644
--- a/node/impl/full/eth.go
+++ b/node/impl/full/eth.go
@@ -825,10 +825,11 @@ func (a *EthModule) EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (eth
 		}
 
 		rewards, totalGasUsed := calculateRewardsAndGasUsed(rewardPercentiles, txGasRewards)
+		maxGas := build.BlockGasLimit * int64(len(ts.Blocks()))
 
 		// arrays should be reversed at the end
 		baseFeeArray = append(baseFeeArray, ethtypes.EthBigInt(basefee))
-		gasUsedRatioArray = append(gasUsedRatioArray, float64(totalGasUsed)/float64(build.BlockGasLimit))
+		gasUsedRatioArray = append(gasUsedRatioArray, float64(totalGasUsed)/float64(maxGas))
 		rewardsArray = append(rewardsArray, rewards)
 		oldestBlkHeight = uint64(ts.Height())
 		blocksIncluded++
@@ -2277,7 +2278,13 @@ func newEthTxReceipt(ctx context.Context, tx ethtypes.EthTx, lookup *api.MsgLook
 		return api.EthTxReceipt{}, xerrors.Errorf("failed to lookup tipset %s when constructing the eth txn receipt: %w", lookup.TipSet, err)
 	}
 
-	baseFee := ts.Blocks()[0].ParentBaseFee
+	// The tx is located in the parent tipset
+	parentTs, err := cs.LoadTipSet(ctx, ts.Parents())
+	if err != nil {
+		return api.EthTxReceipt{}, xerrors.Errorf("failed to lookup tipset %s when constructing the eth txn receipt: %w", ts.Parents(), err)
+	}
+
+	baseFee := parentTs.Blocks()[0].ParentBaseFee
 	gasOutputs := vm.ComputeGasOutputs(lookup.Receipt.GasUsed, int64(tx.Gas), baseFee, big.Int(tx.MaxFeePerGas), big.Int(tx.MaxPriorityFeePerGas), true)
 	totalSpent := big.Sum(gasOutputs.BaseFeeBurn, gasOutputs.MinerTip, gasOutputs.OverEstimationBurn)
 
diff --git a/node/impl/full/state.go b/node/impl/full/state.go
index 78f45062600..b392083e175 100644
--- a/node/impl/full/state.go
+++ b/node/impl/full/state.go
@@ -6,6 +6,7 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
+	"math"
 	"strconv"
 
 	"github.com/ipfs/go-cid"
@@ -19,8 +20,7 @@ import (
 	"github.com/filecoin-project/go-state-types/abi"
 	actorstypes "github.com/filecoin-project/go-state-types/actors"
 	"github.com/filecoin-project/go-state-types/big"
-	minertypes "github.com/filecoin-project/go-state-types/builtin/v9/miner"
-	verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
+	market12 "github.com/filecoin-project/go-state-types/builtin/v12/market"
 	"github.com/filecoin-project/go-state-types/cbor"
 	"github.com/filecoin-project/go-state-types/crypto"
 	"github.com/filecoin-project/go-state-types/dline"
@@ -794,7 +794,7 @@ func (a *StateAPI) StateGetAllocationForPendingDeal(ctx context.Context, dealId
 	if err != nil {
 		return nil, err
 	}
-	if allocationId == verifregtypes.NoAllocationID {
+	if allocationId == verifreg.NoAllocationID {
 		return nil, nil
 	}
 
@@ -914,32 +914,31 @@ func (a *StateAPI) StateComputeDataCID(ctx context.Context, maddr address.Addres
 		return cid.Cid{}, err
 	}
 
-	var ccparams []byte
 	if nv < network.Version13 {
-		ccparams, err = actors.SerializeParams(&market2.ComputeDataCommitmentParams{
-			DealIDs:    deals,
-			SectorType: sectorType,
-		})
+		return a.stateComputeDataCIDv1(ctx, maddr, sectorType, deals, tsk)
+	} else if nv < network.Version21 {
+		return a.stateComputeDataCIDv2(ctx, maddr, sectorType, deals, tsk)
 	} else {
-		ccparams, err = actors.SerializeParams(&market5.ComputeDataCommitmentParams{
-			Inputs: []*market5.SectorDataSpec{
-				{
-					DealIDs:    deals,
-					SectorType: sectorType,
-				},
-			},
-		})
+		return a.stateComputeDataCIDv3(ctx, maddr, sectorType, deals, tsk)
 	}
+}
+
+func (a *StateAPI) stateComputeDataCIDv1(ctx context.Context, maddr address.Address, sectorType abi.RegisteredSealProof, deals []abi.DealID, tsk types.TipSetKey) (cid.Cid, error) {
+	var err error
+	ccparams, err := actors.SerializeParams(&market2.ComputeDataCommitmentParams{
+		DealIDs:    deals,
+		SectorType: sectorType,
+	})
 
 	if err != nil {
 		return cid.Undef, xerrors.Errorf("computing params for ComputeDataCommitment: %w", err)
 	}
-
 	ccmt := &types.Message{
-		To:     market.Address,
-		From:   maddr,
-		Value:  types.NewInt(0),
-		Method: market.Methods.ComputeDataCommitment,
+		To:    market.Address,
+		From:  maddr,
+		Value: types.NewInt(0),
+		// Hard coded, because the method has since been deprecated
+		Method: 8,
 		Params: ccparams,
 	}
 	r, err := a.StateCall(ctx, ccmt, tsk)
@@ -950,13 +949,42 @@ func (a *StateAPI) StateComputeDataCID(ctx context.Context, maddr address.Addres
 		return cid.Undef, xerrors.Errorf("receipt for ComputeDataCommitment had exit code %d", r.MsgRct.ExitCode)
 	}
 
-	if nv < network.Version13 {
-		var c cbg.CborCid
-		if err := c.UnmarshalCBOR(bytes.NewReader(r.MsgRct.Return)); err != nil {
-			return cid.Undef, xerrors.Errorf("failed to unmarshal CBOR to CborCid: %w", err)
-		}
+	var c cbg.CborCid
+	if err := c.UnmarshalCBOR(bytes.NewReader(r.MsgRct.Return)); err != nil {
+		return cid.Undef, xerrors.Errorf("failed to unmarshal CBOR to CborCid: %w", err)
+	}
 
-		return cid.Cid(c), nil
+	return cid.Cid(c), nil
+}
+
+func (a *StateAPI) stateComputeDataCIDv2(ctx context.Context, maddr address.Address, sectorType abi.RegisteredSealProof, deals []abi.DealID, tsk types.TipSetKey) (cid.Cid, error) {
+	var err error
+	ccparams, err := actors.SerializeParams(&market5.ComputeDataCommitmentParams{
+		Inputs: []*market5.SectorDataSpec{
+			{
+				DealIDs:    deals,
+				SectorType: sectorType,
+			},
+		},
+	})
+
+	if err != nil {
+		return cid.Undef, xerrors.Errorf("computing params for ComputeDataCommitment: %w", err)
+	}
+	ccmt := &types.Message{
+		To:    market.Address,
+		From:  maddr,
+		Value: types.NewInt(0),
+		// Hard coded, because the method has since been deprecated
+		Method: 8,
+		Params: ccparams,
+	}
+	r, err := a.StateCall(ctx, ccmt, tsk)
+	if err != nil {
+		return cid.Undef, xerrors.Errorf("calling ComputeDataCommitment: %w", err)
+	}
+	if r.MsgRct.ExitCode != 0 {
+		return cid.Undef, xerrors.Errorf("receipt for ComputeDataCommitment had exit code %d", r.MsgRct.ExitCode)
 	}
 
 	var cr market5.ComputeDataCommitmentReturn
@@ -971,6 +999,52 @@ func (a *StateAPI) StateComputeDataCID(ctx context.Context, maddr address.Addres
 	return cid.Cid(cr.CommDs[0]), nil
 }
 
+func (a *StateAPI) stateComputeDataCIDv3(ctx context.Context, maddr address.Address, sectorType abi.RegisteredSealProof, deals []abi.DealID, tsk types.TipSetKey) (cid.Cid, error) {
+	if len(deals) == 0 {
+		return cid.Undef, nil
+	}
+
+	var err error
+	ccparams, err := actors.SerializeParams(&market12.VerifyDealsForActivationParams{
+		Sectors: []market12.SectorDeals{{
+			SectorType:   sectorType,
+			SectorExpiry: math.MaxInt64,
+			DealIDs:      deals,
+		}},
+	})
+
+	if err != nil {
+		return cid.Undef, xerrors.Errorf("computing params for VerifyDealsForActivation: %w", err)
+	}
+	ccmt := &types.Message{
+		To:     market.Address,
+		From:   maddr,
+		Value:  types.NewInt(0),
+		Method: market.Methods.VerifyDealsForActivation,
+		Params: ccparams,
+	}
+	r, err := a.StateCall(ctx, ccmt, tsk)
+	if err != nil {
+		return cid.Undef, xerrors.Errorf("calling VerifyDealsForActivation: %w", err)
+	}
+	if r.MsgRct.ExitCode != 0 {
+		return cid.Undef, xerrors.Errorf("receipt for VerifyDealsForActivation had exit code %d", r.MsgRct.ExitCode)
+	}
+
+	var cr market12.VerifyDealsForActivationReturn
+	if err := cr.UnmarshalCBOR(bytes.NewReader(r.MsgRct.Return)); err != nil {
+		return cid.Undef, xerrors.Errorf("failed to unmarshal CBOR to VerifyDealsForActivationReturn: %w", err)
+	}
+	if len(cr.UnsealedCIDs) != 1 {
+		return cid.Undef, xerrors.Errorf("Sectors output must have 1 entry")
+	}
+	ucid := cr.UnsealedCIDs[0]
+	if ucid == nil {
+		return cid.Undef, xerrors.Errorf("computed data CID is nil")
+	}
+	return *ucid, nil
+}
+
 func (a *StateAPI) StateChangedActors(ctx context.Context, old cid.Cid, new cid.Cid) (map[string]types.Actor, error) {
 	store := a.Chain.ActorStore(ctx)
 
@@ -1040,7 +1114,7 @@ func (a *StateAPI) StateMinerAllocated(ctx context.Context, addr address.Address
 	return mas.GetAllocatedSectors()
 }
 
-func (a *StateAPI) StateSectorPreCommitInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*minertypes.SectorPreCommitOnChainInfo, error) {
+func (a *StateAPI) StateSectorPreCommitInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorPreCommitOnChainInfo, error) {
 	ts, err := a.Chain.GetTipSetFromKey(ctx, tsk)
 	if err != nil {
 		return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
@@ -1315,7 +1389,7 @@ func (m *StateModule) MsigGetPending(ctx context.Context, addr address.Address,
 var initialPledgeNum = types.NewInt(110)
 var initialPledgeDen = types.NewInt(100)
 
-func (a *StateAPI) StateMinerPreCommitDepositForPower(ctx context.Context, maddr address.Address, pci minertypes.SectorPreCommitInfo, tsk types.TipSetKey) (types.BigInt, error) {
+func (a *StateAPI) StateMinerPreCommitDepositForPower(ctx context.Context, maddr address.Address, pci miner.SectorPreCommitInfo, tsk types.TipSetKey) (types.BigInt, error) {
 	ts, err := a.Chain.GetTipSetFromKey(ctx, tsk)
 	if err != nil {
 		return types.EmptyInt, xerrors.Errorf("loading tipset %s: %w", tsk, err)
@@ -1347,7 +1421,7 @@ func (a *StateAPI) StateMinerPreCommitDepositForPower(ctx context.Context, maddr
 			sectorWeight = builtin.QAPowerForWeight(ssize, duration, w, vw)
 		}
 	} else {
-		sectorWeight = minertypes.QAPowerMax(ssize)
+		sectorWeight = miner.QAPowerMax(ssize)
 	}
 
 	var powerSmoothed builtin.FilterEstimate
@@ -1379,7 +1453,7 @@ func (a *StateAPI) StateMinerPreCommitDepositForPower(ctx context.Context, maddr
 	return types.BigDiv(types.BigMul(deposit, initialPledgeNum), initialPledgeDen), nil
 }
 
-func (a *StateAPI) StateMinerInitialPledgeCollateral(ctx context.Context, maddr address.Address, pci minertypes.SectorPreCommitInfo, tsk types.TipSetKey) (types.BigInt, error) {
+func (a *StateAPI) StateMinerInitialPledgeCollateral(ctx context.Context, maddr address.Address, pci miner.SectorPreCommitInfo, tsk types.TipSetKey) (types.BigInt, error) {
 	// TODO: this repeats a lot of the previous function. Fix that.
 	ts, err := a.Chain.GetTipSetFromKey(ctx, tsk)
 	if err != nil {
@@ -1752,7 +1826,34 @@ func (a *StateAPI) StateGetRandomnessFromTickets(ctx context.Context, personaliz
 
 func (a *StateAPI) StateGetRandomnessFromBeacon(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte, tsk types.TipSetKey) (abi.Randomness, error) {
 	return a.StateManager.GetRandomnessFromBeacon(ctx, personalization, randEpoch, entropy, tsk)
+}
+
+func (a *StateAPI) StateGetRandomnessDigestFromTickets(ctx context.Context, randEpoch abi.ChainEpoch, tsk types.TipSetKey) (abi.Randomness, error) {
+	ts, err := a.Chain.GetTipSetFromKey(ctx, tsk)
+	if err != nil {
+		return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
+	}
+
+	ret, err := a.StateManager.GetRandomnessDigestFromTickets(ctx, randEpoch, ts.Key())
+	if err != nil {
+		return nil, xerrors.Errorf("failed to get randomness digest from tickets: %w", err)
+	}
+
+	return ret[:], nil
+}
+
+func (a *StateAPI) StateGetRandomnessDigestFromBeacon(ctx context.Context, randEpoch abi.ChainEpoch, tsk types.TipSetKey) (abi.Randomness, error) {
+	ts, err := a.Chain.GetTipSetFromKey(ctx, tsk)
+	if err != nil {
+		return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
+	}
+
+	ret, err := a.StateManager.GetRandomnessDigestFromBeacon(ctx, randEpoch, ts.Key())
+	if err != nil {
+		return nil, xerrors.Errorf("failed to get randomness digest from tickets: %w", err)
+	}
 
+	return ret[:], nil
 }
 
 func (a *StateAPI) StateGetBeaconEntry(ctx context.Context, epoch abi.ChainEpoch) (*types.BeaconEntry, error) {
@@ -1811,6 +1912,7 @@ func (a *StateAPI) StateGetNetworkParams(ctx context.Context) (*api.NetworkParam
 			UpgradeHyggeHeight:       build.UpgradeHyggeHeight,
 			UpgradeLightningHeight:   build.UpgradeLightningHeight,
 			UpgradeThunderHeight:     build.UpgradeThunderHeight,
+			UpgradeWatermelonHeight:  build.UpgradeWatermelonHeight,
 		},
 	}, nil
 }
diff --git a/node/impl/full/sync.go b/node/impl/full/sync.go
index 223f5c29e62..4bf44363ce0 100644
--- a/node/impl/full/sync.go
+++ b/node/impl/full/sync.go
@@ -57,7 +57,7 @@ func (a *SyncAPI) SyncSubmitBlock(ctx context.Context, blk *types.BlockMsg) erro
 		return xerrors.Errorf("loading parent block: %w", err)
 	}
 
-	if a.SlashFilter != nil && os.Getenv("LOTUS_NO_SLASHFILTER") != "_yes_i_know_i_can_and_probably_will_lose_all_my_fil_and_power_" {
+	if a.SlashFilter != nil && os.Getenv("LOTUS_NO_SLASHFILTER") != "_yes_i_know_i_can_and_probably_will_lose_all_my_fil_and_power_" && !build.IsNearUpgrade(blk.Header.Height, build.UpgradeWatermelonFixHeight) {
 		witness, fault, err := a.SlashFilter.MinedBlock(ctx, blk.Header, parent.Height)
 		if err != nil {
 			log.Errorf("<!!> SLASH FILTER ERRORED: %s", err)
diff --git a/node/impl/storminer.go b/node/impl/storminer.go
index e4fa41c788a..6f460eccdfb 100644
--- a/node/impl/storminer.go
+++ b/node/impl/storminer.go
@@ -35,7 +35,6 @@ import (
 	"github.com/filecoin-project/go-state-types/abi"
 	"github.com/filecoin-project/go-state-types/big"
 	builtintypes "github.com/filecoin-project/go-state-types/builtin"
-	minertypes "github.com/filecoin-project/go-state-types/builtin/v9/miner"
 	"github.com/filecoin-project/go-state-types/network"
 
 	"github.com/filecoin-project/lotus/api"
@@ -43,6 +42,7 @@ import (
 	"github.com/filecoin-project/lotus/build"
 	"github.com/filecoin-project/lotus/chain/actors"
 	"github.com/filecoin-project/lotus/chain/actors/builtin"
+	lminer "github.com/filecoin-project/lotus/chain/actors/builtin/miner"
 	"github.com/filecoin-project/lotus/chain/gen"
 	"github.com/filecoin-project/lotus/chain/types"
 	mktsdagstore "github.com/filecoin-project/lotus/markets/dagstore"
@@ -488,7 +488,7 @@ func (sm *StorageMinerAPI) SectorReceive(ctx context.Context, meta api.RemoteSec
 	return err
 }
 
-func (sm *StorageMinerAPI) ComputeWindowPoSt(ctx context.Context, dlIdx uint64, tsk types.TipSetKey) ([]minertypes.SubmitWindowedPoStParams, error) {
+func (sm *StorageMinerAPI) ComputeWindowPoSt(ctx context.Context, dlIdx uint64, tsk types.TipSetKey) ([]lminer.SubmitWindowedPoStParams, error) {
 	var ts *types.TipSet
 	var err error
 	if tsk == types.EmptyTSK {
@@ -1395,7 +1395,7 @@ func (sm *StorageMinerAPI) withdrawBalance(ctx context.Context, amount abi.Token
 		amount = available
 	}
 
-	params, err := actors.SerializeParams(&minertypes.WithdrawBalanceParams{
+	params, err := actors.SerializeParams(&lminer.WithdrawBalanceParams{
 		AmountRequested: amount,
 	})
 	if err != nil {
diff --git a/node/modules/lp2p/rcmgr.go b/node/modules/lp2p/rcmgr.go
index 0035ed05bc3..f2b2849863e 100644
--- a/node/modules/lp2p/rcmgr.go
+++ b/node/modules/lp2p/rcmgr.go
@@ -15,7 +15,6 @@ import (
 	"github.com/libp2p/go-libp2p/core/peer"
 	"github.com/libp2p/go-libp2p/core/protocol"
 	rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager"
-	rcmgrObs "github.com/libp2p/go-libp2p/p2p/host/resource-manager/obs"
 	"github.com/prometheus/client_golang/prometheus"
 	"go.opencensus.io/stats"
 	"go.opencensus.io/tag"
@@ -113,13 +112,13 @@ func ResourceManager(connMgrHi uint) func(lc fx.Lifecycle, repo repo.LockedRepo)
 			return nil, err
 		}
 
-		str, err := rcmgrObs.NewStatsTraceReporter()
+		str, err := rcmgr.NewStatsTraceReporter()
 		if err != nil {
 			return nil, fmt.Errorf("error creating resource manager stats reporter: %w", err)
 		}
 
 		rcmgrMetricsOnce.Do(func() {
-			rcmgrObs.MustRegisterWith(prometheus.DefaultRegisterer)
+			rcmgr.MustRegisterWith(prometheus.DefaultRegisterer)
 		})
 
 		// Metrics
diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go
index 74251e21de3..12879cd6405 100644
--- a/node/modules/storageminer.go
+++ b/node/modules/storageminer.go
@@ -157,7 +157,8 @@ func SealProofType(maddr dtypes.MinerAddress, fnapi v1api.FullNode) (abi.Registe
 		return 0, err
 	}
 
-	return miner.PreferredSealProofTypeFromWindowPoStType(networkVersion, mi.WindowPoStProofType)
+	// node seal proof type does not decide whether or not we use synthetic porep
+	return miner.PreferredSealProofTypeFromWindowPoStType(networkVersion, mi.WindowPoStProofType, false)
 }
 
 func AddressSelector(addrConf *config.MinerAddressConfig) func() (*ctladdr.AddressSelector, error) {
@@ -1000,7 +1001,6 @@ func NewSetSealConfigFunc(r repo.LockedRepo) (dtypes.SetSealingConfigFunc, error
 				AvailableBalanceBuffer:     types.FIL(cfg.AvailableBalanceBuffer),
 				DisableCollateralFallback:  cfg.DisableCollateralFallback,
 
-				BatchPreCommits:     cfg.BatchPreCommits,
 				MaxPreCommitBatch:   cfg.MaxPreCommitBatch,
 				PreCommitBatchWait:  config.Duration(cfg.PreCommitBatchWait),
 				PreCommitBatchSlack: config.Duration(cfg.PreCommitBatchSlack),
@@ -1017,6 +1017,7 @@ func NewSetSealConfigFunc(r repo.LockedRepo) (dtypes.SetSealingConfigFunc, error
 				TerminateBatchMin:                      cfg.TerminateBatchMin,
 				TerminateBatchWait:                     config.Duration(cfg.TerminateBatchWait),
 				MaxSectorProveCommitsSubmittedPerEpoch: cfg.MaxSectorProveCommitsSubmittedPerEpoch,
+				UseSyntheticPoRep:                      cfg.UseSyntheticPoRep,
 			}
 			c.SetSealingConfig(newCfg)
 		})
@@ -1045,7 +1046,6 @@ func ToSealingConfig(dealmakingCfg config.DealmakingConfig, sealingCfg config.Se
 		AvailableBalanceBuffer:     types.BigInt(sealingCfg.AvailableBalanceBuffer),
 		DisableCollateralFallback:  sealingCfg.DisableCollateralFallback,
 
-		BatchPreCommits:     sealingCfg.BatchPreCommits,
 		MaxPreCommitBatch:   sealingCfg.MaxPreCommitBatch,
 		PreCommitBatchWait:  time.Duration(sealingCfg.PreCommitBatchWait),
 		PreCommitBatchSlack: time.Duration(sealingCfg.PreCommitBatchSlack),
@@ -1062,6 +1062,7 @@ func ToSealingConfig(dealmakingCfg config.DealmakingConfig, sealingCfg config.Se
 		TerminateBatchMax:  sealingCfg.TerminateBatchMax,
 		TerminateBatchMin:  sealingCfg.TerminateBatchMin,
 		TerminateBatchWait: time.Duration(sealingCfg.TerminateBatchWait),
+		UseSyntheticPoRep:  sealingCfg.UseSyntheticPoRep,
 	}
 }
 
diff --git a/paychmgr/cbor_gen.go b/paychmgr/cbor_gen.go
index b3880aa1067..f97c176a304 100644
--- a/paychmgr/cbor_gen.go
+++ b/paychmgr/cbor_gen.go
@@ -41,7 +41,7 @@ func (t *VoucherInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Proof"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Proof")); err != nil {
+	if _, err := cw.WriteString(string("Proof")); err != nil {
 		return err
 	}
 
@@ -65,7 +65,7 @@ func (t *VoucherInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Voucher"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Voucher")); err != nil {
+	if _, err := cw.WriteString(string("Voucher")); err != nil {
 		return err
 	}
 
@@ -81,7 +81,7 @@ func (t *VoucherInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Submitted"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Submitted")); err != nil {
+	if _, err := cw.WriteString(string("Submitted")); err != nil {
 		return err
 	}
 
@@ -218,7 +218,7 @@ func (t *ChannelInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Amount"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Amount")); err != nil {
+	if _, err := cw.WriteString(string("Amount")); err != nil {
 		return err
 	}
 
@@ -234,7 +234,7 @@ func (t *ChannelInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Target"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Target")); err != nil {
+	if _, err := cw.WriteString(string("Target")); err != nil {
 		return err
 	}
 
@@ -250,7 +250,7 @@ func (t *ChannelInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Channel"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Channel")); err != nil {
+	if _, err := cw.WriteString(string("Channel")); err != nil {
 		return err
 	}
 
@@ -266,7 +266,7 @@ func (t *ChannelInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Control"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Control")); err != nil {
+	if _, err := cw.WriteString(string("Control")); err != nil {
 		return err
 	}
 
@@ -282,7 +282,7 @@ func (t *ChannelInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("NextLane"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("NextLane")); err != nil {
+	if _, err := cw.WriteString(string("NextLane")); err != nil {
 		return err
 	}
 
@@ -298,7 +298,7 @@ func (t *ChannelInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Settling"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Settling")); err != nil {
+	if _, err := cw.WriteString(string("Settling")); err != nil {
 		return err
 	}
 
@@ -314,7 +314,7 @@ func (t *ChannelInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Vouchers"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Vouchers")); err != nil {
+	if _, err := cw.WriteString(string("Vouchers")); err != nil {
 		return err
 	}
 
@@ -339,7 +339,7 @@ func (t *ChannelInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("ChannelID"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("ChannelID")); err != nil {
+	if _, err := cw.WriteString(string("ChannelID")); err != nil {
 		return err
 	}
 
@@ -350,7 +350,7 @@ func (t *ChannelInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.ChannelID))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string(t.ChannelID)); err != nil {
+	if _, err := cw.WriteString(string(t.ChannelID)); err != nil {
 		return err
 	}
 
@@ -362,7 +362,7 @@ func (t *ChannelInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("CreateMsg"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("CreateMsg")); err != nil {
+	if _, err := cw.WriteString(string("CreateMsg")); err != nil {
 		return err
 	}
 
@@ -384,7 +384,7 @@ func (t *ChannelInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Direction"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Direction")); err != nil {
+	if _, err := cw.WriteString(string("Direction")); err != nil {
 		return err
 	}
 
@@ -400,7 +400,7 @@ func (t *ChannelInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("AddFundsMsg"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("AddFundsMsg")); err != nil {
+	if _, err := cw.WriteString(string("AddFundsMsg")); err != nil {
 		return err
 	}
 
@@ -422,7 +422,7 @@ func (t *ChannelInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("PendingAmount"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("PendingAmount")); err != nil {
+	if _, err := cw.WriteString(string("PendingAmount")); err != nil {
 		return err
 	}
 
@@ -438,7 +438,7 @@ func (t *ChannelInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("AvailableAmount"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("AvailableAmount")); err != nil {
+	if _, err := cw.WriteString(string("AvailableAmount")); err != nil {
 		return err
 	}
 
@@ -454,7 +454,7 @@ func (t *ChannelInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("PendingAvailableAmount"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("PendingAvailableAmount")); err != nil {
+	if _, err := cw.WriteString(string("PendingAvailableAmount")); err != nil {
 		return err
 	}
 
@@ -606,13 +606,32 @@ func (t *ChannelInfo) UnmarshalCBOR(r io.Reader) (err error) {
 			}
 
 			for i := 0; i < int(extra); i++ {
+				{
+					var maj byte
+					var extra uint64
+					var err error
+					_ = maj
+					_ = extra
+					_ = err
+
+					{
+
+						b, err := cr.ReadByte()
+						if err != nil {
+							return err
+						}
+						if b != cbg.CborNull[0] {
+							if err := cr.UnreadByte(); err != nil {
+								return err
+							}
+							t.Vouchers[i] = new(VoucherInfo)
+							if err := t.Vouchers[i].UnmarshalCBOR(cr); err != nil {
+								return xerrors.Errorf("unmarshaling t.Vouchers[i] pointer: %w", err)
+							}
+						}
 
-				var v VoucherInfo
-				if err := v.UnmarshalCBOR(cr); err != nil {
-					return err
+					}
 				}
-
-				t.Vouchers[i] = &v
 			}
 
 			// t.ChannelID (string) (string)
@@ -746,7 +765,7 @@ func (t *MsgInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Err"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Err")); err != nil {
+	if _, err := cw.WriteString(string("Err")); err != nil {
 		return err
 	}
 
@@ -757,7 +776,7 @@ func (t *MsgInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Err))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string(t.Err)); err != nil {
+	if _, err := cw.WriteString(string(t.Err)); err != nil {
 		return err
 	}
 
@@ -769,7 +788,7 @@ func (t *MsgInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("MsgCid"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("MsgCid")); err != nil {
+	if _, err := cw.WriteString(string("MsgCid")); err != nil {
 		return err
 	}
 
@@ -785,7 +804,7 @@ func (t *MsgInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Received"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Received")); err != nil {
+	if _, err := cw.WriteString(string("Received")); err != nil {
 		return err
 	}
 
@@ -801,7 +820,7 @@ func (t *MsgInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("ChannelID"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("ChannelID")); err != nil {
+	if _, err := cw.WriteString(string("ChannelID")); err != nil {
 		return err
 	}
 
@@ -812,7 +831,7 @@ func (t *MsgInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.ChannelID))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string(t.ChannelID)); err != nil {
+	if _, err := cw.WriteString(string(t.ChannelID)); err != nil {
 		return err
 	}
 	return nil
diff --git a/storage/pipeline/cbor_gen.go b/storage/pipeline/cbor_gen.go
index d14611c6a34..7ece009ccbf 100644
--- a/storage/pipeline/cbor_gen.go
+++ b/storage/pipeline/cbor_gen.go
@@ -43,7 +43,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Log"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Log")); err != nil {
+	if _, err := cw.WriteString(string("Log")); err != nil {
 		return err
 	}
 
@@ -68,7 +68,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("CommD"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("CommD")); err != nil {
+	if _, err := cw.WriteString(string("CommD")); err != nil {
 		return err
 	}
 
@@ -90,7 +90,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("CommR"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("CommR")); err != nil {
+	if _, err := cw.WriteString(string("CommR")); err != nil {
 		return err
 	}
 
@@ -112,7 +112,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Proof"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Proof")); err != nil {
+	if _, err := cw.WriteString(string("Proof")); err != nil {
 		return err
 	}
 
@@ -136,7 +136,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("State"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("State")); err != nil {
+	if _, err := cw.WriteString(string("State")); err != nil {
 		return err
 	}
 
@@ -147,7 +147,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.State))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string(t.State)); err != nil {
+	if _, err := cw.WriteString(string(t.State)); err != nil {
 		return err
 	}
 
@@ -159,7 +159,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Pieces"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Pieces")); err != nil {
+	if _, err := cw.WriteString(string("Pieces")); err != nil {
 		return err
 	}
 
@@ -184,7 +184,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Return"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Return")); err != nil {
+	if _, err := cw.WriteString(string("Return")); err != nil {
 		return err
 	}
 
@@ -195,7 +195,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Return))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string(t.Return)); err != nil {
+	if _, err := cw.WriteString(string(t.Return)); err != nil {
 		return err
 	}
 
@@ -207,7 +207,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("LastErr"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("LastErr")); err != nil {
+	if _, err := cw.WriteString(string("LastErr")); err != nil {
 		return err
 	}
 
@@ -218,7 +218,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.LastErr))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string(t.LastErr)); err != nil {
+	if _, err := cw.WriteString(string(t.LastErr)); err != nil {
 		return err
 	}
 
@@ -230,7 +230,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("CCPieces"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("CCPieces")); err != nil {
+	if _, err := cw.WriteString(string("CCPieces")); err != nil {
 		return err
 	}
 
@@ -255,7 +255,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("CCUpdate"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("CCUpdate")); err != nil {
+	if _, err := cw.WriteString(string("CCUpdate")); err != nil {
 		return err
 	}
 
@@ -271,7 +271,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("SeedEpoch"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("SeedEpoch")); err != nil {
+	if _, err := cw.WriteString(string("SeedEpoch")); err != nil {
 		return err
 	}
 
@@ -293,7 +293,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("SeedValue"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("SeedValue")); err != nil {
+	if _, err := cw.WriteString(string("SeedValue")); err != nil {
 		return err
 	}
 
@@ -317,7 +317,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("SectorType"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("SectorType")); err != nil {
+	if _, err := cw.WriteString(string("SectorType")); err != nil {
 		return err
 	}
 
@@ -339,7 +339,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("TicketEpoch"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("TicketEpoch")); err != nil {
+	if _, err := cw.WriteString(string("TicketEpoch")); err != nil {
 		return err
 	}
 
@@ -361,7 +361,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("TicketValue"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("TicketValue")); err != nil {
+	if _, err := cw.WriteString(string("TicketValue")); err != nil {
 		return err
 	}
 
@@ -385,7 +385,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("CreationTime"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("CreationTime")); err != nil {
+	if _, err := cw.WriteString(string("CreationTime")); err != nil {
 		return err
 	}
 
@@ -407,7 +407,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("SectorNumber"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("SectorNumber")); err != nil {
+	if _, err := cw.WriteString(string("SectorNumber")); err != nil {
 		return err
 	}
 
@@ -423,7 +423,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("TerminatedAt"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("TerminatedAt")); err != nil {
+	if _, err := cw.WriteString(string("TerminatedAt")); err != nil {
 		return err
 	}
 
@@ -445,7 +445,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("UpdateSealed"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("UpdateSealed")); err != nil {
+	if _, err := cw.WriteString(string("UpdateSealed")); err != nil {
 		return err
 	}
 
@@ -467,7 +467,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("CommitMessage"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("CommitMessage")); err != nil {
+	if _, err := cw.WriteString(string("CommitMessage")); err != nil {
 		return err
 	}
 
@@ -489,7 +489,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("InvalidProofs"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("InvalidProofs")); err != nil {
+	if _, err := cw.WriteString(string("InvalidProofs")); err != nil {
 		return err
 	}
 
@@ -505,7 +505,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("PreCommit1Out"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("PreCommit1Out")); err != nil {
+	if _, err := cw.WriteString(string("PreCommit1Out")); err != nil {
 		return err
 	}
 
@@ -529,7 +529,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("FaultReportMsg"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("FaultReportMsg")); err != nil {
+	if _, err := cw.WriteString(string("FaultReportMsg")); err != nil {
 		return err
 	}
 
@@ -551,7 +551,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("UpdateUnsealed"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("UpdateUnsealed")); err != nil {
+	if _, err := cw.WriteString(string("UpdateUnsealed")); err != nil {
 		return err
 	}
 
@@ -573,7 +573,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("PreCommit2Fails"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("PreCommit2Fails")); err != nil {
+	if _, err := cw.WriteString(string("PreCommit2Fails")); err != nil {
 		return err
 	}
 
@@ -589,7 +589,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("PreCommitTipSet"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("PreCommitTipSet")); err != nil {
+	if _, err := cw.WriteString(string("PreCommitTipSet")); err != nil {
 		return err
 	}
 
@@ -605,7 +605,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("RemoteDataCache"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("RemoteDataCache")); err != nil {
+	if _, err := cw.WriteString(string("RemoteDataCache")); err != nil {
 		return err
 	}
 
@@ -621,7 +621,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("PreCommitDeposit"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("PreCommitDeposit")); err != nil {
+	if _, err := cw.WriteString(string("PreCommitDeposit")); err != nil {
 		return err
 	}
 
@@ -637,7 +637,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("PreCommitMessage"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("PreCommitMessage")); err != nil {
+	if _, err := cw.WriteString(string("PreCommitMessage")); err != nil {
 		return err
 	}
 
@@ -659,7 +659,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("RemoteDataSealed"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("RemoteDataSealed")); err != nil {
+	if _, err := cw.WriteString(string("RemoteDataSealed")); err != nil {
 		return err
 	}
 
@@ -675,7 +675,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("TerminateMessage"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("TerminateMessage")); err != nil {
+	if _, err := cw.WriteString(string("TerminateMessage")); err != nil {
 		return err
 	}
 
@@ -697,7 +697,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("RemoteDataUnsealed"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("RemoteDataUnsealed")); err != nil {
+	if _, err := cw.WriteString(string("RemoteDataUnsealed")); err != nil {
 		return err
 	}
 
@@ -713,7 +713,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("ReplicaUpdateProof"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("ReplicaUpdateProof")); err != nil {
+	if _, err := cw.WriteString(string("ReplicaUpdateProof")); err != nil {
 		return err
 	}
 
@@ -737,7 +737,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("RemoteDataFinalized"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("RemoteDataFinalized")); err != nil {
+	if _, err := cw.WriteString(string("RemoteDataFinalized")); err != nil {
 		return err
 	}
 
@@ -753,7 +753,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("ReplicaUpdateMessage"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("ReplicaUpdateMessage")); err != nil {
+	if _, err := cw.WriteString(string("ReplicaUpdateMessage")); err != nil {
 		return err
 	}
 
@@ -775,7 +775,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("RemoteCommit1Endpoint"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("RemoteCommit1Endpoint")); err != nil {
+	if _, err := cw.WriteString(string("RemoteCommit1Endpoint")); err != nil {
 		return err
 	}
 
@@ -786,7 +786,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.RemoteCommit1Endpoint))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string(t.RemoteCommit1Endpoint)); err != nil {
+	if _, err := cw.WriteString(string(t.RemoteCommit1Endpoint)); err != nil {
 		return err
 	}
 
@@ -798,7 +798,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("RemoteCommit2Endpoint"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("RemoteCommit2Endpoint")); err != nil {
+	if _, err := cw.WriteString(string("RemoteCommit2Endpoint")); err != nil {
 		return err
 	}
 
@@ -809,7 +809,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.RemoteCommit2Endpoint))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string(t.RemoteCommit2Endpoint)); err != nil {
+	if _, err := cw.WriteString(string(t.RemoteCommit2Endpoint)); err != nil {
 		return err
 	}
 
@@ -821,7 +821,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("RemoteSealingDoneEndpoint"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("RemoteSealingDoneEndpoint")); err != nil {
+	if _, err := cw.WriteString(string("RemoteSealingDoneEndpoint")); err != nil {
 		return err
 	}
 
@@ -832,7 +832,7 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.RemoteSealingDoneEndpoint))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string(t.RemoteSealingDoneEndpoint)); err != nil {
+	if _, err := cw.WriteString(string(t.RemoteSealingDoneEndpoint)); err != nil {
 		return err
 	}
 	return nil
@@ -897,13 +897,22 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) (err error) {
 			}
 
 			for i := 0; i < int(extra); i++ {
+				{
+					var maj byte
+					var extra uint64
+					var err error
+					_ = maj
+					_ = extra
+					_ = err
 
-				var v Log
-				if err := v.UnmarshalCBOR(cr); err != nil {
-					return err
-				}
+					{
 
-				t.Log[i] = v
+						if err := t.Log[i].UnmarshalCBOR(cr); err != nil {
+							return xerrors.Errorf("unmarshaling t.Log[i]: %w", err)
+						}
+
+					}
+				}
 			}
 
 			// t.CommD (cid.Cid) (struct)
@@ -1006,13 +1015,22 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) (err error) {
 			}
 
 			for i := 0; i < int(extra); i++ {
+				{
+					var maj byte
+					var extra uint64
+					var err error
+					_ = maj
+					_ = extra
+					_ = err
 
-				var v api.SectorPiece
-				if err := v.UnmarshalCBOR(cr); err != nil {
-					return err
-				}
+					{
+
+						if err := t.Pieces[i].UnmarshalCBOR(cr); err != nil {
+							return xerrors.Errorf("unmarshaling t.Pieces[i]: %w", err)
+						}
 
-				t.Pieces[i] = v
+					}
+				}
 			}
 
 			// t.Return (sealing.ReturnState) (string)
@@ -1058,13 +1076,22 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) (err error) {
 			}
 
 			for i := 0; i < int(extra); i++ {
+				{
+					var maj byte
+					var extra uint64
+					var err error
+					_ = maj
+					_ = extra
+					_ = err
 
-				var v api.SectorPiece
-				if err := v.UnmarshalCBOR(cr); err != nil {
-					return err
-				}
+					{
 
-				t.CCPieces[i] = v
+						if err := t.CCPieces[i].UnmarshalCBOR(cr); err != nil {
+							return xerrors.Errorf("unmarshaling t.CCPieces[i]: %w", err)
+						}
+
+					}
+				}
 			}
 
 			// t.CCUpdate (bool) (bool)
@@ -1669,7 +1696,7 @@ func (t *Log) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Kind"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Kind")); err != nil {
+	if _, err := cw.WriteString(string("Kind")); err != nil {
 		return err
 	}
 
@@ -1680,7 +1707,7 @@ func (t *Log) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Kind))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string(t.Kind)); err != nil {
+	if _, err := cw.WriteString(string(t.Kind)); err != nil {
 		return err
 	}
 
@@ -1692,7 +1719,7 @@ func (t *Log) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Trace"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Trace")); err != nil {
+	if _, err := cw.WriteString(string("Trace")); err != nil {
 		return err
 	}
 
@@ -1703,7 +1730,7 @@ func (t *Log) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Trace))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string(t.Trace)); err != nil {
+	if _, err := cw.WriteString(string(t.Trace)); err != nil {
 		return err
 	}
 
@@ -1715,7 +1742,7 @@ func (t *Log) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Message"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Message")); err != nil {
+	if _, err := cw.WriteString(string("Message")); err != nil {
 		return err
 	}
 
@@ -1726,7 +1753,7 @@ func (t *Log) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Message))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string(t.Message)); err != nil {
+	if _, err := cw.WriteString(string(t.Message)); err != nil {
 		return err
 	}
 
@@ -1738,7 +1765,7 @@ func (t *Log) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Timestamp"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Timestamp")); err != nil {
+	if _, err := cw.WriteString(string("Timestamp")); err != nil {
 		return err
 	}
 
diff --git a/storage/pipeline/checks.go b/storage/pipeline/checks.go
index b243804cc0e..ecd160231c1 100644
--- a/storage/pipeline/checks.go
+++ b/storage/pipeline/checks.go
@@ -106,13 +106,15 @@ func checkPrecommit(ctx context.Context, maddr address.Address, si SectorInfo, t
 		return err
 	}
 
-	commD, err := api.StateComputeDataCID(ctx, maddr, si.SectorType, si.dealIDs(), tsk)
-	if err != nil {
-		return &ErrApi{xerrors.Errorf("calling StateComputeDataCommitment: %w", err)}
-	}
+	if si.hasDeals() {
+		commD, err := api.StateComputeDataCID(ctx, maddr, si.SectorType, si.dealIDs(), tsk)
+		if err != nil {
+			return &ErrApi{xerrors.Errorf("calling StateComputeDataCommitment: %w", err)}
+		}
 
-	if si.CommD == nil || !commD.Equals(*si.CommD) {
-		return &ErrBadCommD{xerrors.Errorf("on chain CommD differs from sector: %s != %s", commD, si.CommD)}
+		if si.CommD == nil || !commD.Equals(*si.CommD) {
+			return &ErrBadCommD{xerrors.Errorf("on chain CommD differs from sector: %s != %s", commD, si.CommD)}
+		}
 	}
 
 	pci, err := api.StateSectorPreCommitInfo(ctx, maddr, si.SectorNumber, tsk)
diff --git a/storage/pipeline/commit_batch.go b/storage/pipeline/commit_batch.go
index 9948b5432dc..754f317630b 100644
--- a/storage/pipeline/commit_batch.go
+++ b/storage/pipeline/commit_batch.go
@@ -16,12 +16,12 @@ import (
 	actorstypes "github.com/filecoin-project/go-state-types/actors"
 	"github.com/filecoin-project/go-state-types/big"
 	"github.com/filecoin-project/go-state-types/builtin"
-	"github.com/filecoin-project/go-state-types/builtin/v9/miner"
 	"github.com/filecoin-project/go-state-types/network"
 	"github.com/filecoin-project/go-state-types/proof"
 
 	"github.com/filecoin-project/lotus/api"
 	"github.com/filecoin-project/lotus/build"
+	"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
 	"github.com/filecoin-project/lotus/chain/actors/policy"
 	"github.com/filecoin-project/lotus/chain/types"
 	"github.com/filecoin-project/lotus/node/config"
diff --git a/storage/pipeline/commit_batch_test.go b/storage/pipeline/commit_batch_test.go
index 15c2100cb85..5ae2f171ae2 100644
--- a/storage/pipeline/commit_batch_test.go
+++ b/storage/pipeline/commit_batch_test.go
@@ -53,7 +53,6 @@ func TestCommitBatcher(t *testing.T) {
 			WaitDealsDelay:            time.Hour * 6,
 			AlwaysKeepUnsealedCopy:    true,
 
-			BatchPreCommits:     true,
 			MaxPreCommitBatch:   miner5.PreCommitSectorBatchMaxSize,
 			PreCommitBatchWait:  24 * time.Hour,
 			PreCommitBatchSlack: 3 * time.Hour,
diff --git a/storage/pipeline/fsm.go b/storage/pipeline/fsm.go
index 8ae18a9fdb7..ac3dafa86ec 100644
--- a/storage/pipeline/fsm.go
+++ b/storage/pipeline/fsm.go
@@ -90,7 +90,7 @@ var fsmPlanners = map[SectorState]func(events []statemachine.Event, state *Secto
 		on(SectorOldTicket{}, GetTicket),
 	),
 	PreCommit2: planOne(
-		on(SectorPreCommit2{}, PreCommitting),
+		on(SectorPreCommit2{}, SubmitPreCommitBatch),
 		on(SectorSealPreCommit2Failed{}, SealPreCommit2Failed),
 		on(SectorSealPreCommit1Failed{}, SealPreCommit1Failed),
 	),
diff --git a/storage/pipeline/fsm_test.go b/storage/pipeline/fsm_test.go
index f12b66f9350..4dfc8548db0 100644
--- a/storage/pipeline/fsm_test.go
+++ b/storage/pipeline/fsm_test.go
@@ -54,10 +54,10 @@ func TestHappyPath(t *testing.T) {
 	require.Equal(m.t, m.state.State, PreCommit2)
 
 	m.planSingle(SectorPreCommit2{})
-	require.Equal(m.t, m.state.State, PreCommitting)
+	require.Equal(m.t, m.state.State, SubmitPreCommitBatch)
 
-	m.planSingle(SectorPreCommitted{})
-	require.Equal(m.t, m.state.State, PreCommitWait)
+	m.planSingle(SectorPreCommitBatchSent{})
+	require.Equal(m.t, m.state.State, PreCommitBatchWait)
 
 	m.planSingle(SectorPreCommitLanded{})
 	require.Equal(m.t, m.state.State, WaitSeed)
@@ -77,7 +77,7 @@ func TestHappyPath(t *testing.T) {
 	m.planSingle(SectorFinalized{})
 	require.Equal(m.t, m.state.State, Proving)
 
-	expected := []SectorState{Packing, GetTicket, PreCommit1, PreCommit2, PreCommitting, PreCommitWait, WaitSeed, Committing, SubmitCommit, CommitWait, FinalizeSector, Proving}
+	expected := []SectorState{Packing, GetTicket, PreCommit1, PreCommit2, SubmitPreCommitBatch, PreCommitBatchWait, WaitSeed, Committing, SubmitCommit, CommitWait, FinalizeSector, Proving}
 	for i, n := range notif {
 		if n.before.State != expected[i] {
 			t.Fatalf("expected before state: %s, got: %s", expected[i], n.before.State)
@@ -116,10 +116,10 @@ func TestHappyPathFinalizeEarly(t *testing.T) {
 	require.Equal(m.t, m.state.State, PreCommit2)
 
 	m.planSingle(SectorPreCommit2{})
-	require.Equal(m.t, m.state.State, PreCommitting)
+	require.Equal(m.t, m.state.State, SubmitPreCommitBatch)
 
-	m.planSingle(SectorPreCommitted{})
-	require.Equal(m.t, m.state.State, PreCommitWait)
+	m.planSingle(SectorPreCommitBatchSent{})
+	require.Equal(m.t, m.state.State, PreCommitBatchWait)
 
 	m.planSingle(SectorPreCommitLanded{})
 	require.Equal(m.t, m.state.State, WaitSeed)
@@ -145,7 +145,7 @@ func TestHappyPathFinalizeEarly(t *testing.T) {
 	m.planSingle(SectorFinalized{})
 	require.Equal(m.t, m.state.State, Proving)
 
-	expected := []SectorState{Packing, GetTicket, PreCommit1, PreCommit2, PreCommitting, PreCommitWait, WaitSeed, Committing, CommitFinalize, SubmitCommit, SubmitCommitAggregate, CommitAggregateWait, FinalizeSector, Proving}
+	expected := []SectorState{Packing, GetTicket, PreCommit1, PreCommit2, SubmitPreCommitBatch, PreCommitBatchWait, WaitSeed, Committing, CommitFinalize, SubmitCommit, SubmitCommitAggregate, CommitAggregateWait, FinalizeSector, Proving}
 	for i, n := range notif {
 		if n.before.State != expected[i] {
 			t.Fatalf("expected before state: %s, got: %s", expected[i], n.before.State)
@@ -220,10 +220,10 @@ func TestSeedRevert(t *testing.T) {
 	require.Equal(m.t, m.state.State, PreCommit2)
 
 	m.planSingle(SectorPreCommit2{})
-	require.Equal(m.t, m.state.State, PreCommitting)
+	require.Equal(m.t, m.state.State, SubmitPreCommitBatch)
 
-	m.planSingle(SectorPreCommitted{})
-	require.Equal(m.t, m.state.State, PreCommitWait)
+	m.planSingle(SectorPreCommitBatchSent{})
+	require.Equal(m.t, m.state.State, PreCommitBatchWait)
 
 	m.planSingle(SectorPreCommitLanded{})
 	require.Equal(m.t, m.state.State, WaitSeed)
diff --git a/storage/pipeline/precommit_batch.go b/storage/pipeline/precommit_batch.go
index 63e26366296..3a86c8628e0 100644
--- a/storage/pipeline/precommit_batch.go
+++ b/storage/pipeline/precommit_batch.go
@@ -7,19 +7,18 @@ import (
 	"sync"
 	"time"
 
-	"github.com/ipfs/go-cid"
 	"golang.org/x/xerrors"
 
 	"github.com/filecoin-project/go-address"
 	"github.com/filecoin-project/go-state-types/abi"
 	"github.com/filecoin-project/go-state-types/big"
 	"github.com/filecoin-project/go-state-types/builtin"
-	"github.com/filecoin-project/go-state-types/builtin/v9/miner"
 	verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
 	"github.com/filecoin-project/go-state-types/network"
 
 	"github.com/filecoin-project/lotus/api"
 	"github.com/filecoin-project/lotus/build"
+	"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
 	"github.com/filecoin-project/lotus/chain/actors/policy"
 	"github.com/filecoin-project/lotus/chain/types"
 	"github.com/filecoin-project/lotus/node/config"
@@ -193,33 +192,30 @@ func (b *PreCommitBatcher) maybeStartBatch(notif bool) ([]sealiface.PreCommitBat
 		return nil, xerrors.Errorf("getting config: %w", err)
 	}
 
-	if notif && total < cfg.MaxPreCommitBatch {
-		return nil, nil
-	}
-
 	ts, err := b.api.ChainHead(b.mctx)
 	if err != nil {
 		return nil, err
 	}
 
-	// TODO: Drop this once nv14 has come and gone
-	nv, err := b.api.StateNetworkVersion(b.mctx, ts.Key())
-	if err != nil {
-		return nil, xerrors.Errorf("couldn't get network version: %w", err)
+	curBasefeeLow := false
+	if !cfg.BatchPreCommitAboveBaseFee.Equals(big.Zero()) && ts.MinTicketBlock().ParentBaseFee.LessThan(cfg.BatchPreCommitAboveBaseFee) {
+		curBasefeeLow = true
 	}
 
-	individual := false
-	if !cfg.BatchPreCommitAboveBaseFee.Equals(big.Zero()) && ts.MinTicketBlock().ParentBaseFee.LessThan(cfg.BatchPreCommitAboveBaseFee) && nv >= network.Version14 {
-		individual = true
+	// if this wasn't an user-forced batch, and we're not at/above the max batch size,
+	// and we're not above the basefee threshold, don't batch yet
+	if notif && total < cfg.MaxPreCommitBatch && !curBasefeeLow {
+		return nil, nil
 	}
 
-	// todo support multiple batches
-	var res []sealiface.PreCommitBatchRes
-	if !individual {
-		res, err = b.processBatch(cfg, ts.Key(), ts.MinTicketBlock().ParentBaseFee, nv)
-	} else {
-		res, err = b.processIndividually(cfg)
+	nv, err := b.api.StateNetworkVersion(b.mctx, ts.Key())
+	if err != nil {
+		return nil, xerrors.Errorf("couldn't get network version: %w", err)
 	}
+
+	// For precommits the only method to precommit sectors after nv21(22?) is to use the new precommit_batch2 method
+	// So we always batch
+	res, err := b.processBatch(cfg, ts.Key(), ts.MinTicketBlock().ParentBaseFee, nv)
 	if err != nil && len(res) == 0 {
 		return nil, err
 	}
@@ -243,91 +239,14 @@ func (b *PreCommitBatcher) maybeStartBatch(notif bool) ([]sealiface.PreCommitBat
 	return res, nil
 }
 
-func (b *PreCommitBatcher) processIndividually(cfg sealiface.Config) ([]sealiface.PreCommitBatchRes, error) {
-	mi, err := b.api.StateMinerInfo(b.mctx, b.maddr, types.EmptyTSK)
-	if err != nil {
-		return nil, xerrors.Errorf("couldn't get miner info: %w", err)
-	}
-
-	avail := types.TotalFilecoinInt
-
-	if cfg.CollateralFromMinerBalance && !cfg.DisableCollateralFallback {
-		avail, err = b.api.StateMinerAvailableBalance(b.mctx, b.maddr, types.EmptyTSK)
-		if err != nil {
-			return nil, xerrors.Errorf("getting available miner balance: %w", err)
-		}
-
-		avail = big.Sub(avail, cfg.AvailableBalanceBuffer)
-		if avail.LessThan(big.Zero()) {
-			avail = big.Zero()
-		}
-	}
-
-	var res []sealiface.PreCommitBatchRes
-
-	for sn, info := range b.todo {
-		r := sealiface.PreCommitBatchRes{
-			Sectors: []abi.SectorNumber{sn},
-		}
-
-		mcid, err := b.processSingle(cfg, mi, &avail, info)
-		if err != nil {
-			r.Error = err.Error()
-		} else {
-			r.Msg = &mcid
-		}
-
-		res = append(res, r)
-	}
-
-	return res, nil
-}
-
-func (b *PreCommitBatcher) processSingle(cfg sealiface.Config, mi api.MinerInfo, avail *abi.TokenAmount, entry *preCommitEntry) (cid.Cid, error) {
-	msgParams := infoToPreCommitSectorParams(entry.pci)
-	enc := new(bytes.Buffer)
-
-	if err := msgParams.MarshalCBOR(enc); err != nil {
-		return cid.Undef, xerrors.Errorf("marshaling precommit params: %w", err)
-	}
-
-	deposit := entry.deposit
-	if cfg.CollateralFromMinerBalance {
-		c := big.Sub(deposit, *avail)
-		*avail = big.Sub(*avail, deposit)
-		deposit = c
-
-		if deposit.LessThan(big.Zero()) {
-			deposit = big.Zero()
-		}
-		if (*avail).LessThan(big.Zero()) {
-			*avail = big.Zero()
-		}
-	}
-
-	goodFunds := big.Add(deposit, big.Int(b.feeCfg.MaxPreCommitGasFee))
-
-	from, _, err := b.addrSel.AddressFor(b.mctx, b.api, mi, api.PreCommitAddr, goodFunds, deposit)
-	if err != nil {
-		return cid.Undef, xerrors.Errorf("no good address to send precommit message from: %w", err)
-	}
-
-	mcid, err := sendMsg(b.mctx, b.api, from, b.maddr, builtin.MethodsMiner.PreCommitSector, deposit, big.Int(b.feeCfg.MaxPreCommitGasFee), enc.Bytes())
-	if err != nil {
-		return cid.Undef, xerrors.Errorf("pushing message to mpool: %w", err)
-	}
-
-	return mcid, nil
-}
-
 func (b *PreCommitBatcher) processPreCommitBatch(cfg sealiface.Config, bf abi.TokenAmount, entries []*preCommitEntry, nv network.Version) ([]sealiface.PreCommitBatchRes, error) {
-	params := miner.PreCommitSectorBatchParams{}
+	params := miner.PreCommitSectorBatchParams2{}
 	deposit := big.Zero()
 	var res sealiface.PreCommitBatchRes
 
 	for _, p := range entries {
 		res.Sectors = append(res.Sectors, p.pci.SectorNumber)
-		params.Sectors = append(params.Sectors, *infoToPreCommitSectorParams(p.pci))
+		params.Sectors = append(params.Sectors, *p.pci)
 		deposit = big.Add(deposit, p.deposit)
 	}
 
@@ -367,7 +286,7 @@ func (b *PreCommitBatcher) processPreCommitBatch(cfg sealiface.Config, bf abi.To
 		return []sealiface.PreCommitBatchRes{res}, xerrors.Errorf("no good address found: %w", err)
 	}
 
-	_, err = simulateMsgGas(b.mctx, b.api, from, b.maddr, builtin.MethodsMiner.PreCommitSectorBatch, needFunds, maxFee, enc.Bytes())
+	_, err = simulateMsgGas(b.mctx, b.api, from, b.maddr, builtin.MethodsMiner.PreCommitSectorBatch2, needFunds, maxFee, enc.Bytes())
 
 	if err != nil && (!api.ErrorIsIn(err, []error{&api.ErrOutOfGas{}}) || len(entries) == 1) {
 		res.Error = err.Error()
@@ -385,7 +304,7 @@ func (b *PreCommitBatcher) processPreCommitBatch(cfg sealiface.Config, bf abi.To
 	}
 
 	// If state call succeeds, we can send the message for real
-	mcid, err := sendMsg(b.mctx, b.api, from, b.maddr, builtin.MethodsMiner.PreCommitSectorBatch, needFunds, maxFee, enc.Bytes())
+	mcid, err := sendMsg(b.mctx, b.api, from, b.maddr, builtin.MethodsMiner.PreCommitSectorBatch2, needFunds, maxFee, enc.Bytes())
 	if err != nil {
 		res.Error = err.Error()
 		return []sealiface.PreCommitBatchRes{res}, xerrors.Errorf("pushing message to mpool: %w", err)
diff --git a/storage/pipeline/precommit_batch_test.go b/storage/pipeline/precommit_batch_test.go
index 6951faad73f..1f3aaf24472 100644
--- a/storage/pipeline/precommit_batch_test.go
+++ b/storage/pipeline/precommit_batch_test.go
@@ -56,7 +56,6 @@ func TestPrecommitBatcher(t *testing.T) {
 			WaitDealsDelay:            time.Hour * 6,
 			AlwaysKeepUnsealedCopy:    true,
 
-			BatchPreCommits:            true,
 			MaxPreCommitBatch:          maxBatch,
 			PreCommitBatchWait:         24 * time.Hour,
 			PreCommitBatchSlack:        3 * time.Hour,
@@ -114,7 +113,7 @@ func TestPrecommitBatcher(t *testing.T) {
 				basefee = big.NewInt(10001)
 			}
 
-			s.EXPECT().ChainHead(gomock.Any()).Return(makeBFTs(t, basefee, 1), nil)
+			s.EXPECT().ChainHead(gomock.Any()).Return(makeBFTs(t, basefee, 1), nil).MaxTimes(2) // once in AddPreCommit
 
 			go func() {
 				defer done.Unlock()
@@ -183,28 +182,6 @@ func TestPrecommitBatcher(t *testing.T) {
 	expectInitialCalls := func() action {
 		return func(t *testing.T, s *mocks.MockPreCommitBatcherApi, pcb *pipeline.PreCommitBatcher) promise {
 			s.EXPECT().ChainHead(gomock.Any()).Return(makeBFTs(t, big.NewInt(10001), 1), nil)
-			s.EXPECT().StateNetworkVersion(gomock.Any(), gomock.Any()).Return(network.Version14, nil)
-			return nil
-		}
-	}
-
-	//stm: @CHAIN_STATE_MINER_INFO_001, @CHAIN_STATE_NETWORK_VERSION_001
-	expectSendsSingle := func(expect []abi.SectorNumber) action {
-		return func(t *testing.T, s *mocks.MockPreCommitBatcherApi, pcb *pipeline.PreCommitBatcher) promise {
-			s.EXPECT().ChainHead(gomock.Any()).Return(makeBFTs(t, big.NewInt(9999), 1), nil)
-			s.EXPECT().StateNetworkVersion(gomock.Any(), gomock.Any()).Return(network.Version14, nil)
-
-			s.EXPECT().StateMinerInfo(gomock.Any(), gomock.Any(), gomock.Any()).Return(api.MinerInfo{Owner: t0123, Worker: t0123}, nil)
-			for _, number := range expect {
-				numClone := number
-				s.EXPECT().MpoolPushMessage(gomock.Any(), funMatcher(func(i interface{}) bool {
-					b := i.(*types.Message)
-					var params miner6.PreCommitSectorParams
-					require.NoError(t, params.UnmarshalCBOR(bytes.NewReader(b.Params)))
-					require.Equal(t, numClone, params.SectorNumber)
-					return true
-				}), gomock.Any()).Return(dummySmsg, nil)
-			}
 			return nil
 		}
 	}
@@ -240,18 +217,11 @@ func TestPrecommitBatcher(t *testing.T) {
 	}{
 		"addSingle": {
 			actions: []action{
-				addSector(0, false),
+				addSector(0, true),
 				waitPending(1),
 				flush([]abi.SectorNumber{0}),
 			},
 		},
-		"addTwo": {
-			actions: []action{
-				addSectors(getSectors(2), false),
-				waitPending(2),
-				flush(getSectors(2)),
-			},
-		},
 		"addMax": {
 			actions: []action{
 				expectInitialCalls(),
@@ -268,10 +238,10 @@ func TestPrecommitBatcher(t *testing.T) {
 				addSectors(getSectors(maxBatch), true),
 			},
 		},
-		"addMax-belowBaseFee": {
+		"addOne-belowBaseFee": {
 			actions: []action{
-				expectSendsSingle(getSectors(maxBatch)),
-				addSectors(getSectors(maxBatch), false),
+				expectSend(getSectors(1), false),
+				addSectors(getSectors(1), false),
 			},
 		},
 	}
@@ -287,6 +257,7 @@ func TestPrecommitBatcher(t *testing.T) {
 
 			// create them mocks
 			pcapi := mocks.NewMockPreCommitBatcherApi(mockCtrl)
+			pcapi.EXPECT().StateNetworkVersion(gomock.Any(), gomock.Any()).Return(network.Version20, nil).AnyTimes()
 
 			pcb := pipeline.NewPreCommitBatcher(ctx, t0123, pcapi, as, fc, cfg)
 
diff --git a/storage/pipeline/precommit_policy.go b/storage/pipeline/precommit_policy.go
index e1b6e6be767..6e234f93094 100644
--- a/storage/pipeline/precommit_policy.go
+++ b/storage/pipeline/precommit_policy.go
@@ -85,10 +85,15 @@ func (p *BasicPreCommitPolicy) Expiration(ctx context.Context, ps ...api.SectorP
 	}
 
 	if end == nil {
+		nv, err := p.api.StateNetworkVersion(ctx, types.EmptyTSK)
+		if err != nil {
+			return 0, xerrors.Errorf("failed to get network version: %w", err)
+		}
+
 		// no deal pieces, get expiration for committed capacity sector
-		expirationDuration, err := p.getCCSectorLifetime()
+		expirationDuration, err := p.getCCSectorLifetime(nv)
 		if err != nil {
-			return 0, err
+			return 0, xerrors.Errorf("failed to get cc sector lifetime: %w", err)
 		}
 
 		tmp := ts.Height() + expirationDuration
@@ -105,25 +110,30 @@ func (p *BasicPreCommitPolicy) Expiration(ctx context.Context, ps ...api.SectorP
 	return *end, nil
 }
 
-func (p *BasicPreCommitPolicy) getCCSectorLifetime() (abi.ChainEpoch, error) {
+func (p *BasicPreCommitPolicy) getCCSectorLifetime(nv network.Version) (abi.ChainEpoch, error) {
 	c, err := p.getSealingConfig()
 	if err != nil {
 		return 0, xerrors.Errorf("sealing config load error: %w", err)
 	}
 
+	maxCommitment, err := policy.GetMaxSectorExpirationExtension(nv)
+	if err != nil {
+		return 0, xerrors.Errorf("failed to get max extension: %w", err)
+	}
+
 	var ccLifetimeEpochs = abi.ChainEpoch(uint64(c.CommittedCapacitySectorLifetime.Seconds()) / builtin.EpochDurationSeconds)
 	// if zero value in config, assume default sector extension
 	if ccLifetimeEpochs == 0 {
-		ccLifetimeEpochs = policy.GetMaxSectorExpirationExtension()
+		ccLifetimeEpochs = maxCommitment
 	}
 
 	if minExpiration := abi.ChainEpoch(miner.MinSectorExpiration); ccLifetimeEpochs < minExpiration {
 		log.Warnf("value for CommittedCapacitySectorLiftime is too short, using default minimum (%d epochs)", minExpiration)
 		return minExpiration, nil
 	}
-	if maxExpiration := policy.GetMaxSectorExpirationExtension(); ccLifetimeEpochs > maxExpiration {
-		log.Warnf("value for CommittedCapacitySectorLiftime is too long, using default maximum (%d epochs)", maxExpiration)
-		return maxExpiration, nil
+	if ccLifetimeEpochs > maxCommitment {
+		log.Warnf("value for CommittedCapacitySectorLiftime is too long, using default maximum (%d epochs)", maxCommitment)
+		return maxCommitment, nil
 	}
 
 	return ccLifetimeEpochs - p.provingBuffer, nil
diff --git a/storage/pipeline/precommit_policy_test.go b/storage/pipeline/precommit_policy_test.go
index 9f23e58d6c9..7865560dec1 100644
--- a/storage/pipeline/precommit_policy_test.go
+++ b/storage/pipeline/precommit_policy_test.go
@@ -68,7 +68,9 @@ func TestBasicPolicyEmptySector(t *testing.T) {
 	require.NoError(t, err)
 
 	// as set when there are no deal pieces
-	expected := h + policy.GetMaxSectorExpirationExtension() - pBuffer
+	maxExtension, err := policy.GetMaxSectorExpirationExtension(build.TestNetworkVersion)
+	assert.NoError(t, err)
+	expected := h + maxExtension - pBuffer
 	assert.Equal(t, int(expected), int(exp))
 }
 
@@ -132,7 +134,7 @@ func TestBasicPolicyMostConstrictiveSchedule(t *testing.T) {
 
 func TestBasicPolicyIgnoresExistingScheduleIfExpired(t *testing.T) {
 	cfg := fakeConfigGetter(nil)
-	policy := pipeline.NewBasicPreCommitPolicy(&fakeChain{
+	pcp := pipeline.NewBasicPreCommitPolicy(&fakeChain{
 		h: abi.ChainEpoch(55),
 	}, cfg, 0)
 
@@ -152,11 +154,14 @@ func TestBasicPolicyIgnoresExistingScheduleIfExpired(t *testing.T) {
 		},
 	}
 
-	exp, err := policy.Expiration(context.Background(), pieces...)
+	exp, err := pcp.Expiration(context.Background(), pieces...)
+	require.NoError(t, err)
+
+	maxLifetime, err := policy.GetMaxSectorExpirationExtension(build.TestNetworkVersion)
 	require.NoError(t, err)
 
 	// Treated as a CC sector, so expiration becomes currEpoch + maxLifetime = 55 + 1555200
-	assert.Equal(t, 1555255, int(exp))
+	assert.Equal(t, 55+maxLifetime, exp)
 }
 
 func TestMissingDealIsIgnored(t *testing.T) {
diff --git a/storage/pipeline/sealiface/config.go b/storage/pipeline/sealiface/config.go
index dbdb91d54ac..e41b143ec20 100644
--- a/storage/pipeline/sealiface/config.go
+++ b/storage/pipeline/sealiface/config.go
@@ -42,7 +42,6 @@ type Config struct {
 	AvailableBalanceBuffer     abi.TokenAmount
 	DisableCollateralFallback  bool
 
-	BatchPreCommits     bool
 	MaxPreCommitBatch   int
 	PreCommitBatchWait  time.Duration
 	PreCommitBatchSlack time.Duration
@@ -61,4 +60,6 @@ type Config struct {
 	TerminateBatchMax  uint64
 	TerminateBatchMin  uint64
 	TerminateBatchWait time.Duration
+
+	UseSyntheticPoRep bool
 }
diff --git a/storage/pipeline/sealing.go b/storage/pipeline/sealing.go
index d664de1e2a9..65d3fb14b1e 100644
--- a/storage/pipeline/sealing.go
+++ b/storage/pipeline/sealing.go
@@ -15,7 +15,6 @@ import (
 	"github.com/filecoin-project/go-bitfield"
 	"github.com/filecoin-project/go-state-types/abi"
 	"github.com/filecoin-project/go-state-types/big"
-	"github.com/filecoin-project/go-state-types/builtin/v9/miner"
 	verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
 	"github.com/filecoin-project/go-state-types/crypto"
 	"github.com/filecoin-project/go-state-types/dline"
@@ -24,6 +23,7 @@ import (
 	"github.com/filecoin-project/go-storedcounter"
 
 	"github.com/filecoin-project/lotus/api"
+	"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
 	lminer "github.com/filecoin-project/lotus/chain/actors/builtin/miner"
 	"github.com/filecoin-project/lotus/chain/events"
 	"github.com/filecoin-project/lotus/chain/types"
@@ -339,7 +339,12 @@ func (m *Sealing) currentSealProof(ctx context.Context) (abi.RegisteredSealProof
 		return 0, err
 	}
 
-	return lminer.PreferredSealProofTypeFromWindowPoStType(ver, mi.WindowPoStProofType)
+	c, err := m.getConfig()
+	if err != nil {
+		return 0, err
+	}
+
+	return lminer.PreferredSealProofTypeFromWindowPoStType(ver, mi.WindowPoStProofType, c.UseSyntheticPoRep)
 }
 
 func (m *Sealing) minerSector(spt abi.RegisteredSealProof, num abi.SectorNumber) storiface.SectorRef {
diff --git a/storage/pipeline/sector_state.go b/storage/pipeline/sector_state.go
index 84c08f43bdc..e1f5bfd69d5 100644
--- a/storage/pipeline/sector_state.go
+++ b/storage/pipeline/sector_state.go
@@ -82,7 +82,7 @@ const (
 	PreCommit1 SectorState = "PreCommit1" // do PreCommit1
 	PreCommit2 SectorState = "PreCommit2" // do PreCommit2
 
-	PreCommitting SectorState = "PreCommitting" // on chain pre-commit
+	PreCommitting SectorState = "PreCommitting" // on chain pre-commit (deprecated)
 	PreCommitWait SectorState = "PreCommitWait" // waiting for precommit to land on chain
 
 	SubmitPreCommitBatch SectorState = "SubmitPreCommitBatch"
diff --git a/storage/pipeline/states_failed.go b/storage/pipeline/states_failed.go
index d952d8edab5..cf9bd4d121c 100644
--- a/storage/pipeline/states_failed.go
+++ b/storage/pipeline/states_failed.go
@@ -10,12 +10,12 @@ import (
 	"github.com/filecoin-project/go-address"
 	"github.com/filecoin-project/go-commp-utils/zerocomm"
 	"github.com/filecoin-project/go-state-types/abi"
-	"github.com/filecoin-project/go-state-types/builtin/v9/miner"
 	"github.com/filecoin-project/go-state-types/exitcode"
 	"github.com/filecoin-project/go-statemachine"
 
 	"github.com/filecoin-project/lotus/api"
 	"github.com/filecoin-project/lotus/chain/actors/builtin/market"
+	"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
 	"github.com/filecoin-project/lotus/chain/types"
 	"github.com/filecoin-project/lotus/storage/sealer/storiface"
 )
diff --git a/storage/pipeline/states_replica_update.go b/storage/pipeline/states_replica_update.go
index e1b9cfc30e6..6717f49a6a6 100644
--- a/storage/pipeline/states_replica_update.go
+++ b/storage/pipeline/states_replica_update.go
@@ -10,12 +10,12 @@ import (
 	"github.com/filecoin-project/go-state-types/abi"
 	"github.com/filecoin-project/go-state-types/big"
 	"github.com/filecoin-project/go-state-types/builtin"
-	"github.com/filecoin-project/go-state-types/builtin/v9/miner"
 	"github.com/filecoin-project/go-state-types/exitcode"
 	"github.com/filecoin-project/go-statemachine"
 
 	"github.com/filecoin-project/lotus/api"
 	"github.com/filecoin-project/lotus/build"
+	"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
 	"github.com/filecoin-project/lotus/chain/actors/policy"
 	"github.com/filecoin-project/lotus/chain/types"
 )
diff --git a/storage/pipeline/states_sealing.go b/storage/pipeline/states_sealing.go
index 0608ead07f9..3210109ccd0 100644
--- a/storage/pipeline/states_sealing.go
+++ b/storage/pipeline/states_sealing.go
@@ -15,7 +15,6 @@ import (
 	actorstypes "github.com/filecoin-project/go-state-types/actors"
 	"github.com/filecoin-project/go-state-types/big"
 	"github.com/filecoin-project/go-state-types/builtin"
-	"github.com/filecoin-project/go-state-types/builtin/v9/miner"
 	"github.com/filecoin-project/go-state-types/crypto"
 	"github.com/filecoin-project/go-state-types/exitcode"
 	"github.com/filecoin-project/go-state-types/network"
@@ -24,6 +23,7 @@ import (
 
 	"github.com/filecoin-project/lotus/api"
 	"github.com/filecoin-project/lotus/build"
+	"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
 	"github.com/filecoin-project/lotus/chain/actors/policy"
 	"github.com/filecoin-project/lotus/chain/types"
 	"github.com/filecoin-project/lotus/storage/pipeline/lib/nullreader"
@@ -353,7 +353,12 @@ func (m *Sealing) preCommitInfo(ctx statemachine.Context, sector SectorInfo) (*m
 	}
 
 	// Assume: both precommit msg & commit msg land on chain as early as possible
-	maxExpiration := ts.Height() + policy.GetPreCommitChallengeDelay() + policy.GetMaxSectorExpirationExtension()
+	maxExtension, err := policy.GetMaxSectorExpirationExtension(nv)
+	if err != nil {
+		return nil, big.Zero(), types.EmptyTSK, ctx.Send(SectorSealPreCommit1Failed{xerrors.Errorf("failed to get max extension: %w", err)})
+	}
+
+	maxExpiration := ts.Height() + policy.GetPreCommitChallengeDelay() + maxExtension
 	if expiration > maxExpiration {
 		expiration = maxExpiration
 	}
@@ -368,6 +373,10 @@ func (m *Sealing) preCommitInfo(ctx statemachine.Context, sector SectorInfo) (*m
 		DealIDs:       sector.dealIDs(),
 	}
 
+	if sector.hasDeals() {
+		params.UnsealedCid = sector.CommD
+	}
+
 	collateral, err := m.Api.StateMinerPreCommitDepositForPower(ctx.Context(), m.maddr, *params, ts.Key())
 	if err != nil {
 		return nil, big.Zero(), types.EmptyTSK, xerrors.Errorf("getting initial pledge collateral: %w", err)
@@ -377,62 +386,10 @@ func (m *Sealing) preCommitInfo(ctx statemachine.Context, sector SectorInfo) (*m
 }
 
 func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInfo) error {
-	cfg, err := m.getConfig()
-	if err != nil {
-		return xerrors.Errorf("getting config: %w", err)
-	}
-
-	if cfg.BatchPreCommits {
-		nv, err := m.Api.StateNetworkVersion(ctx.Context(), types.EmptyTSK)
-		if err != nil {
-			return xerrors.Errorf("getting network version: %w", err)
-		}
-
-		if nv >= network.Version13 {
-			return ctx.Send(SectorPreCommitBatch{})
-		}
-	}
-
-	info, pcd, tsk, err := m.preCommitInfo(ctx, sector)
-	if err != nil {
-		return ctx.Send(SectorChainPreCommitFailed{xerrors.Errorf("preCommitInfo: %w", err)})
-	}
-	if info == nil {
-		return nil // event was sent in preCommitInfo
-	}
-
-	params := infoToPreCommitSectorParams(info)
-
-	deposit, err := collateralSendAmount(ctx.Context(), m.Api, m.maddr, cfg, pcd)
-	if err != nil {
-		return err
-	}
-
-	enc := new(bytes.Buffer)
-	if err := params.MarshalCBOR(enc); err != nil {
-		return ctx.Send(SectorChainPreCommitFailed{xerrors.Errorf("could not serialize pre-commit sector parameters: %w", err)})
-	}
-
-	mi, err := m.Api.StateMinerInfo(ctx.Context(), m.maddr, tsk)
-	if err != nil {
-		log.Errorf("handlePreCommitting: api error, not proceeding: %+v", err)
-		return nil
-	}
-
-	goodFunds := big.Add(deposit, big.Int(m.feeCfg.MaxPreCommitGasFee))
-
-	from, _, err := m.addrSel.AddressFor(ctx.Context(), m.Api, mi, api.PreCommitAddr, goodFunds, deposit)
-	if err != nil {
-		return ctx.Send(SectorChainPreCommitFailed{xerrors.Errorf("no good address to send precommit message from: %w", err)})
-	}
-
-	log.Infof("submitting precommit for sector %d (deposit: %s): ", sector.SectorNumber, deposit)
-	mcid, err := sendMsg(ctx.Context(), m.Api, from, m.maddr, builtin.MethodsMiner.PreCommitSector, deposit, big.Int(m.feeCfg.MaxPreCommitGasFee), enc.Bytes())
-	if err != nil {
-		return ctx.Send(SectorChainPreCommitFailed{xerrors.Errorf("pushing message to mpool: %w", err)})
-	}
-
-	return ctx.Send(SectorPreCommitted{Message: mcid, PreCommitDeposit: pcd, PreCommitInfo: *info})
+	// note: this is a legacy state handler, normally new sectors won't enter this state
+	// but we keep this handler in order to not break existing sector state machines.
+	// todo: drop after nv21
+	return ctx.Send(SectorPreCommitBatch{})
 }
 
 func (m *Sealing) handleSubmitPreCommitBatch(ctx statemachine.Context, sector SectorInfo) error {
@@ -632,6 +589,7 @@ func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo)
 
 		porepProof, err = m.sealer.SealCommit2(sector.sealingCtx(ctx.Context()), m.minerSector(sector.SectorType, sector.SectorNumber), c2in)
 		if err != nil {
+			log.Errorw("Commit2 error", "error", err)
 			return ctx.Send(SectorComputeProofFailed{xerrors.Errorf("computing seal proof failed(2): %w", err)})
 		}
 	} else {
diff --git a/storage/pipeline/utils.go b/storage/pipeline/utils.go
index ce4283b6cd5..4b99a5beadd 100644
--- a/storage/pipeline/utils.go
+++ b/storage/pipeline/utils.go
@@ -10,7 +10,6 @@ import (
 	"github.com/filecoin-project/go-address"
 	"github.com/filecoin-project/go-state-types/abi"
 	"github.com/filecoin-project/go-state-types/big"
-	"github.com/filecoin-project/go-state-types/builtin/v9/miner"
 
 	"github.com/filecoin-project/lotus/api"
 	"github.com/filecoin-project/lotus/chain/types"
@@ -127,14 +126,3 @@ func sendMsg(ctx context.Context, sa interface {
 
 	return smsg.Cid(), nil
 }
-
-func infoToPreCommitSectorParams(info *miner.SectorPreCommitInfo) *miner.PreCommitSectorParams {
-	return &miner.PreCommitSectorParams{
-		SealProof:     info.SealProof,
-		SectorNumber:  info.SectorNumber,
-		SealedCID:     info.SealedCID,
-		SealRandEpoch: info.SealRandEpoch,
-		DealIDs:       info.DealIDs,
-		Expiration:    info.Expiration,
-	}
-}
diff --git a/storage/sealer/cbor_gen.go b/storage/sealer/cbor_gen.go
index 4fa7fd98042..22da1b52081 100644
--- a/storage/sealer/cbor_gen.go
+++ b/storage/sealer/cbor_gen.go
@@ -40,7 +40,7 @@ func (t *Call) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("ID"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("ID")); err != nil {
+	if _, err := cw.WriteString(string("ID")); err != nil {
 		return err
 	}
 
@@ -56,7 +56,7 @@ func (t *Call) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("State"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("State")); err != nil {
+	if _, err := cw.WriteString(string("State")); err != nil {
 		return err
 	}
 
@@ -72,7 +72,7 @@ func (t *Call) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Result"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Result")); err != nil {
+	if _, err := cw.WriteString(string("Result")); err != nil {
 		return err
 	}
 
@@ -88,7 +88,7 @@ func (t *Call) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("RetType"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("RetType")); err != nil {
+	if _, err := cw.WriteString(string("RetType")); err != nil {
 		return err
 	}
 
@@ -99,7 +99,7 @@ func (t *Call) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.RetType))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string(t.RetType)); err != nil {
+	if _, err := cw.WriteString(string(t.RetType)); err != nil {
 		return err
 	}
 	return nil
@@ -228,7 +228,7 @@ func (t *WorkState) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("ID"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("ID")); err != nil {
+	if _, err := cw.WriteString(string("ID")); err != nil {
 		return err
 	}
 
@@ -244,7 +244,7 @@ func (t *WorkState) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Status"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Status")); err != nil {
+	if _, err := cw.WriteString(string("Status")); err != nil {
 		return err
 	}
 
@@ -255,7 +255,7 @@ func (t *WorkState) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Status))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string(t.Status)); err != nil {
+	if _, err := cw.WriteString(string(t.Status)); err != nil {
 		return err
 	}
 
@@ -267,7 +267,7 @@ func (t *WorkState) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("StartTime"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("StartTime")); err != nil {
+	if _, err := cw.WriteString(string("StartTime")); err != nil {
 		return err
 	}
 
@@ -289,7 +289,7 @@ func (t *WorkState) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("WorkError"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("WorkError")); err != nil {
+	if _, err := cw.WriteString(string("WorkError")); err != nil {
 		return err
 	}
 
@@ -300,7 +300,7 @@ func (t *WorkState) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.WorkError))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string(t.WorkError)); err != nil {
+	if _, err := cw.WriteString(string(t.WorkError)); err != nil {
 		return err
 	}
 
@@ -312,7 +312,7 @@ func (t *WorkState) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("WorkerCall"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("WorkerCall")); err != nil {
+	if _, err := cw.WriteString(string("WorkerCall")); err != nil {
 		return err
 	}
 
@@ -328,7 +328,7 @@ func (t *WorkState) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("WorkerHostname"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("WorkerHostname")); err != nil {
+	if _, err := cw.WriteString(string("WorkerHostname")); err != nil {
 		return err
 	}
 
@@ -339,7 +339,7 @@ func (t *WorkState) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.WorkerHostname))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string(t.WorkerHostname)); err != nil {
+	if _, err := cw.WriteString(string(t.WorkerHostname)); err != nil {
 		return err
 	}
 	return nil
@@ -491,7 +491,7 @@ func (t *WorkID) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Method"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Method")); err != nil {
+	if _, err := cw.WriteString(string("Method")); err != nil {
 		return err
 	}
 
@@ -502,7 +502,7 @@ func (t *WorkID) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Method))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string(t.Method)); err != nil {
+	if _, err := cw.WriteString(string(t.Method)); err != nil {
 		return err
 	}
 
@@ -514,7 +514,7 @@ func (t *WorkID) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Params"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Params")); err != nil {
+	if _, err := cw.WriteString(string("Params")); err != nil {
 		return err
 	}
 
@@ -525,7 +525,7 @@ func (t *WorkID) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Params))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string(t.Params)); err != nil {
+	if _, err := cw.WriteString(string(t.Params)); err != nil {
 		return err
 	}
 	return nil
diff --git a/storage/sealer/ffiwrapper/sealer_cgo.go b/storage/sealer/ffiwrapper/sealer_cgo.go
index 871012d0bed..85c80a9c1c6 100644
--- a/storage/sealer/ffiwrapper/sealer_cgo.go
+++ b/storage/sealer/ffiwrapper/sealer_cgo.go
@@ -825,15 +825,49 @@ func (sb *Sealer) SealPreCommit2(ctx context.Context, sector storiface.SectorRef
 		return storiface.SectorCids{}, xerrors.Errorf("unmarshaling pc1 output: %w", err)
 	}
 
-	var ticket abi.SealRandomness
 	ti, found := p1odec["_lotus_SealRandomness"]
 
+	if abi.Synthetic[sector.ProofType] {
+		if !found {
+			return storiface.SectorCids{}, xerrors.Errorf("synthetic mode: ticket not found")
+		}
+	}
+
 	if found {
-		ticket, err = base64.StdEncoding.DecodeString(ti.(string))
+		ticket, err := base64.StdEncoding.DecodeString(ti.(string))
 		if err != nil {
 			return storiface.SectorCids{}, xerrors.Errorf("decoding ticket: %w", err)
 		}
 
+		if abi.Synthetic[sector.ProofType] {
+			// note: we generate synth porep challenges first because the C1 check below reads from those
+
+			err = ffi.GenerateSynthProofs(
+				sector.ProofType,
+				sealedCID,
+				unsealedCID,
+				paths.Cache,
+				paths.Sealed,
+				sector.ID.Number,
+				sector.ID.Miner, ticket,
+				[]abi.PieceInfo{{Size: abi.PaddedPieceSize(ssize), PieceCID: unsealedCID}})
+			if err != nil {
+				log.Warn("GenerateSynthProofs() failed: ", err)
+				log.Warnf("num:%d tkt:%v, sealedCID:%v, unsealedCID:%v", sector.ID.Number, ticket, sealedCID, unsealedCID)
+				return storiface.SectorCids{}, xerrors.Errorf("generate synth proofs: %w", err)
+			}
+
+			if err = ffi.ClearLayerData(ssize, paths.Cache); err != nil {
+				log.Warn("failed to GenerateSynthProofs(): ", err)
+				log.Warnf("num:%d tkt:%v, sealedCID:%v, unsealedCID:%v", sector.ID.Number, ticket, sealedCID, unsealedCID)
+				return storiface.SectorCids{
+					Unsealed: unsealedCID,
+					Sealed:   sealedCID,
+				}, nil
+				// Note: non-fatal error.
+			}
+		}
+
 		for i := 0; i < PC2CheckRounds; i++ {
 			var sd [32]byte
 			_, _ = rand.Read(sd[:])
@@ -889,6 +923,7 @@ func (sb *Sealer) SealCommit1(ctx context.Context, sector storiface.SectorRef, t
 
 		return nil, xerrors.Errorf("StandaloneSealCommit: %w", err)
 	}
+
 	return output, nil
 }
 
@@ -1078,6 +1113,13 @@ func (sb *Sealer) FinalizeSector(ctx context.Context, sector storiface.SectorRef
 	}
 	defer done()
 
+	if abi.Synthetic[sector.ProofType] {
+		if err = ffi.ClearSyntheticProofs(uint64(ssize), paths.Cache); err != nil {
+			log.Warn("Unable to delete Synth cache:", err)
+			// Pass-Thru on error.
+		}
+	}
+
 	return ffi.ClearCache(uint64(ssize), paths.Cache)
 }
 
@@ -1116,6 +1158,13 @@ func (sb *Sealer) FinalizeSectorInto(ctx context.Context, sector storiface.Secto
 		}
 	}
 
+	if abi.Synthetic[sector.ProofType] {
+		if err = ffi.ClearSyntheticProofs(uint64(ssize), dest); err != nil {
+			log.Warn("Unable to delete Synth cache:", err)
+			// Pass-Thru on error.
+		}
+	}
+
 	return ffi.ClearCache(uint64(ssize), dest)
 }
 
@@ -1132,6 +1181,12 @@ func (sb *Sealer) FinalizeReplicaUpdate(ctx context.Context, sector storiface.Se
 		}
 		defer done()
 
+		if abi.Synthetic[sector.ProofType] {
+			if err = ffi.ClearSyntheticProofs(uint64(ssize), paths.Cache); err != nil {
+				return xerrors.Errorf("clear synth cache: %w", err)
+			}
+		}
+
 		if err := ffi.ClearCache(uint64(ssize), paths.Cache); err != nil {
 			return xerrors.Errorf("clear cache: %w", err)
 		}
@@ -1144,6 +1199,8 @@ func (sb *Sealer) FinalizeReplicaUpdate(ctx context.Context, sector storiface.Se
 		}
 		defer done()
 
+		// note: synth cache is not a thing for snapdeals
+
 		if err := ffi.ClearCache(uint64(ssize), paths.UpdateCache); err != nil {
 			return xerrors.Errorf("clear cache: %w", err)
 		}
diff --git a/storage/sealer/ffiwrapper/sealer_test.go b/storage/sealer/ffiwrapper/sealer_test.go
index 4d3b1a9be03..98c562fd2fd 100644
--- a/storage/sealer/ffiwrapper/sealer_test.go
+++ b/storage/sealer/ffiwrapper/sealer_test.go
@@ -1066,7 +1066,111 @@ func TestDCAPCloses(t *testing.T) {
 		require.Equal(t, "baga6ea4seaqeje7jy4hufnybpo7ckxzujaigqbcxhdjq7ojb4b6xzgqdugkyciq", c.PieceCID.String())
 		require.True(t, clr.closed)
 	})
+}
+
+func TestSealAndVerifySynth(t *testing.T) {
+	sealProofType = abi.RegisteredSealProof_StackedDrg2KiBV1_1_Feat_SyntheticPoRep
+
+	if testing.Short() {
+		t.Skip("skipping test in short mode")
+	}
+
+	defer requireFDsClosed(t, openFDs(t))
+
+	if runtime.NumCPU() < 10 && os.Getenv("CI") == "" { // don't bother on slow hardware
+		t.Skip("this is slow")
+	}
+	_ = os.Setenv("RUST_LOG", "info")
+
+	getGrothParamFileAndVerifyingKeys(sectorSize)
+
+	cdir, err := os.MkdirTemp("", "sbtest-c-")
+	if err != nil {
+		t.Fatal(err)
+	}
+	miner := abi.ActorID(123)
+
+	synthPorRepVProofsName := "syn-porep-vanilla-proofs.dat"
+
+	printFileList := func(stage string, expectSynthPorep bool) {
+		var hasSynthPorep bool
+
+		fmt.Println("----file list:", stage)
+		err := filepath.Walk(cdir, func(path string, info os.FileInfo, err error) error {
+			if strings.Contains(path, synthPorRepVProofsName) {
+				hasSynthPorep = true
+			}
+			fmt.Println(path)
+			return nil
+		})
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		require.Equal(t, expectSynthPorep, hasSynthPorep)
+
+		fmt.Println("----")
+	}
+
+	sp := &basicfs.Provider{
+		Root: cdir,
+	}
+	sb, err := New(sp)
+	if err != nil {
+		t.Fatalf("%+v", err)
+	}
+	t.Cleanup(func() {
+		if t.Failed() {
+			fmt.Printf("not removing %s\n", cdir)
+			return
+		}
+		if err := os.RemoveAll(cdir); err != nil {
+			t.Error(err)
+		}
+	})
+
+	si := storiface.SectorRef{
+		ID:        abi.SectorID{Miner: miner, Number: 1},
+		ProofType: sealProofType,
+	}
+
+	s := seal{ref: si}
+
+	start := time.Now()
+
+	s.precommit(t, sb, si, func() {})
+
+	printFileList("precommit", true)
+
+	precommit := time.Now()
+
+	s.commit(t, sb, func() {})
 
+	printFileList("commit", true)
+
+	commit := time.Now()
+
+	post(t, sb, nil, s)
+
+	printFileList("post", true)
+
+	epost := time.Now()
+
+	post(t, sb, nil, s)
+
+	if err := sb.FinalizeSector(context.TODO(), si); err != nil {
+		t.Fatalf("%+v", err)
+	}
+
+	printFileList("finalize", false)
+
+	s.unseal(t, sb, sp, si, func() {})
+
+	printFileList("unseal", false)
+
+	fmt.Printf("PreCommit: %s\n", precommit.Sub(start).String())
+	fmt.Printf("Commit: %s\n", commit.Sub(precommit).String())
+	fmt.Printf("EPoSt: %s\n", epost.Sub(commit).String())
 }
 
 type closeAssertReader struct {
diff --git a/storage/sealer/manager_test.go b/storage/sealer/manager_test.go
index 8acd474a391..99ead1e8e6d 100644
--- a/storage/sealer/manager_test.go
+++ b/storage/sealer/manager_test.go
@@ -21,13 +21,16 @@ import (
 	logging "github.com/ipfs/go-log/v2"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+	"golang.org/x/xerrors"
 
 	ffi "github.com/filecoin-project/filecoin-ffi"
+	"github.com/filecoin-project/go-paramfetch"
 	"github.com/filecoin-project/go-state-types/abi"
 	"github.com/filecoin-project/go-state-types/proof"
 	"github.com/filecoin-project/go-statestore"
 	proof7 "github.com/filecoin-project/specs-actors/v7/actors/runtime/proof"
 
+	"github.com/filecoin-project/lotus/build"
 	"github.com/filecoin-project/lotus/storage/paths"
 	"github.com/filecoin-project/lotus/storage/sealer/ffiwrapper"
 	"github.com/filecoin-project/lotus/storage/sealer/fsutil"
@@ -198,6 +201,16 @@ func (m NullReader) NullBytes() int64 {
 	return m.N
 }
 
+func TestMain(m *testing.M) {
+	err := paramfetch.GetParams(context.TODO(), build.ParametersJSON(), build.SrsJSON(), uint64(2048))
+	if err != nil {
+		panic(xerrors.Errorf("failed to acquire Groth parameters for 2KiB sectors: %w", err))
+	}
+
+	code := m.Run()
+	os.Exit(code)
+}
+
 func TestSnapDeals(t *testing.T) {
 	logging.SetAllLoggers(logging.LevelWarn)
 	ctx := context.Background()
diff --git a/storage/sealer/storiface/cbor_gen.go b/storage/sealer/storiface/cbor_gen.go
index 2f82da3e6ef..0b42136ead3 100644
--- a/storage/sealer/storiface/cbor_gen.go
+++ b/storage/sealer/storiface/cbor_gen.go
@@ -38,7 +38,7 @@ func (t *CallID) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("ID"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("ID")); err != nil {
+	if _, err := cw.WriteString(string("ID")); err != nil {
 		return err
 	}
 
@@ -62,7 +62,7 @@ func (t *CallID) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Sector"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Sector")); err != nil {
+	if _, err := cw.WriteString(string("Sector")); err != nil {
 		return err
 	}
 
@@ -173,7 +173,7 @@ func (t *SecDataHttpHeader) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Key"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Key")); err != nil {
+	if _, err := cw.WriteString(string("Key")); err != nil {
 		return err
 	}
 
@@ -184,7 +184,7 @@ func (t *SecDataHttpHeader) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Key))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string(t.Key)); err != nil {
+	if _, err := cw.WriteString(string(t.Key)); err != nil {
 		return err
 	}
 
@@ -196,7 +196,7 @@ func (t *SecDataHttpHeader) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Value"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Value")); err != nil {
+	if _, err := cw.WriteString(string("Value")); err != nil {
 		return err
 	}
 
@@ -207,7 +207,7 @@ func (t *SecDataHttpHeader) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Value))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string(t.Value)); err != nil {
+	if _, err := cw.WriteString(string(t.Value)); err != nil {
 		return err
 	}
 	return nil
@@ -302,7 +302,7 @@ func (t *SectorLocation) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("URL"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("URL")); err != nil {
+	if _, err := cw.WriteString(string("URL")); err != nil {
 		return err
 	}
 
@@ -313,7 +313,7 @@ func (t *SectorLocation) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.URL))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string(t.URL)); err != nil {
+	if _, err := cw.WriteString(string(t.URL)); err != nil {
 		return err
 	}
 
@@ -325,7 +325,7 @@ func (t *SectorLocation) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Local"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Local")); err != nil {
+	if _, err := cw.WriteString(string("Local")); err != nil {
 		return err
 	}
 
@@ -341,7 +341,7 @@ func (t *SectorLocation) MarshalCBOR(w io.Writer) error {
 	if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("Headers"))); err != nil {
 		return err
 	}
-	if _, err := io.WriteString(w, string("Headers")); err != nil {
+	if _, err := cw.WriteString(string("Headers")); err != nil {
 		return err
 	}
 
@@ -448,13 +448,22 @@ func (t *SectorLocation) UnmarshalCBOR(r io.Reader) (err error) {
 			}
 
 			for i := 0; i < int(extra); i++ {
+				{
+					var maj byte
+					var extra uint64
+					var err error
+					_ = maj
+					_ = extra
+					_ = err
 
-				var v SecDataHttpHeader
-				if err := v.UnmarshalCBOR(cr); err != nil {
-					return err
-				}
+					{
 
-				t.Headers[i] = v
+						if err := t.Headers[i].UnmarshalCBOR(cr); err != nil {
+							return xerrors.Errorf("unmarshaling t.Headers[i]: %w", err)
+						}
+
+					}
+				}
 			}
 
 		default:
diff --git a/storage/sealer/storiface/resources.go b/storage/sealer/storiface/resources.go
index 0fd80d79ab0..6f8d83265a6 100644
--- a/storage/sealer/storiface/resources.go
+++ b/storage/sealer/storiface/resources.go
@@ -587,13 +587,18 @@ func init() {
 		ResourceTable[sealtasks.TTDataCid][proof] = ResourceTable[sealtasks.TTAddPiece][abi.RegisteredSealProof_StackedDrg32GiBV1]
 	}
 
-	// V1_1 is the same as V1
+	// V1_1 and SynthethicpoRep is the same as V1
 	for _, m := range ResourceTable {
 		m[abi.RegisteredSealProof_StackedDrg2KiBV1_1] = m[abi.RegisteredSealProof_StackedDrg2KiBV1]
+		m[abi.RegisteredSealProof_StackedDrg2KiBV1_1_Feat_SyntheticPoRep] = m[abi.RegisteredSealProof_StackedDrg2KiBV1]
 		m[abi.RegisteredSealProof_StackedDrg8MiBV1_1] = m[abi.RegisteredSealProof_StackedDrg8MiBV1]
+		m[abi.RegisteredSealProof_StackedDrg8MiBV1_1_Feat_SyntheticPoRep] = m[abi.RegisteredSealProof_StackedDrg8MiBV1]
 		m[abi.RegisteredSealProof_StackedDrg512MiBV1_1] = m[abi.RegisteredSealProof_StackedDrg512MiBV1]
+		m[abi.RegisteredSealProof_StackedDrg512MiBV1_1_Feat_SyntheticPoRep] = m[abi.RegisteredSealProof_StackedDrg512MiBV1]
 		m[abi.RegisteredSealProof_StackedDrg32GiBV1_1] = m[abi.RegisteredSealProof_StackedDrg32GiBV1]
+		m[abi.RegisteredSealProof_StackedDrg32GiBV1_1_Feat_SyntheticPoRep] = m[abi.RegisteredSealProof_StackedDrg32GiBV1]
 		m[abi.RegisteredSealProof_StackedDrg64GiBV1_1] = m[abi.RegisteredSealProof_StackedDrg64GiBV1]
+		m[abi.RegisteredSealProof_StackedDrg64GiBV1_1_Feat_SyntheticPoRep] = m[abi.RegisteredSealProof_StackedDrg64GiBV1]
 	}
 }
 
diff --git a/storage/wdpost/wdpost_changehandler.go b/storage/wdpost/wdpost_changehandler.go
index 266b8b0421a..5f4b0ca0c3e 100644
--- a/storage/wdpost/wdpost_changehandler.go
+++ b/storage/wdpost/wdpost_changehandler.go
@@ -6,9 +6,9 @@ import (
 
 	"github.com/filecoin-project/go-address"
 	"github.com/filecoin-project/go-state-types/abi"
-	"github.com/filecoin-project/go-state-types/builtin/v9/miner"
 	"github.com/filecoin-project/go-state-types/dline"
 
+	"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
 	"github.com/filecoin-project/lotus/chain/types"
 )
 
@@ -531,12 +531,12 @@ func nextDeadline(currentDeadline *dline.Info) *dline.Info {
 	newDeadline := currentDeadline.Index + 1
 	if newDeadline == miner.WPoStPeriodDeadlines {
 		newDeadline = 0
-		periodStart = periodStart + miner.WPoStProvingPeriod
+		periodStart = periodStart + miner.WPoStProvingPeriod()
 	}
 
 	return NewDeadlineInfo(periodStart, newDeadline, currentDeadline.CurrentEpoch)
 }
 
 func NewDeadlineInfo(periodStart abi.ChainEpoch, deadlineIdx uint64, currEpoch abi.ChainEpoch) *dline.Info {
-	return dline.NewInfo(periodStart, deadlineIdx, currEpoch, miner.WPoStPeriodDeadlines, miner.WPoStProvingPeriod, miner.WPoStChallengeWindow, miner.WPoStChallengeLookback, miner.FaultDeclarationCutoff)
+	return dline.NewInfo(periodStart, deadlineIdx, currEpoch, miner.WPoStPeriodDeadlines, miner.WPoStProvingPeriod(), miner.WPoStChallengeWindow(), miner.WPoStChallengeLookback, miner.FaultDeclarationCutoff)
 }
diff --git a/storage/wdpost/wdpost_journal.go b/storage/wdpost/wdpost_journal.go
index 406628f681b..68cad3fcf3f 100644
--- a/storage/wdpost/wdpost_journal.go
+++ b/storage/wdpost/wdpost_journal.go
@@ -4,8 +4,9 @@ import (
 	"github.com/ipfs/go-cid"
 
 	"github.com/filecoin-project/go-state-types/abi"
-	"github.com/filecoin-project/go-state-types/builtin/v9/miner"
 	"github.com/filecoin-project/go-state-types/dline"
+
+	"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
 )
 
 // SchedulerState defines the possible states in which the scheduler could be,
diff --git a/storage/wdpost/wdpost_run.go b/storage/wdpost/wdpost_run.go
index c2a448fb093..d70d0254fde 100644
--- a/storage/wdpost/wdpost_run.go
+++ b/storage/wdpost/wdpost_run.go
@@ -15,7 +15,6 @@ import (
 	"github.com/filecoin-project/go-state-types/abi"
 	"github.com/filecoin-project/go-state-types/big"
 	"github.com/filecoin-project/go-state-types/builtin"
-	"github.com/filecoin-project/go-state-types/builtin/v9/miner"
 	"github.com/filecoin-project/go-state-types/crypto"
 	"github.com/filecoin-project/go-state-types/dline"
 	"github.com/filecoin-project/go-state-types/network"
@@ -25,6 +24,7 @@ import (
 	"github.com/filecoin-project/lotus/api"
 	"github.com/filecoin-project/lotus/build"
 	"github.com/filecoin-project/lotus/chain/actors"
+	"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
 	"github.com/filecoin-project/lotus/chain/actors/policy"
 	"github.com/filecoin-project/lotus/chain/messagepool"
 	"github.com/filecoin-project/lotus/chain/types"
diff --git a/storage/wdpost/wdpost_run_faults.go b/storage/wdpost/wdpost_run_faults.go
index 2474ce77b3c..ebdd66a69f8 100644
--- a/storage/wdpost/wdpost_run_faults.go
+++ b/storage/wdpost/wdpost_run_faults.go
@@ -14,12 +14,12 @@ import (
 	"github.com/filecoin-project/go-bitfield"
 	"github.com/filecoin-project/go-state-types/abi"
 	"github.com/filecoin-project/go-state-types/builtin"
-	"github.com/filecoin-project/go-state-types/builtin/v9/miner"
 	"github.com/filecoin-project/go-state-types/dline"
 
 	"github.com/filecoin-project/lotus/api"
 	"github.com/filecoin-project/lotus/build"
 	"github.com/filecoin-project/lotus/chain/actors"
+	"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
 	"github.com/filecoin-project/lotus/chain/types"
 )
 
diff --git a/storage/wdpost/wdpost_run_test.go b/storage/wdpost/wdpost_run_test.go
index bfc9ef9c1c3..a3847a6f6bd 100644
--- a/storage/wdpost/wdpost_run_test.go
+++ b/storage/wdpost/wdpost_run_test.go
@@ -298,7 +298,7 @@ func TestWDPostDoPostPartLimitConfig(t *testing.T) {
 	//stm: @CHAIN_SYNCER_COLLECT_CHAIN_001, @CHAIN_SYNCER_COLLECT_HEADERS_001, @CHAIN_SYNCER_VALIDATE_TIPSET_001
 	//stm: @CHAIN_SYNCER_NEW_PEER_HEAD_001, @CHAIN_SYNCER_VALIDATE_MESSAGE_META_001, @CHAIN_SYNCER_STOP_001
 	ctx := context.Background()
-	expectedMsgCount := 364
+	expectedMsgCount := 8
 
 	proofType := abi.RegisteredPoStProof_StackedDrgWindow2KiBV1
 	postAct := tutils.NewIDAddr(t, 100)
@@ -318,15 +318,15 @@ func TestWDPostDoPostPartLimitConfig(t *testing.T) {
 		partitionsPerMsg = minertypes.AddressedPartitionsMax
 	}
 
-	partitionCount := 4 * partitionsPerMsg
+	partitionCount := 5 * partitionsPerMsg
 
 	// Assert that user config is less than network limit
-	userPartLimit := 33
-	lastMsgParts := 21
-	require.Greater(t, partitionCount, userPartLimit)
+	userPartLimit := 2
+	lastMsgParts := 1
+	require.Greater(t, partitionsPerMsg, userPartLimit)
 
 	// Assert that we consts are correct
-	require.Equal(t, (expectedMsgCount-1)*userPartLimit+lastMsgParts, 4*partitionsPerMsg)
+	require.Equal(t, (expectedMsgCount-1)*userPartLimit+lastMsgParts, partitionCount)
 
 	var partitions []api.Partition
 	for p := 0; p < partitionCount; p++ {
@@ -398,7 +398,7 @@ func TestBatchPartitionsRecoverySectors(t *testing.T) {
 
 	mockStgMinerAPI := newMockStorageMinerAPI()
 
-	userPartLimit := 4
+	userPartLimit := 2
 
 	scheduler := &WindowPoStScheduler{
 		api:          mockStgMinerAPI,
@@ -426,12 +426,12 @@ func TestBatchPartitionsRecoverySectors(t *testing.T) {
 	}
 	partitions = append(partitions, generatePartition(100, 10))
 
-	expectedBatchLens := []int{4, 1, 1, 4, 2, 1}
+	expectedBatchLens := []int{2, 2, 1, 1, 2, 2, 2, 1}
 
-	batches, err := scheduler.BatchPartitions(partitions, network.Version16)
+	batches, err := scheduler.BatchPartitions(partitions, network.Version21)
 	require.NoError(t, err)
 
-	require.Equal(t, len(batches), 6)
+	require.Equal(t, len(batches), len(expectedBatchLens))
 
 	for i, batch := range batches {
 		require.Equal(t, len(batch), expectedBatchLens[i])
diff --git a/storage/wdpost/wdpost_sched.go b/storage/wdpost/wdpost_sched.go
index 29c39ad9e44..8e2a8bc96dd 100644
--- a/storage/wdpost/wdpost_sched.go
+++ b/storage/wdpost/wdpost_sched.go
@@ -12,14 +12,13 @@ import (
 	"github.com/filecoin-project/go-address"
 	"github.com/filecoin-project/go-bitfield"
 	"github.com/filecoin-project/go-state-types/abi"
-	"github.com/filecoin-project/go-state-types/builtin/v9/miner"
 	"github.com/filecoin-project/go-state-types/crypto"
 	"github.com/filecoin-project/go-state-types/dline"
 	"github.com/filecoin-project/go-state-types/network"
 
 	"github.com/filecoin-project/lotus/api"
 	"github.com/filecoin-project/lotus/build"
-	lminer "github.com/filecoin-project/lotus/chain/actors/builtin/miner"
+	"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
 	"github.com/filecoin-project/lotus/chain/store"
 	"github.com/filecoin-project/lotus/chain/types"
 	"github.com/filecoin-project/lotus/journal"
@@ -45,7 +44,7 @@ type NodeAPI interface {
 	StateMinerPartitions(context.Context, address.Address, uint64, types.TipSetKey) ([]api.Partition, error)
 	StateLookupID(context.Context, address.Address, types.TipSetKey) (address.Address, error)
 	StateAccountKey(context.Context, address.Address, types.TipSetKey) (address.Address, error)
-	StateSectorPartition(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok types.TipSetKey) (*lminer.SectorLocation, error)
+	StateSectorPartition(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok types.TipSetKey) (*miner.SectorLocation, error)
 
 	MpoolPushMessage(context.Context, *types.Message, *api.MessageSendSpec) (*types.SignedMessage, error)