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

Sync prettier #118

Merged
merged 2 commits into from
Jul 30, 2024
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
9 changes: 8 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
{
"proseWrap": "always",
"plugins": ["prettier-plugin-tailwindcss"]
"overrides": [
{
"files": "*.js",
"options": {
"plugins": ["prettier-plugin-tailwindcss"]
}
}
]
}
2 changes: 1 addition & 1 deletion scripts/format.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ while getopts c option; do
esac
done

npx [email protected] --$op --no-config "./src/**/*.md" "./src/**/*.mdx"
npx [email protected] --$op "./src/**/*.md" "./src/**/*.mdx"
24 changes: 9 additions & 15 deletions src/pages/core.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,27 @@ import { Callout } from "nextra/components";

# Introduction

This chapter will give you an overview over CosmWasm from a contract developer
perspective, its capabilities, and guide you through initializing your first
smart contract.
This chapter will give you an overview over CosmWasm from a contract developer perspective, its
capabilities, and guide you through initializing your first smart contract.

<Callout>
We assume you have basic knowledge of Rust and Cargo (its standard build
system)
</Callout>
<Callout>We assume you have basic knowledge of Rust and Cargo (its standard build system)</Callout>

## What is CosmWasm?

CosmWasm is a platform for writing smart contracts for Cosmos chains using Rust
and WebAssembly.
Meaning CosmWasm is your one-stop shop for developing, testing, and running
smart contracts on enabled chains.
CosmWasm is a platform for writing smart contracts for Cosmos chains using Rust and WebAssembly.
Meaning CosmWasm is your one-stop shop for developing, testing, and running smart contracts on
enabled chains.

## What does CosmWasm provide?

For you, a contract developer, CosmWasm provides a set of high-quality
primitives through our standard library. These primitives include:
For you, a contract developer, CosmWasm provides a set of high-quality primitives through our
standard library. These primitives include:

- extended precision arithmetic (128, 256, 512-bit integers)
- cryptographic primitives (for example, secp256k1 verification)
- interaction with the Cosmos SDK

## What does CosmWasm _not_ provide?

- Abstractions to simplify contract development (for this, check out
[Sylvia](/sylvia))
- Abstractions to simplify contract development (for this, check out [Sylvia](/sylvia))
- Storage abstractions (for this, check out [Storey](/storey))
11 changes: 5 additions & 6 deletions src/pages/core/advanced.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@ import { Callout } from "nextra/components";

# Advanced topics

In this part of the documentation, we go over some more "advanced" things you
can do with the functionality CosmWasm core offers.
In this part of the documentation, we go over some more "advanced" things you can do with the
functionality CosmWasm core offers.

<Callout>
While the name of this section is "advanced", this doesn't mean that we want
to imply that you only need these functions in advanced contexts. The wording
"advanced" moreso refers to the fact that you should be familiar with
endpoints, the structs that are passed to the endpoints, etc.
While the name of this section is "advanced", this doesn't mean that we want to imply that you
only need these functions in advanced contexts. The wording "advanced" moreso refers to the fact
that you should be familiar with endpoints, the structs that are passed to the endpoints, etc.
</Callout>
22 changes: 10 additions & 12 deletions src/pages/core/advanced/measuring-time.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,21 @@ import { Callout } from "nextra/components";

# Measuring time

Accessing the current time is useful in a lot of different contexts but time is
hard. It is hard to coordinate, hard to keep in sync, and this gets worse in
distributed settings such as blockchains.
Accessing the current time is useful in a lot of different contexts but time is hard. It is hard to
coordinate, hard to keep in sync, and this gets worse in distributed settings such as blockchains.

In CosmWasm, we solve this by passing you some information about the blockchain
you are running on whenever an entrypoint is invoked.
In CosmWasm, we solve this by passing you some information about the blockchain you are running on
whenever an entrypoint is invoked.

In each of the entrypoints, you get a parameter of the type `Env` and this
struct contains the field `block`. The struct contained in this field has a
bunch of different information about the current state of the blockchain you are
running on.
In each of the entrypoints, you get a parameter of the type `Env` and this struct contains the field
`block`. The struct contained in this field has a bunch of different information about the current
state of the blockchain you are running on.

> The documentation about the `BlockInfo` struct can be [found here]

The timestamp contained in this struct can be safely used in your program as the
source of the current time. Well, kinda. It won't be 100% matching the current
time, as it is the timestamp of the block we are currently operating on.
The timestamp contained in this struct can be safely used in your program as the source of the
current time. Well, kinda. It won't be 100% matching the current time, as it is the timestamp of the
block we are currently operating on.

