diff --git a/rfcs/rfc-001-smart-contracts-engine.md b/rfcs/rfc-001-smart-contracts-engine.md index 60db5fcf958df2..0673e860e56df1 100644 --- a/rfcs/rfc-001-smart-contracts-engine.md +++ b/rfcs/rfc-001-smart-contracts-engine.md @@ -1,6 +1,6 @@ # Smart Contracts Engine -The goal of this RFC is to define a set of constraints for APIs and runtime such that we can safely execute our smart contracts safely on massively parallel hardware such as a GPU. +The goal of this RFC is to define a set of constraints for APIs and runtime such that we can execute our smart contracts safely on massively parallel hardware such as a GPU. Our runtime is built around an OS *syscall* primitive. The difference in blockchain is that now the OS does a cryptographic check of memory region ownership before accessing the memory in the Solana kernel. ## Toolchain Stack @@ -31,7 +31,7 @@ The goal of this RFC is to define a set of constraints for APIs and runtime such [Figure 1. Smart Contracts Stack] -In Figure 1. an untrusted client, creates a program in the front-end language of her choice, (like C/C++/Rust/Lua), and compiles it with LLVM to a position independent shared object ELF, targeting BPF bytecode. Solana will safely load and execute the ELF. +In Figure 1 an untrusted client, creates a program in the front-end language of her choice, (like C/C++/Rust/Lua), and compiles it with LLVM to a position independent shared object ELF, targeting BPF bytecode. Solana will safely load and execute the ELF. ## Bytecode @@ -77,7 +77,7 @@ Now clients can `start` the instance: ## Runtime -Our goal with the runtime is to have a general purpose execution environment that is highly parallelizable and doesn't require dynamic resource management. Basically, we want to execute as many contracts as we can in parallel, and have them pass or fail without a destructive state change. +Our goal with the runtime is to have a general purpose execution environment that is highly parallelizable and doesn't require dynamic resource management. We want to execute as many contracts as we can in parallel, and have them pass or fail without a destructive state change. ### State and Entry Point @@ -104,15 +104,29 @@ void call( ); ``` -To call this operation, the transaction that is destined to the contract instance specifies what keyed state it should present to the `call` function. To allocate the state memory, the client has to first call a function on the contract with the designed address that will own the state. +To call this operation, the transaction that is destined to the contract instance specifies what keyed state it should present to the `call` function. To allocate the state memory or a call context, the client has to first call a function on the contract with the designed address that will own the state. -* `Instance_Allocate(Instance PubKey, My PubKey, Proof of key ownership)` +At its core, this is a system call that requires cryptographic proof of ownership of memory regions instead of an OS that checks page tables for access rights. -Any transaction can then call `call` on the contract with a set of keys. It's up to the contract itself to manage owndership: +* `Instance_AllocateContext(Instance PubKey, My PubKey, Proof of key ownership)` -* `Instance_Call(Instance PubKey, [Input PubKeys], proofs of ownership, userdata...)` +Any transaction can then call `call` on the contract with a set of keys. It's up to the contract itself to manage ownership: -The contract has read/write privileges to all the memory that is allocated. +* `Instance_Call(Instance PubKey, [Context PubKeys], proofs of ownership, userdata...)` + +Contracts should be able to read any state that is part of solana, but only write to state that the contract allocated. + +#### Caller State + +Caller `state` is memory allocated for the `call` that belongs to the public key that is issuing the `call`. This is the caller's context. + +#### Instance State + +Instance `state` is memory that belongs to this contract instance. We may also need module-wide `state` as well. + +#### Participant State + +Participant `state` is any other memory. In some cases it may make sense to have these allocated as part of the call by the caller. ### Reduce @@ -165,3 +179,4 @@ A single contract can read and write to separate key pairs without interference. 2. Persistant Memory is allocated to a Key with ownership 3. Contracts can `call` to update key owned state 4. Contracts can `reduce` over the memory to aggregate state +5. `call` is just a *syscall* that does a cryptographic check of memory owndershp