Skip to content

Commit 464fd35

Browse files
feat: allow upload/retrieve of assets of arbitrary size from asset canister (#1482)
Per the [design doc](https://github.com/dfinity/sdk/blob/master/docs/design/asset-canister.adoc): 1. Adds asset canister methods: - create_batch() - create_chunk() - commit_batch() - get() - get_chunk() 2. Reworks the asset installer in `dfx` to use these methods. It can therefore upload assets that exceed the message ingress size. Separate work (which this PR enables) will have to update `agent-js` to download these large assets. Other than allowing the storage and retrieval of large assets, this PR does not address: - multiple content types and content encodings: in this PR `dfx` always uploads with `content-type: application/octet-stream` and `content-encoding: identity` - smart/correct synchronization: in this PR `dfx` always uploads all assets (even those that have not changed), and still does not delete assets that were previously uploaded but no longer exist. - All assets and chunks are uploaded in series. See #1491 and dfinity/agent-rs#125 - The `store()`, `retrieve()`, and `list()` method signatures are unchanged for the time being, for backward compatibility. Later work will remove the `retrieve()` method, change the semantics and parameters of `store()`, and change the parameters and return type of `list()`. ``` Uploading assets to asset canister... large-asset.bin 1/7 (1900000 bytes) large-asset.bin 2/7 (1900000 bytes) large-asset.bin 3/7 (1900000 bytes) large-asset.bin 4/7 (1900000 bytes) large-asset.bin 5/7 (1900000 bytes) large-asset.bin 6/7 (1900000 bytes) large-asset.bin 7/7 (1100000 bytes) index.js 1/1 (1218 bytes) sample-asset.txt 1/1 (24 bytes) index.js.map 1/1 (5625 bytes) ```
1 parent 85d3618 commit 464fd35

File tree

11 files changed

+1041
-112
lines changed

11 files changed

+1041
-112
lines changed

CHANGELOG.adoc

+9-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,15 @@ This commit also upgrades tokio and reqwest in order to work correctly. There ar
1919

2020
Renamed the `project_name` in our own generated assets to `canister_name`, for things that are generated during canister build (and not project generation).
2121

22-
---
22+
== Asset Canister
23+
24+
=== feat: The asset canister can now store assets that exceed the message ingress limit (2 MB)
25+
26+
* Please note that neither the JS agent nor the HTTP server have been updated yet to server such large assets.
27+
* The existing interface is left in place for backwards-compatibility, but deprecated:
28+
** retrieve(): use get() and get_chunk() instead
29+
** store(): use create_batch(), create_chunk(), and commit_batch() instead
30+
** list(): use keys() instead
2331

2432
= 0.6.25
2533

distributed-canisters.nix

+4-4
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,19 @@ pkgs.runCommandNoCCLocal "distributed-canisters" {
1212
} ''
1313
mkdir -p $out
1414
15-
for canister_mo in ${distributed}/*.mo; do
16-
canister_name=$(basename -s .mo $canister_mo)
15+
for canister_dir in $(find ${distributed} -mindepth 1 -maxdepth 1 -type d); do
16+
canister_name=$(basename $canister_dir)
1717
1818
build_dir=$out/$canister_name
1919
mkdir -p $build_dir
2020
2121
$moc/bin/moc \
22-
$canister_mo \
22+
$canister_dir/Main.mo \
2323
-o $build_dir/$canister_name.did \
2424
--idl \
2525
--package base $base
2626
$moc/bin/moc \
27-
$canister_mo \
27+
$canister_dir/Main.mo \
2828
-o $build_dir/$canister_name.wasm \
2929
-c --release \
3030
--package base $base

e2e/tests-dfx/assetscanister.bash

+44
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,47 @@ teardown() {
6262
it's cherry season
6363
CHERRIES" "$stdout"
6464
}
65+
66+
@test 'can store arbitrarily large files' {
67+
[ "$USE_IC_REF" ] && skip "skip for ic-ref" # this takes too long for ic-ref's wasm interpreter
68+
69+
install_asset assetscanister
70+
71+
dfx_start
72+
dfx canister create --all
73+
dfx build
74+
dfx canister install e2e_project_assets
75+
76+
dd if=/dev/urandom of=src/e2e_project_assets/assets/large-asset.bin bs=1000000 count=6
77+
78+
dfx deploy
79+
80+
assert_command dfx canister call --query e2e_project_assets get '(record{key="/large-asset.bin";accept_encodings=vec{"identity"}})'
81+
assert_match 'total_length = 6_000_000'
82+
assert_match 'content_type = "application/octet-stream"'
83+
assert_match 'content_encoding = "identity"'
84+
85+
assert_command dfx canister call --query e2e_project_assets get_chunk '(record{key="/large-asset.bin";content_encoding="identity";index=2})'
86+
87+
assert_command dfx canister call --query e2e_project_assets get_chunk '(record{key="/large-asset.bin";content_encoding="identity";index=3})'
88+
assert_command_fail dfx canister call --query e2e_project_assets get_chunk '(record{key="/large-asset.bin";content_encoding="identity";index=4})'
89+
}
90+
91+
@test "list() and keys() return asset keys" {
92+
install_asset assetscanister
93+
94+
dfx_start
95+
dfx canister create --all
96+
dfx build
97+
dfx canister install e2e_project_assets
98+
99+
assert_command dfx canister call --query e2e_project_assets list
100+
assert_match '"/binary/noise.txt"'
101+
assert_match '"/text-with-newlines.txt"'
102+
assert_match '"/sample-asset.txt"'
103+
104+
assert_command dfx canister call --query e2e_project_assets keys
105+
assert_match '"/binary/noise.txt"'
106+
assert_match '"/text-with-newlines.txt"'
107+
assert_match '"/sample-asset.txt"'
108+
}

0 commit comments

Comments
 (0)