But you can rely on this timestamp to have the following properties:

Expand Down
65 changes: 30 additions & 35 deletions src/pages/core/architecture/actor-model.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,32 @@ import { Callout } from "nextra/components";

# Actor Model

CosmWasm, at its core, is built around the actor model. This prevents some
common pitfalls which, for example, Ethereum smart contracts had to fix over the
years. The issues mostly revolved around [reentrancy issues] where we could, for
example, call out to another contract before finishing the current execution.
CosmWasm, at its core, is built around the actor model. This prevents some common pitfalls which,
for example, Ethereum smart contracts had to fix over the years. The issues mostly revolved around
[reentrancy issues] where we could, for example, call out to another contract before finishing the current
execution.

<Callout>
If you are already familiar with the actor model through, for example,
programming in languages such as Erlang or Elixir, you can skip this page.
If you are already familiar with the actor model through, for example, programming in languages
such as Erlang or Elixir, you can skip this page.
</Callout>

While the term "actor model" sounds fancy, it is actually quite simple. Each
contract is an "actor" and _plays_ a role in the system (pun intended).
While the term "actor model" sounds fancy, it is actually quite simple. Each contract is an "actor"
and _plays_ a role in the system (pun intended).

Each actor has its own state and can only be interacted with via messages. This
means a contract can only interact with the outside world via messages and only
manipulate its own state.
Each actor has its own state and can only be interacted with via messages. This means a contract can
only interact with the outside world via messages and only manipulate its own state.

Picture two people living in two houses, each house has a mailbox. If person A
wants to talk to person B, they write a letter, address it to person B, and send
it off. The mailman (or in this case, the chain) will put the letter in person
B's mailbox.
Picture two people living in two houses, each house has a mailbox. If person A wants to talk to
person B, they write a letter, address it to person B, and send it off. The mailman (or in this
case, the chain) will put the letter in person B's mailbox.

Person B will then read the letter and can choose to write a response, address
it to person A with a note indicating that this is a reply, and send it off once
again.
Person B will then read the letter and can choose to write a response, address it to person A with a
note indicating that this is a reply, and send it off once again.

No direct interaction is happening here, nobody visits each other's house which
would allow them to rummage around in their belongings (state). They simply
exchange messages and put everything the other side needs to know into a
message.
No direct interaction is happening here, nobody visits each other's house which would allow them to
rummage around in their belongings (state). They simply exchange messages and put everything the
other side needs to know into a message.

<Image
src="/actor-model.svg"
Expand All @@ -46,24 +42,23 @@ message.
height={1080}
/>

As you can see in the simple graphic above, they simply exchange messages
addressed to each other, and the messages reference previous messages if need
be.
As you can see in the simple graphic above, they simply exchange messages addressed to each other,
and the messages reference previous messages if need be.

<Callout>
In CosmWasm you can only pass a single message type to a contract endpoint. If
you are wondering how to handle multiple message types, check out the [enum
dispatch] page.
In CosmWasm you can only pass a single message type to a contract endpoint. If you are wondering
how to handle multiple message types, check out the [enum dispatch] page.
</Callout>

But how does that fix reentrancy? In CosmWasm, you can only send out messages at
the end of a contract execution as part of the response. This ensures you have
already written everything to the state, meaning the state can't suddenly change
mid-execution and make your contract exhibit buggy behaviour.
But how does that fix reentrancy? In CosmWasm, you can only send out messages at the end of a
contract execution as part of the response. This ensures you have already written everything to the
state, meaning the state can't suddenly change mid-execution and make your contract exhibit buggy
behaviour.

CosmWasm effectively forces you to follow the [CEI pattern (Checks, Effects,
Interactions)] while other similar systems only have this as a "best practice".
CosmWasm effectively forces you to follow the [CEI pattern (Checks, Effects, Interactions)] while
other similar systems only have this as a "best practice".

[reentrancy issues]: https://ethereum.org/en/developers/docs/smart-contracts/security/#reentrancy
[enum dispatch]: ../conventions/enum-dispatch
[CEI pattern (Checks, Effects, Interactions)]: https://fravoll.github.io/solidity-patterns/checks_effects_interactions.html
[CEI pattern (Checks, Effects, Interactions)]:
https://fravoll.github.io/solidity-patterns/checks_effects_interactions.html
18 changes: 7 additions & 11 deletions src/pages/core/architecture/events.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,16 @@ import { Callout } from "nextra/components";

