Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/guides/backends/data-persistence.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,7 @@ If the count drops to 0 after upgrade, the data is not in stable memory. Review
| Heap | 4 GiB | No (Rust) / Yes (Motoko `persistent actor`) | Frequently accessed data, caches, ephemeral computation |
| Stable | 500 GiB | Yes | All important data, large datasets, anything that must survive upgrades |

The practical rule: **use stable structures directly for any data that matters**. Avoid relying on `pre_upgrade` / `post_upgrade` hooks to serialize heap data to stable memory. Serializing large heap state during an upgrade can hit the instruction limit and trap, leaving the canister on the old code. Data in stable structures is already in stable memory from the first write no serialization step required on upgrade.
The practical rule: **use stable structures directly for any data that matters**. Avoid relying on `pre_upgrade` / `post_upgrade` hooks to serialize heap data to stable memory. Serializing large heap state during an upgrade can hit the instruction limit and trap, leaving the canister on the old code. Data in stable structures is already in stable memory from the first write, with no serialization step required on upgrade.

For Motoko, `persistent actor` makes all `let` and `var` declarations persistent automatically. There is no need to choose manually between heap and stable memory.

Expand Down
2 changes: 1 addition & 1 deletion docs/guides/digital-assets/chain-key-tokens.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ The ckETH minter handles both ETH and ERC-20 deposits using a shared Ethereum he
1. Call `depositEth` on the ckETH helper contract on Ethereum (mainnet: `0x18901044688D3756C35Ed2b36D93e6a5B8e00E68`), passing:
- The amount of ETH.
- Your ICP principal encoded as `bytes32`.
- A 32-byte subaccount (`0x` for the default account, or a derived subaccount for per-user deposits see [Per-user deposit addresses](#per-user-deposit-addresses)).
- A 32-byte subaccount (`0x` for the default account, or a derived subaccount for per-user deposits; see [Per-user deposit addresses](#per-user-deposit-addresses)).
2. The minter detects the `ReceivedEthOrErc20` event and mints ckETH to `(principal, subaccount)` after roughly 20 minutes.

> The ckETH deposit flow requires an Ethereum wallet or library. For sending Ethereum transactions from an ICP canister, see [Ethereum integration](../chain-fusion/ethereum.md).
Expand Down
11 changes: 8 additions & 3 deletions scripts/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,13 @@ function checkFrontmatter(file, content) {
}
}

// `checkForbiddenPatterns` skips fenced code, so these patterns only ever see
// prose. `mo:base` is the exception: what must never appear is an *import*
// (`mo:base/Buffer`), which lives inside a fence, while naming the legacy
// library in prose is legitimate (base-to-core migration tables do it). It
// therefore matches the import path and is checked inside fences too.
const FORBIDDEN = [
{ re: /mo:base/, msg: '"mo:base" is banned — use "mo:core" instead' },
{ re: /mo:base\//, msg: '"mo:base/" import is banned — use "mo:core" instead', includeFences: true },
{ re: /https?:\/\/(?:www\.)?internetcomputer\.org\/docs/, msg: 'internetcomputer.org/docs is retired — link internally or inline' },
{ re: /docs\.internetcomputer\.org/, msg: 'docs.internetcomputer.org is this site — use relative paths for internal links' },
];
Expand Down Expand Up @@ -68,8 +73,8 @@ function checkForbiddenPatterns(file, content) {
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
if (/^```/.test(line.trimStart())) { inFence = !inFence; continue; }
if (inFence) continue;
for (const { re, msg } of FORBIDDEN) {
for (const { re, msg, includeFences } of FORBIDDEN) {
if (inFence && !includeFences) continue;
if (re.test(line)) errors.push(`line ${i + 1}: ${msg}`);
}
}
Expand Down
Loading