Git Product home page Git Product logo

mystenlabs / sui Goto Github PK

View Code? Open in Web Editor NEW
6.0K 6.0K 11.1K 318.9 MB

Sui, a next-generation smart contract platform with high throughput, low latency, and an asset-oriented programming model powered by the Move programming language

Home Page: https://sui.io

License: Apache License 2.0

Rust 73.13% Python 0.55% Shell 0.22% JavaScript 0.11% HTML 0.01% TypeScript 8.50% CSS 0.01% SCSS 0.08% Dockerfile 0.05% Boogie 0.01% Move 16.15% PLpgSQL 0.01% MDX 0.57% Solidity 0.60% Smarty 0.01%
blockchain distributed-ledger-technology move smart-contracts

sui's People

Contributors

666lcz avatar akichidis avatar amnn avatar andll avatar aschran avatar awelc avatar bmwill avatar clay-mysten avatar dependabot[bot] avatar ebmifa avatar emmazzz avatar gegaowp avatar hayes-mysten avatar huitseeker avatar jordan-mysten avatar joyqvq avatar lavindir avatar longbowlu avatar lxfind avatar mwtian avatar mystenmark avatar oxade avatar patrickkuo avatar pchrysochoidis avatar plam-ml avatar ronny-mysten avatar sadhansood avatar stefan-mysten avatar tnowacki avatar tzakian avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sui's Issues

[fastx adapter] bytecode verifier pass to prevent usage of global storage

  • FastNFT does not allow mutable memory to be shared between multiple agents
  • The purpose of Move's global storage is to share global mutable memory across agents
  • Thus, we need a bytecode verifier pass to prevent fastNFT code from accessing Move's global storage. FastNFT has its own mechanism for putting objects into global storage (i.e., Transfer::transfer) and getting them out (i.e., the adapter code).

Operationally, this pass should flag all usages of the global storage bytecodes (move_from, move_to, borrow_global, ...). An example of a similar bytecode verifier pass in the VM is here. The code for this bytecode verifier pass should live in the fastNFT repo + be run in the adapter on the code path for publishing new Move modules.

[fastx distsys] Adapt fastpay client into fastnft client handling objects

The fastpay client was managing a single account associated with an address. Fastnft has instead a notion of objects, many of which may be associated with a client. We need to refactor the core client logic, the networked client logic, as well as their tests to build a client that handles many objects and can act on them.