# Events

CosmWasm can emit [Cosmos Events]. These events are stored in the block as
metadata, allowing the contract to attach metadata to what exactly happened
during execution.
CosmWasm can emit [Cosmos Events]. These events are stored in the block as metadata, allowing the contract
to attach metadata to what exactly happened during execution.

<Callout>

Some important details about the keys:

- Whitespaces will be trimmed (i.e. removed from the begin and end)
- Empty keys (that includes keys only consisting of whitespaces) are not allowed
- Keys _cannot_ start with an underscore (`_`). These types of keys are reserved
for `wasmd`
- Keys _cannot_ start with an underscore (`_`). These types of keys are reserved for `wasmd`

</Callout>

Expand All @@ -30,13 +28,11 @@ let response: Response<Empty> = Response::new()

## Custom events

As mentioned above, CosmWasm only emits the event `wasm` by default. If you want
to emit other events, such as domain-specific events like `user_added`, you can
construct a fully custom event and attach it to the response.
As mentioned above, CosmWasm only emits the event `wasm` by default. If you want to emit other
events, such as domain-specific events like `user_added`, you can construct a fully custom event and
attach it to the response.

<Callout>
Note that those custom events will be prefixed with `wasm-` by the runtime.
</Callout>
<Callout>Note that those custom events will be prefixed with `wasm-` by the runtime.</Callout>

