Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update snapshots page, practice and scripts #212

Merged
merged 6 commits into from
Jul 20, 2023
Merged
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
194 changes: 50 additions & 144 deletions content/contributor/content/practice/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,143 +13,92 @@ You can use [`httpie`](https://github.com/httpie/httpie) or format responses wit
This is what we'll do:

1. Query the status of the content server.
2. Locate and download the [snapshot]({{< relref "snapshots" >}}) for a list of entities.
2. Locate and download a daily [snapshot]({{< relref "snapshots" >}}) with a list of entities.
3. Obtain the manifest for an entity.
4. Download some of the entity's files.
4. Download one of the entity's files.

Let's begin by querying the server status using `/about`:

```bash
curl "https://peer.decentraland.org/about"
```

```json
```js
{
"healthy": true,
"acceptingUsers": true,
"bff": {
"commitHash": "1a2ff915a216191ecc6ef85f3822f0809fe16f3c",
"healthy": true,
"protocolVersion": "1.0_0",
"publicUrl": "/bff",
"userCount": 12
},
"comms": {
"commitHash": "ad06af3339484411eb639e402462fd2715ce80f6",
"healthy": true,
"protocol": "v3"
},
"content": {
"commitHash": "d6e5d094ef81e2d5630eba9f3eaba2bdc21f5b13",
"healthy": true,
"publicUrl": "https://peer-ec1.decentraland.org/content/",
"version": "5.1.9"
},
"lambdas": {
"commitHash": "b80be3b95e0e8d5b4c9295e7f89fc6f17f7d8a8d",
"healthy": true,
"publicUrl": "https://peer-ec1.decentraland.org/lambdas/",
"version": "5.1.10"
},
"configurations": {
"globalScenesUrn": [],
"networkId": 1,
"realmName": "hephaestus",
"scenesUrn": []
"version": "6.5.0",
},
// ... more server information (feature flags, versions, paths, etc.)
}
```

Looks like the server is up and running normally (`"healthy": true`), and is giving us information about the version it implements for each feature set, plus some configuration options of the instance.

We're interested in downloading some content, so let's explore the available [snapshots]({{< relref "snapshots" >}}) to get our hands on some identifiers via `/content/snapshot`.
We're interested in downloading some content, so let's explore the available [snapshots]({{< relref "snapshots" >}}) to get our hands on some identifiers via `/content/snapshots`.

```bash
curl "https://peer.decentraland.org/content/snapshot"
curl "https://peer.decentraland.org/content/snapshots"
```

```json
{
"hash": "bafybeibtfyox4mho6nfxtfibvol3h6mvnsduslofnwuej33eag2yqgw5bi",
"lastIncludedDeploymentTimestamp": 1671631795620,
"entities": {
"scene": {
"hash": "bafybeiadxlvdmgmzhvhrgbgzumfdp52i7ubzmhq5sxfyfiivcjuxyddl54",
"lastIncludedDeploymentTimestamp": 1671631464866
},
"profile": {
"hash": "bafybeib6mk6p2ymod7lmsw6ttsacbmkgmvwpn23jmdkpkfdzvgvp7lzaeu",
"lastIncludedDeploymentTimestamp": 1671631795620
},
"wearable": {
"hash": "bafybeidcl3kmsnufkvl7tlmeussajiqiqqzsq3uto7m5wrzhstnix5f6vu",
"lastIncludedDeploymentTimestamp": 1671630538830
},
"store": {
"hash": "bafybeidq2yivbl5wlozds4okldqlb6uesqeflb7k6hyygyr7xjx63h5eta",
"lastIncludedDeploymentTimestamp": 1671604715626
```js
[
{
"hash": "bafybeia6qoum64psaooiqo3f45i6hykfwx723uc236waub3gng2naof224",
"timeRange": {
"initTimestamp": 1689120000000,
"endTimestamp": 1689206400000
},
"emote": {
"hash": "bafkreialb5j2vhhes3dorynuyvkbvh3nxddjtadmupaukr4da7peyvlfny",
"lastIncludedDeploymentTimestamp": 1671621566675
}
}
}
"replacedSnapshotHashes": [],
"numberOfEntities": 981,
"generationTimestamp": 1689219353866
},
// ...more snapshot files
]
```

There we have the [file identifiers](({{< relref "filesystem#identifiers" >}})) for each [snapshot]({{< relref "snapshots" >}}) file. Say we want to look at some of the available emotes, and let's take the `entities.emote.hash` field to download the file from the `/content/contents` endpoint.
Each item in the array describes a [snapshot]({{< relref "snapshots" >}}). Let's grab a `hash` and download the file from the `/content/contents` endpoint.

```bash
curl "https://peer.decentraland.org/content/contents/bafkreialb5j2vhhes3dorynuyvkbvh3nxddjtadmupaukr4da7peyvlfny" > emotes.snapshot
curl "https://peer.decentraland.org/content/contents/bafybeia6qoum64psaooiqo3f45i6hykfwx723uc236waub3gng2naof224" > snapshot
```

{{< info >}}
You can experiment with the `profile` or global snapshots, but bear in mind that those are very large files.
You can experiment with larger snapshots, as in the [advanced python example](https://github.com/decentraland/documentation/blob/main/content/contributor/content/practice/snapshots.py). To try this out interactively, you probably want one of the smaller ones.
{{< /info >}}

We can check that we downloaded the right file in a format we know, by looking at the first line:

```bash
head -n1 emotes.snapshot
head -n1 snapshot
```
```
### Decentraland json snapshot
```

Great! Now we have a local copy of the current set of `emote` entities. Let's take the first one listed (the second line in the file):
Great! Now we have a local summary of all entities that were captured in that snapshot. Let's take the first one listed (the second line in the file), a `profile`:

```bash
# You can omit jq and get the raw unformatted JSON:
head -n+2 emotes.snapshot | jq
tail -n+2 snapshot | head -n1
```
```json
```js
{
"entityType": "emote",
"entityId": "bafkreigcreq7rv6b2wf4zc4fsnif43ziwb4q46v4qhsewpf7gbsyxew3om",
"entityId": "bafkreif7hjremkxlvixyxoxnoo7bdcnf7qqp245sjb2pag2nk3n6o6yc4c",
"entityType": "profile",
"pointers": [
"urn:decentraland:matic:collections-v2:0xc304f10579a499c967291c014365304207c59a62:0"
"0x271cdb3b1c792c336c4b2bdc52c4f415d0046b92"
],
"localTimestamp": 1667798266960,
"authChain": [
{
"type": "SIGNER",
"payload": "0xa8c7d5818a255a1856b31177e5c96e1d61c83991",
"signature": ""
},
{
"type": "ECDSA_EPHEMERAL",
"payload": "Decentraland Login\r\nEphemeral address: 0x8cbbCC5B597981cf0c2B254089cf2d7c90943961\r\nExpiration: 2022-11-16T07:18:01.235Z",
"signature": "0x97d38594dad0388eb20cfc3ef2e2a692858f1a809594ba43b7bca9171aecff09218adeb949a72b60f8b2d4281f85f348dae5224a2f750b4b22fe7b6bf392f6941c"
},
{
"type": "ECDSA_SIGNED_ENTITY",
"payload": "bafkreigcreq7rv6b2wf4zc4fsnif43ziwb4q46v4qhsewpf7gbsyxew3om",
"signature": "0xe0037fc5ddb00d0befae6b29214ed3a846fbd2982c70edf6d556ef813efe78cc7a64b3f0669a50d6aa1d12cbc3b5cc75adc833c6b3ee2c444d34de48227726321b"
}
]
// See https://docs.decentraland.org/contributor/auth/authchain/
],
"entityTimestamp": 1689120135624
}
```

{{< info >}}
Since snapshots expire and entities are replaced, the identifiers in this article won't work. Follow along in your command line to get real, active file IDs.
{{< /info >}}

This is information we could save. We'll use the `entityId` to download the entity's JSON manifest, but persisting the listed [pointer]({{< relref "pointers" >}}) is a good idea if we want to locate this entity and any updated versions in the future.

We also have the [authentication chain]({{< relref "../entities#ownership" >}}) used to sign this entity, and we could validate the listed signatures to verify the authenticity of any related files we download.
Expand All @@ -159,76 +108,33 @@ Let's get our hands on the entity manifest. Remember, the `entityId` is the [fil
```bash
curl "https://peer.decentraland.org/content/contents/bafkreigcreq7rv6b2wf4zc4fsnif43ziwb4q46v4qhsewpf7gbsyxew3om"
```
```json
```js
{
"version": "v3",
"type": "emote",
"image": "image.png",
"thumbnail": "thumbnail.png",
"pointers": [ "urn:decentraland:matic:collections-v2:0xc304f10579a499c967291c014365304207c59a62:0" ],
"timestamp": 1667798235182,
"type": "profile",
"pointers": [
"0x273cdb3b1c791c336c4b2bcc52c4f415d0046b91"
],
"timestamp": 1689120135624,
"content": [
{
"file": "thumbnail.png",
"hash": "bafkreiajc6gwp4ldcnah7jrv4ligmuokb2ssn2yq3rmlx3erzvak42vjoe"
},
{
"file": "male/PassedOut.glb",
"hash": "bafkreigdc2ytkyfqvdggodgkh4u4wae7x6b2q45mxqv3vfzh4xt6k772y4"
"file": "body.png",
"hash": "bafybeibzaqkirz7fk474xvyhurho5xviphs7anawaceb6gscuigia4x33u"
},
{
"file": "female/PassedOut.glb",
"hash": "bafkreigdc2ytkyfqvdggodgkh4u4wae7x6b2q45mxqv3vfzh4xt6k772y4"
},
{
"file": "image.png",
"hash": "bafkreihxvd736yotitatwqyhl7fmrpzjprsah32kwf63djwdr5xepak54y"
}
// ...more files
],
"metadata": {
"id": "urn:decentraland:matic:collections-v2:0xc304f10579a499c967291c014365304207c59a62:0",
"name": "Passed Out",
"description": "Sometimes you need to sleep it off",
"collectionAddress": "0xc304f10579a499c967291c014365304207c59a62",
"rarity": "legendary",
"i18n": [
{ "code": "en", "text": "Passed Out" }
],
"emoteDataADR74": {
"category": "poses",
"representations": [
{
"bodyShapes": [ "urn:decentraland:off-chain:base-avatars:BaseMale" ],
"mainFile": "male/PassedOut.glb",
"contents": [ "male/PassedOut.glb" ]
},
{
"bodyShapes": [ "urn:decentraland:off-chain:base-avatars:BaseFemale" ],
"mainFile": "female/PassedOut.glb",
"contents": [ "female/PassedOut.glb" ]
}
],
"tags": [ "sleep", "mvmf22", "emote", "canessa", "passed", "out", "beer" ],
"loop": true
},
"metrics": {
"triangles": 0,
"materials": 0,
"textures": 0,
"meshes": 0,
"bodies": 0,
"entities": 1
}
// ...avatars and other information
}
}
```

This is all the information World Explorers use to animate avatars with this emote. If we're interested in getting one of the packaged files, we can continue to use the `/content/contents` endpoint.
This `profile` entity has all the information World Explorers use to render and animate a player. If we're interested in getting one of the packaged files, we can continue to use the `/content/contents` endpoint.

If we look at the `thumbnail` field, we can see that the internal file name is `thumbnail.png`. This is listed in `content` array of files, where we can match the `name` to a `hash` that identifies the file. Let's get it:
If we look at the `content` field, we can see the `hash` of the file internally called `body.png`. Let's get it:

```bash
curl "https://peer.decentraland.org/content/contents/bafkreiajc6gwp4ldcnah7jrv4ligmuokb2ssn2yq3rmlx3erzvak42vjoe" > thumbnail.png
curl "https://peer.decentraland.org/content/contents/bafybeibzaqkirz7fk474xvyhurho5xviphs7anawaceb6gscuigia4x33u" > body.png
```

We can open this `png` file in an image viewer or web browser, and check out the author's work. Nice!
Loading