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

Misc fixes #1149

Merged
merged 4 commits into from
Dec 21, 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
4 changes: 2 additions & 2 deletions docs/build/guides/conventions/error-enum.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ impl Contract {
}
```

When converted to XDR, the value becomes an `ScVal`, containing a `ScStatus`, containing the integer value of the error as contract error.
When converted to XDR, the value becomes an `ScVal`, containing a `ScError`, containing the integer value of the error as contract error.

```json
{ "status": { "contractError": 1 } }
{ "error": { "contractError": 1 } }
```
18 changes: 9 additions & 9 deletions docs/build/smart-contracts/example-contracts/errors.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,15 @@ count: U32(2)
count: U32(3)
count: U32(4)
count: U32(5)
Status(ContractError(1))
contract call invocation resulted in error Status(ContractError(1))
Error(ContractError(1))
contract call invocation resulted in error Error(ContractError(1))
test test::test ... ok
thread 'test::test_panic' panicked at 'called `Result::unwrap()` on an `Err` value: HostError
Value: Status(ContractError(1))
Value: Error(ContractError(1))
Debug events (newest first):
0: "Status(ContractError(1))"
0: "Error(ContractError(1))"
1: "count: U32(5)"
2: "count: U32(4)"
3: "count: U32(3)"
Expand Down Expand Up @@ -219,7 +219,7 @@ fn test() {
}

#[test]
#[should_panic(expected = "Status(ContractError(1))")]
#[should_panic(expected = "Error(ContractError(1))")]
#E3256B
fn test_panic() {
let env = Env::default();
Expand Down Expand Up @@ -257,7 +257,7 @@ Two functions are generated for every contract function, one that returns a `Res

### `try_increment`

In the first test the `try_increment` function is called and returns `Result<Result<u32, _>, Result<Error, Status>>`.
In the first test the `try_increment` function is called and returns `Result<Result<u32, _>, Result<Error, InvokeError>>`.

```rust
assert_eq!(client.try_increment(), Ok(Ok(5)));
Expand All @@ -268,13 +268,13 @@ assert_eq!(client.try_increment(), Err(Ok(Error::LimitReached)));

- If the function call is successful but returns a value that is not a `u32`, `Ok(Err(_))` is returned.

- If the function call is unsuccessful, `Err(Ok(Error))` is returned.
- If the function call is unsuccessful and fails with an error in the `Error` enum, `Err(Ok(Error))` is returned.

- If the function call is unsuccessful but returns an error code not in the `Error` enum, or returns a system error code, `Err(Err(Status))` is returned and the `Status` can be inspected.
- If the function call is unsuccessful but returns an error code not in the `Error` enum, or returns a system error code, `Err(Err(InvokeError))` is returned and the `InvokeError` can be inspected.

### `increment`

In the second test the `increment` function is called and returns `u32`. When the last call is made the function panicks.
In the second test the `increment` function is called and returns `u32`. When the last call is made the function panics.

```rust
assert_eq!(client.increment(), 5);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ sidebar_position: 5

Contracts are invoked through a pair of host functions `call` and `try_call`:

- `try_call(contract, function, args)` calls `function` exported from `contract`, passing `args` and returning a `Status` on any error.
- `call(contract, function, args)` just calls `try_call` with its arguments and traps on `Status`, essentially propagating the error.
- `try_call(contract, function, args)` calls `function` exported from `contract`, passing `args` and returning a `Error` on any error.
- `call(contract, function, args)` just calls `try_call` with its arguments and traps on `Error`, essentially propagating the error.

In both cases `contract` is a `Binary` host object containing the contract ID, `function` is a `Symbol` holding the name of an exported function to call, and `args` is a `Vector` of values to pass as arguments.

Expand Down
11 changes: 9 additions & 2 deletions docs/learn/encyclopedia/contract-development/rust-dialect.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ The host object and host function repertoire has been designed to relieve the gu

Using host objects instead of data structures in guest memory carries numerous benefits: much higher performance, much smaller code size, interoperability between contracts, shared host support for serialization, debugging and data structure introspection.

The guest does, however, has a small linear memory available to it in cases where dynamic memory allocation is necessary. Using this memory carries costs: the guest must include in its code a full copy of a memory allocator, and must pay the runtime cost of executing the allocator's code inside the VM.
The guest does, however, have a small linear memory available to it in cases where dynamic memory allocation is necessary. Using this memory carries costs: the guest must include in its code a full copy of a memory allocator, and must pay the runtime cost of executing the allocator's code inside the VM.

This restriction is due to the limited ability of Wasm to support code-sharing: there is no standard way for the Wasm sandbox to provide shared "standard library" code within a guest, such as a memory allocator, nor does the host have adequate insight into the contents of the guest's memory to provide an allocator itself. Every contract that wishes to use dynamic allocation must therefore carry its own copy of an allocator.

Expand Down Expand Up @@ -73,4 +73,11 @@ This is not a hard restriction enforced by the host, but a soft configuration ma

Host objects have significantly different semantics than typical Rust data structures, especially those implementing _collections_ such as maps and vectors.