```rust filename="custom_event.rs" template="core"
let event = Event::new("custom_event")
Expand Down
84 changes: 38 additions & 46 deletions src/pages/core/architecture/gas.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,75 +4,66 @@ tags: ["core", "architecture"]

# Gas

Gas is a way to measure computational expense of a smart contract execution,
including CPU time and storage cost. Its unit is 1, i.e. you can think of it as
countable points. Gas consumption is deterministic, so executing the same thing
costs the same amount of gas across all hardware and operating systems.
Gas is a way to measure computational expense of a smart contract execution, including CPU time and
storage cost. Its unit is 1, i.e. you can think of it as countable points. Gas consumption is
deterministic, so executing the same thing costs the same amount of gas across all hardware and
operating systems.

## CosmWasm gas vs. Cosmos SDK gas

CosmWasm charges gas for Wasm operations, calls to host functions and calls to
the Cosmos SDK. _CosmWasm gas_ is different from _Cosmos SDK gas_ as the numbers
here are much larger. Since we charge gas for arbitrary user defined operations,
we need to charge each Wasm operation individually and cannot group larger tasks
together. As a result, the gas values become much larger than in Cosmos SDK even
for very fast executions. There is a [multiplier][defaultgasmultiplier] to
translate between CosmWasm gas and Cosmos SDK. It was measured and set to 100 a
while ago and can be adjusted when necessary.
CosmWasm charges gas for Wasm operations, calls to host functions and calls to the Cosmos SDK.
_CosmWasm gas_ is different from _Cosmos SDK gas_ as the numbers here are much larger. Since we
charge gas for arbitrary user defined operations, we need to charge each Wasm operation individually
and cannot group larger tasks together. As a result, the gas values become much larger than in
Cosmos SDK even for very fast executions. There is a [multiplier][defaultgasmultiplier] to translate
between CosmWasm gas and Cosmos SDK. It was measured and set to 100 a while ago and can be adjusted
when necessary.

## CosmWasm gas pricing

For CosmWasm gas, the target gas consumption is 1 Teragas (10^12 gas) per
second. This idea is [inspired by NEAR][neargas] and we encourage you to read
their excellent docs on that topic.
For CosmWasm gas, the target gas consumption is 1 Teragas (10^12 gas) per second. This idea is
[inspired by NEAR][neargas] and we encourage you to read their excellent docs on that topic.

In order to meet this target, we execute Argon2 in a test contract ([#1120]).
This is a CPU and memory intense job that does not call out into the host. At a
constant gas cost per operation of 1 (pre CosmWasm 1.0), this consumed 96837752
gas and took 15ms on our CI system. The ideal cost per operation for this system
is `10^12 / (96837752 / (15 / 1000))`: 154. This is rounded to 150 for
In order to meet this target, we execute Argon2 in a test contract ([#1120]). This is a CPU and
memory intense job that does not call out into the host. At a constant gas cost per operation of 1
(pre CosmWasm 1.0), this consumed 96837752 gas and took 15ms on our CI system. The ideal cost per
operation for this system is `10^12 / (96837752 / (15 / 1000))`: 154. This is rounded to 150 for
simplicity.

CosmWasm 2.1 update: All gas values were re-evaluated and adjusted to meet the 1
Teragas/second target mentioned above. A rerun of the Argon2 test contract
consumed 5270718300 gas with the previous cost of 150, so the operation count
was `5270718300 / 150 = 35138122`. This took 6ms on our benchmark server, so the
new cost per operation is `10^12 / (35138122 / (6 / 1000))`: 171. This is
CosmWasm 2.1 update: All gas values were re-evaluated and adjusted to meet the 1 Teragas/second
target mentioned above. A rerun of the Argon2 test contract consumed 5270718300 gas with the
previous cost of 150, so the operation count was `5270718300 / 150 = 35138122`. This took 6ms on our
benchmark server, so the new cost per operation is `10^12 / (35138122 / (6 / 1000))`: 171. This is
rounded to 170 for simplicity.

Benchmarking system:

- CPU: Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz (4 cores, 8 threads)
- RAM: 32GB DDR4 2133 MHz

Each machine is different, we know that. But the above target helps us in
multiple ways:
Each machine is different, we know that. But the above target helps us in multiple ways:

1. Develop an intuition what it means to burn X gas or how much gas can be used
if a block should be executable in e.g. 1 second
2. Have a target for adjustments, e.g. when the Wasm runtime becomes faster or
slower
1. Develop an intuition what it means to burn X gas or how much gas can be used if a block should be
executable in e.g. 1 second
2. Have a target for adjustments, e.g. when the Wasm runtime becomes faster or slower
3. Allow pricing of calls that are not executed in Wasm, such as crypto APIs
4. Find significant over or underpricing

## Gas overflow potential

CosmWasm gas aims for 1 Teragas/second, i.e. the uint64 range exceeds after 18
million seconds (5000 hours)<sup>1</sup>. Assuming a max supported block
execution time of 30 seconds, the gas price has to be over-priced by a factor of
614891 (614891 Teragas/second) in order to exceed the uint64 range<sup>2</sup>.
Since serious over or underpricing is considered a bug, using uint64 for gas
CosmWasm gas aims for 1 Teragas/second, i.e. the uint64 range exceeds after 18 million seconds (5000
hours)<sup>1</sup>. Assuming a max supported block execution time of 30 seconds, the gas price has
to be over-priced by a factor of 614891 (614891 Teragas/second) in order to exceed the uint64
range<sup>2</sup>. Since serious over or underpricing is considered a bug, using uint64 for gas
measurements is considered safe.

Cosmos SDK gas uses values that are smaller by a factor of 150, so those don't
overflow as well. Since no Cosmos SDK gas values are processed inside of this
repository, this is not our main concern. However, it's good to know that we can
safely pass them in uint64 fields, as long as the full range is supported. This
is the case for the C API as well as [JSON numbers] as long as both sides
support integers in their JSON implementation. Go and Rust do that while many
other implementations don't support integers, and convert them to IEEE-754
doubles, which has a safe integer range up to about 53 bit (e.g. JavaScript and
jq).
Cosmos SDK gas uses values that are smaller by a factor of 150, so those don't overflow as well.
Since no Cosmos SDK gas values are processed inside of this repository, this is not our main
concern. However, it's good to know that we can safely pass them in uint64 fields, as long as the
full range is supported. This is the case for the C API as well as [JSON numbers] as long as both sides
support integers in their JSON implementation. Go and Rust do that while many other implementations don't
support integers, and convert them to IEEE-754 doubles, which has a safe integer range up to about 53
bit (e.g. JavaScript and jq).

<sup>1</sup> `(2^64-1) / 10^12`

Expand All @@ -98,6 +89,7 @@ jq).

[#1599]: https://github.com/CosmWasm/cosmwasm/pull/1599
[JSON numbers]: https://www.json.org/
[defaultgasmultiplier]: https://github.com/CosmWasm/wasmd/blob/v0.19.0/x/wasm/keeper/gas_register.go#L18
[defaultgasmultiplier]:
https://github.com/CosmWasm/wasmd/blob/v0.19.0/x/wasm/keeper/gas_register.go#L18
[neargas]: https://docs.near.org/docs/concepts/gas
[#1120]: https://github.com/CosmWasm/cosmwasm/pull/1120
Loading