[fastx adapter] bytecode verifier pass to ensure immutability + non-reuse of ID's

  • Every object in the fastX global pool must have an ID (see #15)
  • These ID's need to be immutable. This can be enforced with a simple per-instruction check (e.g., flag BorrowField instructions that try to look at an id field of an object with the key ability)
  • In addition, if an object is destroyed via the Unpack instruction, it's ID will end up on the stack. This ID should not flow into another object, as that will cause confusion in the world of clients (e.g., an object ID may appear to become associated with new data of a completely different type). This can be enforced with an escape analysis: taint an unpacked ID and ensure that it does not flow into a return value, a Pack or a WriteRef.
  • This code implements an escape analysis inside the Move prover and might be useful to look at/steal abstract domains from.

Note: the escape analysis will be the most complicated fastX bytecode verifier pass by a good margin. The code for this bytecode verifier pass should live in the fastNFT repo + be run in the adapter on the code path for publishing new Move modules.

[fastx adapter] choose gas costs

There are two kinds of costs for us to reflect: computation, and storage. Some decisions to be made:

Storage

  1. How much do we charge per byte of storage?
  2. Do we charge only for the storage of the order itself, or also for the storage of the objects it creates?
  3. What should the upper limit on the size of transactions be?
  4. What should the upper limit on the total size of objects created by a transaction be?
  5. What should the upper limit on the size of an individual object be?

Computation

  1. The Move VM allows us to configure the gas costs of individual bytecode instructions. What values should we choose?
  2. What should we choose for the gas costs of native order types (e.g., transfer)?

[fastx adapter] bytecode verifier pass to ensure all global objects have ID's

  • FastNFT requires that every object in the global object pool has a unique ID.
  • In Move, objects that can be stored in the global object pool must have the key attribute
  • Thus, we need a bytecode verifier pass that ensures that every struct declaration with the key attribute has a field of type ID
  • For convenience + to avoid ambiguity, we should also enforce that this is the first field in the declaration and that the field is named id
  • In addition, any struct declaration with the key attribute must not have the drop attribute. This ensures that mutable references into the global object pool (e.g., via a &mut parameter in an entrypoint) cannot change the ID of an existing object in the pool (because ID's must be immutable--see #18)

An example of a similar bytecode verifier pass inside the VM is here. The code for this bytecode verifier pass should live in the fastNFT repo + be run in the adapter on the code path for publishing new Move modules.

[fastx] add Option::swap_opt to Move stdlib

See https://github.com/MystenLabs/fastnft/blob/main/fastx_programmability/examples/Hero.move#L166--the idea is to add a function Option::swap_opt(self: &mut Option<T>, t: T): Option<T> that replaces the contents of self (if any) with t. If self formerly contained a value, it should be returned--otherwise, it should return None.

This function is useful because needing to swap out the contents of a possibly-empty Option is fairly common, but the code to implement this swap is fairly cumbersome + is less efficient for an end-user than it is for the Option library, which can directly access the internal representation of the type.

This Move stdlib lives here in the diem repo.

[fastx] Merge the traits from `fastnftexec-experimental` and example execution into the fastnft

We need to agree on some traits that define objects, transactions, execution between the VM/exec layer of fastnft and the distributed systems safety / liveness logic. We already have a proposal for such interfaces in the fastnftexec-experimental project (https://github.com/MystenLabs/fastnftexec-experimental). Lets copy these files here, and code both the authority and the exec layer against these (potentially modified) interfaces.

[fastx] Refactor authority structure

Fastpay was account based, and the structures within authority.rs are structured around accounts. We should rename accounts to objects, and extract the structures holding certificates and transactions out of accounts to the authority object. Further we should rename all fields to align to our object centric structure as in the spec (https://www.overleaf.com/7111272316rvsqhrmycmwn)

Random coin for leader election

The leader election in Tusk is a post-proposal leader pick based on a random coin.

The code we have right now is not a random coin, but rather a round-robin:
https://github.com/MystenLabs/narwhal/blob/35319b17ece0bcfc6839fb23188138424da86a27/consensus/src/lib.rs#L210-L228

We should implement a real leader election based on a public coin.

  • the most common incarnation of this is a random beacon extracted from threshold signatures (ร  la BLS),
  • the signature is provisioned in a DKG. For this, we should eschew the traditional Feldman-VSS (which is hard to deploy and tune in production) and rather go for a scalable DKG.
  • This could be Gurkan-Maller 2021:
    https://eprint.iacr.org/2021/005
    https://github.com/kobigurk/aggregatable-dkg except it doesn't quite produce field elements.
  • the implementation should be modular enough to allow us to replace this piecemeal with a customer's DKG when available (e.g. Celo)

[fastx dist sys] Design and implement bridge logic + Light Clients

fastx should interop with other important chains, such as ETH or Solana. For this we need to implement 2-way bridges that allow:

  • Assets issued on another chain to be imported to fastx, and eventually re-exported to a new owner on the other chain.
  • Assets issued on fastx to be exported to another chain and eventually re-imported to fastx.

We also would like to support light client reads onto the fastx state, which would allow trustless third party services that provide APIs for read.

Currently our thinking is to use the committee of fastx to authorise these actions through a collective signature, but other options are welcome.

[fastx distsys] Nested objects, provenance, and replay prevention

This goes deeper into an issue with object wrapping initially raised in https://docs.google.com/presentation/d/1-xpsmJC3VEaRPH9U1Lklap858MaU_E3YQsRcaiOYI0Y/edit?usp=sharing, slide 16.

Note that this is going off of the Overleaf https://www.overleaf.com/project/6187be7580dc35362b091a73, not what is currently implemented (since the current implementation is lagging behind the spec a bit). In particular, the discussion will not mention object sequence numbers/versions, since they are an optional feature that is useful for making sync more sane, but we could just as easily choose to omit them.

Let's say the following things happen:

  1. First, a transaction T creates an object O with id id1. The derived ObjRef is (id, digest(T), com(O)). The authority updates LockMap[(id, digest(T), com(O))] := T and ObjMap[id] := O
  2. A subsequent transaction T' takes this object as input and wraps it in a new object we will call W. The authority updates LockMap[(id, digest(T), com(O))] = \bot and ObjMap[id] := \bot, as well as doing some W-related updates that we will omit.
  3. A subsequent transaction T'' destroys W, unwraps O from it, and sends it to an address. The authority updates LockMap[(id, digest(T''), com(O))] := T and ObjMap[id] := O

This scheme achieves the following:

  • Replay prevention (by uniqueness of the TxDigest and id combination in the LockMap domain)
  • Object ID stability (i.e., O retains the same ID even as it flows in and out of other objects)

Discussion

However, there is some funkiness here:

  • For tracking of object provenance, it would be nice for a client to easily determine whether step (2) above deleted O forever, or wrapped it in another object. We could choose to push this problem to application devs (e.g., say "well-written applications should emit an event like Wrapped(W.id, O.id)"), or choose to help more directly (e.g., we could do ObjMap[id] := Wrapped(digest(T)) in step 2 instead, where Wrapped is some special marker pointing to the tx that wrapped the object)
  • It could be nice for the storage layer to have the property that once ObjMap[id] is set to \bot, no subsequent assignments to ObjMap[id] can occur.

[fastx adapter/verifier] implement Move module initializers

In many cases, it's useful to have a singleton object (e.g., a guarantee that there can be at most one instance of type TreasuryCap in the system). However, the fastX restrictions on global state prevent the usual Move design patterns for creating singletons.

One way out of this conundrum is to support module initializers as part of the module publishing logic. Some ideas:

  • A module initializer must be a private function named init, take a single parameter of type TxContext, and return no values
  • A module initializer cannot be called from any function. This condition and the previous one should be enforced by a pass in the FastX verifier.
  • For a transaction publishing a list containing N modules, the module publishing logic runs the initializer of each module (if any) sequentially in the order given by the list. Initializers are only run if verification and linking succeeded.
  • If any initializer aborts, the entire transaction aborts (i.e., no modules are published and no effects from running initializers persist)
  • I suppose a publish tx now needs a gas budget, and running out of gas during module initializers is possible?

[fastx adapter] Call Move bytecode verifier and linker directly rather than via the Move VM

adapter::publish runs the Move bytecode verifier and linker by calling the VM's publish_module_bundle API. This causes some problems from both a semantics perspective (it runs some checks we don't want like enforcing that the sender address is the same as the module's self address) and an efficiency perspective (it produces some data structures like ChangeSet that we don't want/need).

Instead, we should change the adapter to invoke the bytecode verifier and linker directly. Ideally, we would do this by refactoring the upstream VM to expose a new API that does only this + call the new entrypoint from publish_module_bundle.

[fastx adapter] bytecode verifier pass to enforce that `Transfer::transfer<T>` and `Event::emit<T>` can only be applied to a `T` declared in the current module

  • We want to enforce that the T in Transfer::transfer<T: key>(t: T, recipient: Authenticator) must be a type declared in the current module. This makes it possible to enforce restricted transfer policies on objects that can flow out of their declaring modules--without this, a new module can subvert the restrictions of transfers defined by an existing one. Similar story for events and Event::emit.
  • Although we could do this with a custom bytecode verifier pass, we might (eventually or immediately?) want to add this as an extension to the Move ability system (e.g., an internal ability constraint such that T: internal can only be bound to T's declared in the current module). There are a number of cases where this would be useful in the Diem Framework codebase, and it greatly increases the expressivity of adapters--you can basically implement new module-internal bytecode instructions. This is the preferred approach--as @lxfind points out below, the other approaches have some serious limitations
  • Something to be careful about: even if we have this bytecode verifier pass, it is possible to subvert transfer restrictions by placing the T in a wrapper type with unrestricted transfers. I think the right fix here is probably a linter that warns you if a module defines both a restricted transfer policy for your T and a public function that returns a T.

An example of a similar bytecode verifier pass inside the VM is here. The code for this bytecode verifier pass should live in the fastNFT repo + be run in the adapter on the code path for publishing new Move modules.

[fastx adapter] add gas fee logic

A MoveCall order o contains a gas_payment: ObjectID argument, but it is currently ignored. In order to levy the fee, we need to:

  1. Resolve the object O associated with the id o.gas_payment
  2. Confirm that O belongs to the order's sender
  3. Check that the value of O is greater than or equal to o.gas_budget
  4. After executing the transaction, subtract the gas used from O's value

On (3), note that the type of gas_budget reflects the computational costs and storage cost of executing a transaction (denominated in "gas units") and should be nonzero for all transactions, but that the choice of a sensible gas costs is a separate issue from the mechanics of charging for gas (which are the same regardless of the choice of budget). See #81 for more discussion on choice of gas costs.

[fastx types] Unify Rust and Move `TxContext`

TxContext is a special type that exists in both Rust and Move-land. This type encodes metadata about the transaction currently being executed such as its sender, its digest, and the number of objects it has created. Most importantly, a TxContext has the ability to generate fresh object ID's.

The Rust version of this type is here, and the Move version is here. The steps required to unify these two representations are

  • Add a sender field to the Rust TxContext
  • The Move TxContext implements its own ID derivation here. We should delete this and use a native function that calls the Rust TxContext::fresh_id() instead
  • Serialize the Rust TxContext directly into BCS and eliminate the TxContextForMove hack
  • We need to address #65
  • Move TxContext to its own file

[fastx crypto] audit Object ID derivation

We need to define a ObjectIDPreimage struct that holds (transaction_id, new_obj_sequence), then make it BcsSignable and use sha3_hash to get the digest. This ensures that we have one way to derive hashes (incl. for what we sign) and therefore domain separation is ensured uniformly..

[fastx dist sys] Ensure all operations include the correct epoch

Fastx will operate within epochs, and actions in one epoch should not be confused for actions in a different epoch. We should ensure transactions contain the epoch; validators keep track of the current epoch and committee for the epoch; and checks are performed to not accept transactions from other epochs.

Receiver logic is vector for network DoS

Our ETH colleagues identified the uncontrolled creation of tasks, upon TCP connection, as well as the lack of any rate limiting / fairness / etc as a vector for DoS in Narwhal (This has been tested and confirmed by Adrian Perig's Team). Options to mitigate this include:

  • Add a MAC to authority-authority communications, checked before opening or maintaining state.
  • Use a single task with a UnorderedFutures to maintain the sender/receiver ends of all TCP connections (not a task each).
  • Drop unused or less used connections, etc.

Obvs any better ideas welcome here.

https://github.com/MystenLabs/narwhal/blob/9e34b18be0c77cb70d70073b7e8aa41e4c7910fd/network/src/receiver.rs#L64-L87

[fastx distsys] Refactor Client code

There are a lot of reference to balances lingering in Client code, e.g. get_spendable_amount, we need to remove all reference to balance before adding new object specific api to the Client

[fastx client api] Expand the Rust Client API

The current client API supports transfer, receive and get balance

It should be expended to support all the operations supported by OrderKind.

Also get_spendable_amount should be replaced by get_possesed_objects as we no longer have the concept of balance in the system.

The expended Client should contains the following functions :

fn transfer_to_fastpay(
    &mut self, 
    object_id: ObjectID, 
    recipient: FastPayAddress, 
    user_data: UserData
) -> AsyncResult<CertifiedOrder, Error>
fn transfer_to_primary(
    &mut self,
    object_id: ObjectID,
    recipient: PrimaryAddress,
    user_data: UserData,
) -> AsyncResult<CertifiedOrder, Error>
fn publish_module(
    &mut self, 
    gas_payment: ObjectRef, 
    module_bytes: Dec<u8>
) -> AsyncResult<CertifiedOrder, Error>
fn call_module(
    &mut self, 
    module: ModuleId,
    function: Identifier,
    type_arguments: Vec<TypeTag>,
    gas_payment: ObjectRef,
    object_arguments: Vec<ObjectRef>,
    pure_arguments: Vec<Vec<u8>>,
    gas_budget: u64,
) -> AsyncResult<CertifiedOrder, Error>
fn receive_from_fastpay(
    &mut self,
    certificate: CertifiedOrder,
) -> AsyncResult<(), Error> 
fn get_possesed_objects(&mut self) -> AsyncResult<Vec<ObjectRef>, Error>

[fastx dist sys] Design and implement re-configuration

fastx operates in epochs. Within each epoch committee and stake are stable, but between epochs they may change. Between epoch a rec-configuration protocol is ran between validators and a consensus system to ensure safety and liveness. We need to implement this re-configuration mechanism, specifically:

  • The logic by which a validator closes an epoch, and asks 2f+1 validators of the next epoch to provide a certificate over the set of certificates processed.
  • The logic by which an epoch starts through a validator accepting the first 2f+1 certificates (on the consensus core), initializes its database, and start processing transactions.
  • Efficiency improvements to minimize downtime.
  • Make decisions and implement the smart contract on an L1/consensus core driving the governance logic, and sequencing the certificates of state between epochs.

[fastx sharding] Sharding logic is broken right now

In our transitions between fastpay and fastx we broke the logic associated with sharding. In the fastpay world we filtered transactions in a shard by the single object_id of the transaction, and only executed it on a single shard. The fastx system allows for many objects, and therefore the sharding strategy has to be adapted accordingly.

How exactly we do sharding has to be determined by how exactly we do storage of locks and objects. So this will have to be dealt with down the line.

[programmability MVP][umbrella] end-to-end demo of "heroes of blockchain and magic" game

This is an umbrella task for the developer experience MVP that we are building towards (see #4 (comment) for the genesis of this goal):

"Heros of Blockchain and Magic" concept: You make a hero with a sword (onchain), and log in the game server (offchain) proving you own this hero. The game server does a read about the version of your hero to make sure you do not double-play. Then you explore around the map, and find boars and potions of different strength. Once the user chooses (in the UI) to interact with a a portion or boar on-chain, the game server will send the object to the user, triggering an event for the user indicating what sort of object has been received. The user's wallet will then craft a signed transaction that drinks the potion or slays the boar. The wallet should do this automatically upon getting the event--the user already gave consent via the interaction in the UI. After the user signals an intent to fight the boar in the UI, they can continue to walk around in the game UI finding more potions/boars while the transactions to send the boar/fight it get created and committed in the background.

At a high level, what we want is to build out everything required for a game player and game studio to interact with this blockchain game running on fastNFT network backed by 1 to N nodes.

[fastx adapter] fix failing expected value test

This expected value test works if you run it directly:

cd fastnft/tree/main/fastx_programmability/adapter/tests/testsuite/create_transfer_use 
cargo run -p fastx-adapter -- sandbox exp-test

, but not if you uncomment the test::run_one to drive the test via the cargo test hook here:

// uncomment test::run_one
RUST_BACKTRACE=1 cargo test

running 1 tests
test run_all::create_transfer_use/args.txt ... FAILED
Error: prefix not found

Stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /Users/shb/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.58/src/backtrace/libunwind.rs:90:5
      backtrace::backtrace::trace_unsynchronized
             at /Users/shb/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.58/src/backtrace/mod.rs:66:5
   1: backtrace::backtrace::trace
             at /Users/shb/.cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.58/src/backtrace/mod.rs:53:14
   2: anyhow::backtrace::capture::Backtrace::create
             at /Users/shb/.cargo/registry/src/github.com-1ecc6299db9ec823/anyhow-1.0.51/src/backtrace.rs:216:13
   3: anyhow::backtrace::capture::Backtrace::capture
             at /Users/shb/.cargo/registry/src/github.com-1ecc6299db9ec823/anyhow-1.0.51/src/backtrace.rs:204:17
   4: anyhow::error::<impl core::convert::From<E> for anyhow::Error>::from
             at /Users/shb/.cargo/registry/src/github.com-1ecc6299db9ec823/anyhow-1.0.51/src/error.rs:530:25
   5: <core::result::Result<T,F> as core::ops::try_trait::FromResidual<core::result::Result<core::convert::Infallible,E>>>::from_residual
             at /rustc/09c42c45858d5f3aedfa670698275303a3d19afa/library/core/src/result.rs:1915:27
   6: move_cli::sandbox::commands::test::determine_package_nest_depth
             at /Users/shb/.cargo/git/checkouts/diem-3157fea0403687f7/661a2d1/language/tools/move-cli/src/sandbox/commands/test.rs:106:13
   7: move_cli::sandbox::commands::test::copy_deps
             at /Users/shb/.cargo/git/checkouts/diem-3157fea0403687f7/661a2d1/language/tools/move-cli/src/sandbox/commands/test.rs:138:30
   8: move_cli::sandbox::commands::test::run_one
             at /Users/shb/.cargo/git/checkouts/diem-3157fea0403687f7/661a2d1/language/tools/move-cli/src/sandbox/commands/test.rs:181:26
   9: cli_testsuite::run_all
             at ./tests/cli_testsuite.rs:13:5
  10: datatest_stable::runner::Requirements::expand::{{closure}}::{{closure}}
             at /Users/shb/.cargo/registry/src/github.com-1ecc6299db9ec823/datatest-stable-0.1.1/src/runner.rs:355:51
  11: <alloc::boxed::Box<F,A> as core::ops::function::Fn<Args>>::call
             at /rustc/09c42c45858d5f3aedfa670698275303a3d19afa/library/alloc/src/boxed.rs:1650:9
  12: datatest_stable::runner::run_test::{{closure}}::{{closure}}
             at /Users/shb/.cargo/registry/src/github.com-1ecc6299db9ec823/datatest-stable-0.1.1/src/runner.rs:202:61
  13: core::ops::function::FnOnce::call_once
             at /rustc/09c42c45858d5f3aedfa670698275303a3d19afa/library/core/src/ops/function.rs:227:5
  14: <core::panic::unwind_safe::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
             at /rustc/09c42c45858d5f3aedfa670698275303a3d19afa/library/core/src/panic/unwind_safe.rs:271:9
  15: std::panicking::try::do_call
             at /rustc/09c42c45858d5f3aedfa670698275303a3d19afa/library/std/src/panicking.rs:403:40
  16: ___rust_try
  17: std::panicking::try
             at /rustc/09c42c45858d5f3aedfa670698275303a3d19afa/library/std/src/panicking.rs:367:19
  18: std::panic::catch_unwind
             at /rustc/09c42c45858d5f3aedfa670698275303a3d19afa/library/std/src/panic.rs:129:14
  19: datatest_stable::runner::run_test::{{closure}}
             at /Users/shb/.cargo/registry/src/github.com-1ecc6299db9ec823/datatest-stable-0.1.1/src/runner.rs:202:28
  20: std::sys_common::backtrace::__rust_begin_short_backtrace
             at /rustc/09c42c45858d5f3aedfa670698275303a3d19afa/library/std/src/sys_common/backtrace.rs:125:18
  21: std::thread::Builder::spawn_unchecked::{{closure}}::{{closure}}
             at /rustc/09c42c45858d5f3aedfa670698275303a3d19afa/library/std/src/thread/mod.rs:481:17
  22: <core::panic::unwind_safe::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
             at /rustc/09c42c45858d5f3aedfa670698275303a3d19afa/library/core/src/panic/unwind_safe.rs:271:9
  23: std::panicking::try::do_call
             at /rustc/09c42c45858d5f3aedfa670698275303a3d19afa/library/std/src/panicking.rs:403:40
  24: ___rust_try
  25: std::panicking::try
             at /rustc/09c42c45858d5f3aedfa670698275303a3d19afa/library/std/src/panicking.rs:367:19
  26: std::panic::catch_unwind
             at /rustc/09c42c45858d5f3aedfa670698275303a3d19afa/library/std/src/panic.rs:129:14
  27: std::thread::Builder::spawn_unchecked::{{closure}}
             at /rustc/09c42c45858d5f3aedfa670698275303a3d19afa/library/std/src/thread/mod.rs:480:30
  28: core::ops::function::FnOnce::call_once{{vtable.shim}}
             at /rustc/09c42c45858d5f3aedfa670698275303a3d19afa/library/core/src/ops/function.rs:227:5
  29: <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once
             at /rustc/09c42c45858d5f3aedfa670698275303a3d19afa/library/alloc/src/boxed.rs:1636:9
      <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once
             at /rustc/09c42c45858d5f3aedfa670698275303a3d19afa/library/alloc/src/boxed.rs:1636:9
      std::sys::unix::thread::Thread::new::thread_start
             at /rustc/09c42c45858d5f3aedfa670698275303a3d19afa/library/std/src/sys/unix/thread.rs:106:17
  30: _pthread_from_mach_thread_np

failures:
    run_all::create_transfer_use/args.txt

Looks like a crash inside of diem code.

Worker crash fault-tolerance

The Primary - Worker architecture of the nodes is a classic "primary-secondary" approach.

In the current Celo integration plan, we are thinking about two successive phases:

  1. using validators to propose TXes, where the TXes are found in the existing devp2p mempool,
  2. validators receive TXes directly, through their workers, and the validators submit from their own "shard" of TXes,

This issue is about phase 2:

  • if TXes are submitted by the user to a single validator, that's not super fault-tolerant (a devp2p / libp2p gossipsub network may help here)
  • if a worker, recipient of "unique" TXes, dies through a crash fault, the network loses the full TX copy, along with other TXes uniquely submitted to that worker

This latter point hampers:

  • crash fault tolerance w.r.t the users, (is my TX lost)
  • crash fault tolerance w.r.t the nodes (are all my batches something I can serve)

The solution for this is data replication: every TX is maintained replicated on >= 2 workers of the same validator.

When the TX is incorporated into a batch, and then into a block, it would be great to naturally provide the same replication guarantee for the group (batch or block) as we do for the individual TXes with a minimum of extra data transfer.

[genesis] fastx genesis with initial modules and state

We need this to start writing tests that exercise programmability. The plan:

  • Finish the module publishing logic
  • Add genesis code that publishes the fastX framework/ modules
  • Use the genesis to start writing tests with toy modules that build on framework functionality like Transfer
  • Add a gas token to the framework to unblock #45

[fastx types] make size of Move's `address` type configurable

Move account addresses are 16 bytes. We would like to make them the same size as fastX authenticators (i.e., FastPayAddress), and (ideally) fastX ObjectID's too. We haven't decided on the size of either of those types yet, but they will likely need to be >= 20 bytes for safety (e.g., a 32 byte hash truncated to the shortest length that is safe w.r.t collisions).

Whatever length(s) we chose, we need to be able to adjust Move addresses accordingly. The size of Move addresses is determined by this constant in the Diem codebase. We need to tweak it via one mechanism or another. Some ideas:

  • cargo magic to set a constant at compile-time via a build config (preferred long-term solution)
  • Use cargo's patch feature to override the address length locally (probably the quickest short term solution)
  • Use a fork of Diem with our preferred address length (least preferred solution)

[fastx verifier] call Move linker directly instead of using VM publish API's

Linking checks that the handles in a a Move bytecode module (e.g., function handles, struct handles, module handles) refer to already-published modules and that names/signatures in the handle match the definition in their declaring module (some mroe details here).

Today, the Move VM only exposes the linker through its publish_module and publish_module_bundle API's, which run the linker, but also do several other checks that FastX does not want (e.g., checking that module.self_id().address() is equal to the transaction sender). In addition, these API's take raw bytes and then deserialize the module(s), which is wasteful because we also need to deserialize the modules in order to run our FastX verifier passes.

Thus, the task is to expose a VM API for the linker that operates directly over CompiledModules--basically, refactor to expose https://github.com/diem/diem/blob/main/language/move-vm/runtime/src/runtime.rs#L105#L128.

[fastx distsys] Fix tests to remove `address_to_object_id_hack` hack

When we adapted fastnft from fastpay we had to convert the account model into an object model. Many of the tests had to be adapted to work on an object instead of an account and we did this by deriving an object id from the public key of the account using a function address_to_object_id_hack.

We should re-factor the tests to be using objects instead of account, and do away with the need for the address_to_object_id_hack function.

[fastx distsys] Refactor Sequence number

In the current design, each client have one sequence number counter next_sequence_number to keep track of the client's certificate history, however this become a problem when we try to retrieve certificate from authority because we don't record the association between object id and sequence number, we don't know which authority to query from for a particular sequence number.

The current work around is looping through each authorities until we have a hit, but this is inefficient.

[fastx distsys] Implement multiple object, flexible transactions

Fastnft should be take transactions operating on multiple objects, execute them, and then output potentially many objects. The current fastpay refactor only has a single transaction implementing transfer, taking one object and mutating its owner. We need to implement the core logic to allow for multiple object transactions and down the line a richer set of transactions.

More information on the idealized model of execution can be found in this repo:
https://github.com/MystenLabs/fastnftexec-experimental

[devex] use `anyhow` crate for `Result` instead of `failure`

FastPay was written at a time when the failure crate was in vogue, but it is now deprecated. anyhow is a vastly superior alternative that should facilitate creating errors and interacting with other crates that expose errors (which will invariably use anyhow). We should probably make this switch sooner rather than later to make the refactoring less painful...

[fastx adapter] bytecode verifier pass to ensure that module's self address is not used by bytecodes

Every module has a "self" address that lives in module.address_identifiers[0]. The fastX adapter overwrites this self address to the object ID of the module to enable the Move VM to look up a module by its ID.

We should add a bytecode verifier pass that ensures no bytecodes read from the module.address_identifiers[0] slot that will be overwritten. If bytecodes reference this slot, the effect will be confusing--e.g., a branch like if (x == old_self_address) could sneakily change to if (x == overwritten_id) .

One additional (related) measure that might help is enforcing that the self address is always a distinguished value (e.g., 0xFF...F) before mutation to reduce the likelihood of accidental usage.

[fastx adapter] implement immutable objects

  • Add read_only: bool field to MoveValue
  • Check that field is false for all mutable input parameters to a MoveCall
  • Add Move Freeze module to the framework + freeze<T: key>(t: T) native function
  • Implement native function similar to Transfer::transfer that emits a freeze event
  • Inside adapter, add postprocessing logic for freeze that sets read_only to true

[fastx programmability] Logic to update module handles of dependencies in module publishing flow

Background

In "normal" Move, a module is uniquely identified by ModuleId derived from its "self address" and its name. E.g., module 0x1::MyModule has the module Id 0x1::MyModule, where 0x is the self address.

However, in fastX we need the module's self address to be the same as its object ID, both to prevent duplicate publishing of modules and to enable lookups of a module and its dependencies by ID. The natural solution is to ask a user to update a module with its self address set to its ObjectID. However, ObjectID's are derived from the hash of the transaction that creates the object (which itself contains the module and its self ID!), so we have a circularity...

This problem is known, and already solved by the following (unfortunate, but necessary) workaround: before actually publishing the module, we mutate its self address to the correct ObjectID.

The Problem

However, this workaround creates its own problems (e.g., the one described in #56). The big one is that if you are publishing module 0x1:Parent and dependent module 0x2::Child in the same transaction, the current publishing logic will:

  1. overwrite 0x1 with a fresh object ID in Parent
  2. overwrite 0x2 with a fresh object ID in Child

The problem is that Child will use the module handle 0x1::Parent (because it depends on Parent!), but steps (1) and (2) do not update that handle to Parent's new address. The resulting modules will fail to link, and publishing will fail.

The Proposed Solution

Both this issue and #56 can be solved by more careful (and more complex) bytecode rewriting on the publish codepath. The rewrites that we do should be both semantics-preserving (e.g., not cause problems like #56) and ensure that if the input modules linked before rewriting, they should also link after rewriting.

[Move devex] Move source code linters to explain language subset

FastX needs a number of custom bytecode verifier passes (see #18, #19, #16, #15) to keep users in the no-shared-memory subset of Move. This is sufficient for on-chain safety, but for an end-user trying to write code in the Move source language, finding out that you've strayed from the subset via a bytecode verifier error at module publish time is not a great experience.

We should address this is by adding custom linters that enforce the subset rules at the source level. See this for some examples in the existing compiler. The code for this linters should live in the fastNFT repo. We will probably need to extend the upstream compiler to make it easy to plug in custom linters.

[fastx distsys] Add a `TransactionDigest` in the `ObjectRef` of objects

Ideally we would like objects to be referenced by the ordered triplet (object_id, sequence_number, transaction_digest) instead of the current ObjectRef being just (object_id, sequence_number). The transaction digest is a cryptographic hash of the transaction in the certificate that created this version of the object. This allows for the full history of certificates and objects to be self-certifying ie. starting from a certificate anyone can walk 'back' the digests contained in objects and certificates up to the root certificate to check the computation of the full history of an object.

This issue involves:

  • derive a transaction digest from the transaction that creates objects (one should be around).
  • add the digest to the ObjectRef and fix all structures to work with that.
  • (optional maybe separate PR) add ways to extract the full history of certificates (and objects?) from a certificate and return them for anyone to check correct execution (auditing)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.