In particular: host objects are **immutable**, and often **share substructure**. They therefore resemble the data structures from pure-functional programming more closely than the typical imperative model used in many Rust programs.
In particular: host objects are **immutable**, and any "modification" to a host object returns a **full new copy** of the object, leaving the initial one unchanged.
For the most part this distinction is hidden through wrappers in the SDK, such that objects like `Map` or `Vec` appear to the contract programmer to be uniquely owned mutable values similar to Rust's standard library types,
but the underlying host objects are immutable, so have different performance characteristics. Specifically: cloning such an object is O(1), whereas any modification is O(N).
Since most host objects are typically very small, the O(N) cost of modification is typically cheaper than any alternative implementation involving shared substructures.

**Note**: these container types `Vec` and `Map` should _not_ be used for managing large or unbounded collections of data.
For such cases, contracts should store data in multiple separate ledger entries, each with its own unique contract-defined key.
Doing so also limits the IO cost of a contract to only the entries it accesses, and furthermore allows concurrent modification of entries with separate keys from separate transactions.
3 changes: 2 additions & 1 deletion docs/learn/encyclopedia/data-format/xdr.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ Stellar stores and communicates ledger data, transactions, results, history, and

## .X files

Data structures in XDR are specified in an interface definition file (IDL). The IDL files used for the Stellar Network are available on [GitHub](https://github.com/stellar/stellar-xdr).
Data structures in XDR are specified in `.x` files. These files _only_ contain data structure definitions, no operations or executable code.
The `.x` files for the XDR structures used on the Stellar Network are available on [GitHub](https://github.com/stellar/stellar-xdr).

## JSON and XDR Conversion Schema

Expand Down
2 changes: 1 addition & 1 deletion docs/learn/encyclopedia/errors-and-debugging/debugging.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,4 @@ While we encourage most testing to happen in local-testing mode, some problems w

- A "sandbox" host with a mock-ledger that can read and write `CONTRACT_DATA` ledger entries to the local filesystem.
- A general logging system that allows contracts to log values of the [shared host/guest "value" type](../contract-development/environment-concepts.mdx), even in production.
- User-extensible `Status` codes that can be returned from any contract call to indicate problems.
- User-extensible `Error` codes that can be returned from any contract call to indicate problems.
6 changes: 3 additions & 3 deletions docs/learn/encyclopedia/errors-and-debugging/errors.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ The [errors example] demonstrates how to define your own error types.

## Error Enums

Errors are a special type of enum integer type that are stored on ledger as `Status` values containing a `u32` code.
Errors are a special type of enum integer type that are stored on ledger as `Error` values containing a `u32` code.

```rust
#[contracterror]
Expand All @@ -39,8 +39,8 @@ pub enum Error {
}
```

When converted to XDR, the value becomes an `ScVal`, containing a `ScStatus`, containing the integer value of the error as contract error.
When converted to XDR, the value becomes an `ScVal`, containing a `ScError`, containing the integer value of the error as contract error.

```json
{ "status": { "contractError": 1 } }
{ "error": { "contractError": 1 } }
```
48 changes: 40 additions & 8 deletions docs/learn/encyclopedia/network-configuration/ledger-headers.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,49 @@ title: Ledger Headers
sidebar_position: 30
---

Every ledger has a header that references the data in that ledger and the previous ledger. These references are cryptographic hashes of the content which behave like pointers in typical data structures but with added security guarantees. Think of a historical ledger chain as a linked list of ledger headers:
Every ledger has a header that references the data in that ledger and the previous ledger.
These references are cryptographic hashes of the content which behave like pointers in typical data structures but with added security guarantees.
Think of a historical ledger chain as a linked list of ledger headers.
Time flows forward from left to right, hashes point backwards in time, from right to left.
Each hash in the chain links a ledger to its previous ledger, which authenticates the entire history of ledgers in its past:

```mermaid
stateDiagram
direction LR
Genesis --> LedgerHeader_1
LedgerHeader_1 --> ...
... --> LedgerHeader_n
flowchart RL
subgraph genesis["Genesis"]
direction LR
prev1["Prev: none"]
state1["Genesis state"]
end

subgraph block2["Ledger 2"]
prev2["Prev: hash(Genesis)"]
state2["Ledger 2<br/>transactions<br/>and state"]
end

subgraph block3["Ledger 3"]
prev3["Prev: hash(Ledger 2)"]
state3["Ledger 3<br/>transactions<br/>and state"]
end

subgraph dotdot["..."]
end

subgraph blockn["Ledger N"]
prevn["Prev: hash(Ledger N-1)"]
staten["Ledger N<br/>transactions<br/>and state"]
end


genesis ~~~ block2 ~~~ block3 ~~~ dotdot ~~~ blockn
prev2 --> genesis
prev3 --> block2
dotdot --> block3
prevn --> dotdot

```

The genesis ledger has a sequence number of 1. The ledger directly following a ledger with sequence number n has a sequence number of n+1.
The genesis ledger has a sequence number of 1. The ledger directly following a ledger with sequence number `N` has a sequence number of `N+1`.
Ledger `N+1` contains a hash of ledger `N` in its previous ledger field.

## Ledger header fields

Expand Down Expand Up @@ -83,4 +115,4 @@ The reserve the network uses when calculating an account’s minimum balance.

### Skip list

Hashes of ledgers in the past. Allows you to jump back in time in the ledger chain without walking back ledger by ledger. There are four ledger hashes stored in the skip list. Each slot contains the oldest ledger that is mod of either 50 5000 50000 or 500000 depending on index skipList[0] mod(50), skipList[1] mod(5000), etc.
Hashes of ledgers in the past. Intended to accelerate access to past ledgers without walking back ledger by ledger. Currently unused.
Loading