move-language / move Goto Github PK
View Code? Open in Web Editor NEWLicense: Apache License 2.0
License: Apache License 2.0
Right now Move uses the move-cli to create and manage packages. The goal of this proposal is to provide a website in addition to the CLI for more transparency and more easily accessible package pages like Rubygems or Crates.io
At the time of writing, the logic for interacting and getting package info from multiple blockchains is rather unclear. Therefore, the website current goal is to act as a central metadata hub for packages hosted on Github only.
The website uses an in-house design. You can see it at https://www.figma.com/file/mGLv9qI5n1XSVJickhLuQD/Movey
Changes we have made to Move-CLI
Before you use the new command to upload metadata to Movey make sure your package has been pushed to Github and the remote must be named βoriginβ.
Step 1: Navigate to the folder containing your package.
Step 2: Run the following command:
move package upload
Right now Movey is only a metadata hub, all the heavy work of pulling or version control of packages rely on Github. Maybe expansion on hosting Move own dependencies in the future?
Should Movey run check on every single package it knows to ensure it's a valid package and there's no malicious code?
Security could be enhanced by adding apikey to prevent unauthorized calls.
Right now Movey is a closed source project, however we would like to hear what the community has to say. We do plan to go open source in the near future.
I have mentioned the idea of TypeTable in the documentation of Table, and I describe it in more detail here.
According to the implementation of Table(#150), we get:
module Std::Table {
native struct Table<K, V: store> has store;
native fun create<K, V>(): Table<K, V>
native fun destroy<K, V>(t: Table<K, V>);
native fun insert<K, V>(t: &mut Table<K, V>, k: &K, v: V);
native fun remove<K, V>(t: &mut Table<K, V>, k: &K): V;
native fun contains_key<K, V>(t: &Table<K, V>, k: &K): bool;
native fun borrow<K, V>(t: &Table<K, V>, k: &K): &V;
native fun borrow_mut<K, V>(t: &mut Table<K, V>, k: &K): &mut V;
}
But this Table can only use type K's value as the key, not type K as the key like borrow_global.
So I suggest introducing TypeTable with the basic operations described below:
module Std::TypeTable {
native struct TypeTable has store;
native fun create(): TypeTable
native fun destroy(t: TypeTable);
native fun insert<T>(t: &mut TypeTable, v: T);
native fun remove<T>(t: &mut TypeTable<K>): T;
native fun contains_key<T>(t: &TypeTable<T>): bool;
native fun borrow<T>(t: &TypeTable): &T;
native fun borrow_mut<T>(t: &mut TypeTable<T>): &mut T;
}
Now, we can define a AccountStorage struct in Move:
module Std::Account{
struct AccountStroage{
resources: TypeTable,
moudles: Table<Identifer,vector<u8>>,
}
}
Then we bind the table when Account create, such as:
module Std::Account{
public fun create_account(addr: address){
let resources = TypeTable::create();
let modules = Table::create<Identifer,vector<u8>>();
let account_storage = AccountStorage{
resources,
modules,
};
native_save_account(addr,account_storage);
}
public fun borrow<T>(addr:address):&T{
let account_storage = native_get_account_staroge(addr);
//This expression is not available in the current Move
//We can not return ref like this, but we can ignore it now.
return TypeTable::borrow<T>(&account_storage.resources);
}
public fun move_to<T>(signer:&signer, t:T){
//if do not want to limit signer, can use address.
let addr = Signer:address_of(signer);
let account_storage = native_get_account_staroge(addr);
TypeTable::insert(&mut account_storage.resources,t);
}
//We can update or deploy code in Move now, like `create2` in ethereum.
public fun update_module(signer:&signer, name:Identifer, code:vector<u8>){
let account_storage = native_get_account_staroge(addr);
account_storage.modules.insert(name, code);
}
}
This feature can implement via an extension like Table and the backend storage is the same as Table, but TypeTable needs the same security guarantees as borrow_global.
We have two approaches to achieving this goal:
Migrate from diem/move, previous discussion diem/move#158
Not sure I have the wrong version of the solidity compiler. I installed it from node like this https://docs.soliditylang.org/en/v0.8.13/installing-solidity.html#npm-node-js
It's possible it requires a specific version, but just trying to make sure all the tests pass!
Code snippet to reproduce
cargo test
Stack trace/error message
test run_all::dev_address/args.evm.txt ... FAILED
Error: Expected output differs from actual output:
Command `package build -v -d --arch ethereum`:
COMPILING A to Yul
GENERATING EVM bytecote from Yul
ERROR Failed to generate EVM bytecote
Error: error: unknown option '--strict-assembly'
Working tests :)
Please complete the following information:
See the error log:
$ npx hardhat test
An unexpected error occurred:
[Error: ENOENT: no such file or directory, stat '/Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/ERC721Mock/Move.toml'] {
errno: -2,
code: 'ENOENT',
syscall: 'stat',
path: '/Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/ERC721Mock/Move.toml'
}
contracts/ERC721Mock
does not exist in this branch. It did in a different branch. However, it complains.
value comparison (vec_u8_1 == vec_u8_2
) works but not reference comparison.
However, this is not a blocker for the demo.
Given the example:
fun f(){return;}
... the compiler reports
adding a semicolon implicitly adds '()' value after the semicolon. That value '()' will not be reachable
But the documentation says:
The unit value '()' does not result in any runtime value ( https://diem.github.io/move/tuples.html )
This is confusing, specifically for new users which are not acquainted with the Rust-style syntax of Move,
[Collected from Aptos user forum]
Right now when you run move package build
, it writes both info and errors to stdout. This creates problems for tools that need to differentiate errors from regular info.
Need this feature in ERC721Mock::supportsInterface
To correctly execute a script, we need to have the signature of the script to (1) validate the script has the correct signature and (2) to determine how to add a signer into the args.
Now, there is already support for the script_function (some previous discussion happens here diem/move#209). However, we still need a "load_script" function to provide similar functionalities.
The following test in hardhat-examples/test/ExternalCall.test.js
fails.
describe('Receiver', function () {
it('receiver test', async function () {
const receiver = await Receiver.new(RECEIVER_MAGIC_VALUE, Error.None);
const receipt = await this.externalCall.doSafeTransferAcceptanceCheck(this.externalCall.address, receiver.address, 5042, '0x42');
});
});
The failure message is as follows:
1) Contract: ExternalCall
Receiver
receiver test:
Error: Returned error: Transaction ran out of gas
at Context.<anonymous> (test/ExternalCall.test.js:71:53)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
Right now Move uses the move-cli to create and manage packages. The goal of this proposal is to provide a website in addition to the CLI for more transparency and more easily accessible package pages like Rubygems or Crates.io
At the time of writing, the logic for interacting and getting package info from multiple blockchains is rather unclear. Therefore, the website current goal is to act as a central metadata hub for packages hosted on Github only.
- Scenario 1: A user writes a new Move package and then use the move-cli tool to upload/publish the package to get recognized in the Movey registry. In order to do this we added a new command (upload
) to call an api request to Movey with the package's metadata info (name, version, description, github, rev,...) and store it as a new package record.
Question:
upload
request so that Movey can recognize the user and set them as the package owner. Is this preferable or do you have any suggestion of wrapping this?- Scenario 2: A user uses move-cli tool to fetch existing dependencies for a Move package they are working on. We hook into the process and sends an api request to move-cli to register a "download" for each of the existing dependency package. If it's already registered on Movey, we increase the download count. If it does not, we create a shadow record for it, starting the download with 1.
Question: Does this work with the way Move packages are managed, or is there a better way to recognize a new "download" of a package? After all, our goal is to have a metric similar to "downloads count" of crates.io or rubygems.
- Scenario 3: A user visits movey.org and view packages there / search packages in the registry, similar to crates.io . In order to support that we'll store a list of available packages that either comes from (a) Scenario 1 above (explicitly uploaded by the creator), or (b) crawling the list of all available/public Move packages somehow.
Question: Is there any way/method for us to "crawl" and get the list of all existing Move packages? Because of the nature of storing these packages/their compiled binary on chains, it would be super helpful if you can point us in a direction to accomplish this (or if it's feasible or not).
The website uses an in-house design. You can see it at https://www.figma.com/file/mGLv9qI5n1XSVJickhLuQD/Movey
Changes we have made to Move-CLI
Before you use the new command to upload metadata to Movey make sure your package has been pushed to Github and the remote must be named βoriginβ.
Step 1: Navigate to the folder containing your package.
Step 2: Run the following command:
move package upload
Right now Movey is only a metadata hub, all the heavy work of pulling or version control of packages rely on Github. Maybe expansion on hosting Move own dependencies in the future?
Should Movey run check on every single package it knows to ensure it's a valid package and there's no malicious code?
Security could be enhanced by adding apikey to prevent unauthorized calls.
Right now Movey is a closed source project, however we would like to hear what the community has to say. We do plan to go open source in the near future.
Move-compiler needs to support Callback/Interact function, which is convenient for platform expansion without FS.
I need to implement a Move build in a web browser.
But the browser does not support file operations, compiling move-compiler to wasm-unkown-unkown will fail because it cannot read the file. The solution of the pontem-network team is to let move-compiler provide compilation Callback/Interact, and then wasm implements the file access interface separately. Related Commit: pontem-network/diem@11ae64b
But now move-language/move has no Callback/Interact function.
Describe the solution you'd like
Merge commit: pontem-network/diem@11ae64b
Describe alternatives you've considered
Rust supports registering custom filesystems
Are you willing to open a pull request? (See CONTRIBUTING)
No
My issue: starcoinorg/starcoin#3363
Access FS fail in wasm:
As mentioned in #18, we are very restrictive in our character sets today. We had discussed relaxing this late last year, but made no changes yet. We should open up the character sets and give warnings where we think it might be applicable
Package system should expose build
and build_and_report
variants that return errors or report errors to stdout respectively. Currently it always reports to stdout and exits
I'm not quite sure what I'm asking in practice. Maybe taking the key by value (and require K: copy).
This doesn't compile because "Invalid return. Local variable 'bucket_idx' is still being borrowed.".
A similar thing can be done easily in Rust.
module AptosFramework::BucketedVector {
use AptosFramework::Table;
use Std::Vector;
struct BucketedVector<V> has store {
bucket_size: u64,
buckets: Table::Table<u64, vector<V>>
}
public fun borrow<T: store>(vec: &BucketedVector<T>, idx: u64): &T {
let bucket_idx = idx / vec.bucket_size;
let item_idx = idx % vec.bucket_size;
let bucket = Table::borrow(&vec.buckets, &bucket_idx);
Vector::borrow(bucket, item_idx)
}
}
Describe the solution you'd like
Make it work so we can implement a BucketedVector.
Describe alternatives you've considered
Let user code manage the buckets directly.
Are you willing to open a pull request? (See CONTRIBUTING)
I'm not able to.
Currently, Move's structs use implicit visibility, e.g.
struct Foo{
f1: u64,
}
is equivalent to.
public struct Foo{
private f1: u64,
}
Also, an implicit global storage access restriction is used to ensure that a struct can only be borrowed in the module in which it is defined.
This is actually equivalent to a conditional visibility constraint and has the same effect as adding a private visibility constraint to the struct.
private struct Foo has key{
}
So I propose to introduce the visibility of structs. This leaves it up to the smart contract developer to decide on access control for the global storage and the struct fields.
For example.
module MyModule {
public struct Foo has key{
public f1:u64,
}
private struct Bar has key{
f1:u64,
}
public fun do_some(){
let foo = borrow_global<Foo>();
let bar = borrow_global<Bar>();
// Both of these work
}
}
module XXX {
use MyModule::Foo;
public fun so_some(){
let foo = borrow_global<Foo>();
let f1 = foo.f1
let bar = borrow_global<Bar>();
// the first one will succeed, the second one will fail
}
}
Of course, compatibility is a bigger problem, this is just an idea. If it works, I can do more work on it.
Migrate from diem/move, previous discussion diem/move#157
this causes the gas test fail in the ERC1155(721) testsuite
// TODO: exceeded the gas limit (30560 > 30000)
(*Vector::borrow(&interfaceId, 0) == *Vector::borrow(&id165, 0) &&
*Vector::borrow(&interfaceId, 1) == *Vector::borrow(&id165, 1) &&
*Vector::borrow(&interfaceId, 2) == *Vector::borrow(&id165, 2) &&
*Vector::borrow(&interfaceId, 3) == *Vector::borrow(&id165, 3)
) ||
(*Vector::borrow(&interfaceId, 0) == *Vector::borrow(&id1155, 0) &&
*Vector::borrow(&interfaceId, 1) == *Vector::borrow(&id1155, 1) &&
*Vector::borrow(&interfaceId, 2) == *Vector::borrow(&id1155, 2) &&
*Vector::borrow(&interfaceId, 3) == *Vector::borrow(&id1155, 3)
// TODO: Exceeds the gas limit (33834 > 30000)
// ERC721Metadata (5b5e139f)
(*Vector::borrow(&interfaceId, 0) == 91 &&
*Vector::borrow(&interfaceId, 1) == 94 &&
*Vector::borrow(&interfaceId, 2) == 19 &&
*Vector::borrow(&interfaceId, 3) == 159
) ||
// ERC165
(*Vector::borrow(&interfaceId, 0) == 1 &&
*Vector::borrow(&interfaceId, 1) == 255 &&
*Vector::borrow(&interfaceId, 2) == 201 &&
*Vector::borrow(&interfaceId, 3) == 167
) ||
// ERC721
(*Vector::borrow(&interfaceId, 0) == 128 &&
*Vector::borrow(&interfaceId, 1) == 172 &&
*Vector::borrow(&interfaceId, 2) == 88 &&
*Vector::borrow(&interfaceId, 3) == 205
)
npx hardhat compile
Nothing to compile
Building 10 Move packages...
Successfully built /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/Caller
Successfully built /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/ERC20DecimalsMock
Successfully built /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/ERC20Mock
Successfully built /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/Event
Failed to build /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/ExternalCall
Error: exiting with Yul generation errors
Successfully built /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/FortyTwo
Successfully built /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/Greeter
Successfully built /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/Native
Successfully built /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/Revert
Successfully built /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/Token
An unexpected error occurred:
Error: Failed to build one or more Move packages
at SimpleTaskDefinition.action (/Users/jkpark/Work/move/language/evm/hardhat-move/src/index.ts:388:19)
at Environment._runTaskDefinition (/Users/jkpark/Work/move/language/evm/hardhat-examples/node_modules/hardhat/src/internal/core/runtime-environment.ts:219:14)
at Environment.run (/Users/jkpark/Work/move/language/evm/hardhat-examples/node_modules/hardhat/src/internal/core/runtime-environment.ts:131:14)
at SimpleTaskDefinition.action (/Users/jkpark/Work/move/language/evm/hardhat-examples/node_modules/hardhat/src/builtin-tasks/compile.ts:1422:7)
at Environment._runTaskDefinition (/Users/jkpark/Work/move/language/evm/hardhat-examples/node_modules/hardhat/src/internal/core/runtime-environment.ts:219:14)
at Environment.run (/Users/jkpark/Work/move/language/evm/hardhat-examples/node_modules/hardhat/src/internal/core/runtime-environment.ts:131:14)
at main (/Users/jkpark/Work/move/language/evm/hardhat-examples/node_modules/hardhat/src/internal/cli/cli.ts:218:5)
$ npx hardhat compile
Nothing to compile
Building 14 Move packages...
Failed to build /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/Native
error: Invalid value "ethereum" for '--arch <ARCHITECTURE>': Unrecognized architecture ethereum -- only "move", "async-move" are supported
For more information try --help
Failed to build /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/Greeter
error: Invalid value "ethereum" for '--arch <ARCHITECTURE>': Unrecognized architecture ethereum -- only "move", "async-move" are supported
For more information try --help
Failed to build /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/FortyTwo
error: Invalid value "ethereum" for '--arch <ARCHITECTURE>': Unrecognized architecture ethereum -- only "move", "async-move" are supported
For more information try --help
Failed to build /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/ExternalCall
error: Invalid value "ethereum" for '--arch <ARCHITECTURE>': Unrecognized architecture ethereum -- only "move", "async-move" are supported
For more information try --help
Failed to build /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/Event
error: Invalid value "ethereum" for '--arch <ARCHITECTURE>': Unrecognized architecture ethereum -- only "move", "async-move" are supported
For more information try --help
Failed to build /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/ERC721Tradable
error: Invalid value "ethereum" for '--arch <ARCHITECTURE>': Unrecognized architecture ethereum -- only "move", "async-move" are supported
For more information try --help
Failed to build /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/ERC721Mock
error: Invalid value "ethereum" for '--arch <ARCHITECTURE>': Unrecognized architecture ethereum -- only "move", "async-move" are supported
For more information try --help
Failed to build /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/ERC20Mock
error: Invalid value "ethereum" for '--arch <ARCHITECTURE>': Unrecognized architecture ethereum -- only "move", "async-move" are supported
For more information try --help
Failed to build /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/ERC20DecimalsMock
error: Invalid value "ethereum" for '--arch <ARCHITECTURE>': Unrecognized architecture ethereum -- only "move", "async-move" are supported
For more information try --help
Failed to build /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/ERC1155Tradable
error: Invalid value "ethereum" for '--arch <ARCHITECTURE>': Unrecognized architecture ethereum -- only "move", "async-move" are supported
For more information try --help
Failed to build /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/ERC1155Mock
error: Invalid value "ethereum" for '--arch <ARCHITECTURE>': Unrecognized architecture ethereum -- only "move", "async-move" are supported
For more information try --help
Failed to build /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/Caller
error: Invalid value "ethereum" for '--arch <ARCHITECTURE>': Unrecognized architecture ethereum -- only "move", "async-move" are supported
For more information try --help
Failed to build /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/Revert
error: Invalid value "ethereum" for '--arch <ARCHITECTURE>': Unrecognized architecture ethereum -- only "move", "async-move" are supported
For more information try --help
Failed to build /Users/jkpark/Work/move/language/evm/hardhat-examples/contracts/Token
error: Invalid value "ethereum" for '--arch <ARCHITECTURE>': Unrecognized architecture ethereum -- only "move", "async-move" are supported
For more information try --help
An unexpected error occurred:
Error: Failed to build one or more Move packages
at SimpleTaskDefinition.action (/Users/jkpark/Work/move/language/evm/hardhat-move/src/index.ts:388:19)
at Environment._runTaskDefinition (/Users/jkpark/Work/move/language/evm/hardhat-examples/node_modules/hardhat/src/internal/core/runtime-environment.ts:219:14)
at Environment.run (/Users/jkpark/Work/move/language/evm/hardhat-examples/node_modules/hardhat/src/internal/core/runtime-environment.ts:131:14)
at SimpleTaskDefinition.action (/Users/jkpark/Work/move/language/evm/hardhat-examples/node_modules/hardhat/src/builtin-tasks/compile.ts:1422:7)
at Environment._runTaskDefinition (/Users/jkpark/Work/move/language/evm/hardhat-examples/node_modules/hardhat/src/internal/core/runtime-environment.ts:219:14)
at Environment.run (/Users/jkpark/Work/move/language/evm/hardhat-examples/node_modules/hardhat/src/internal/core/runtime-environment.ts:131:14)
at main (/Users/jkpark/Work/move/language/evm/hardhat-examples/node_modules/hardhat/src/internal/cli/cli.ts:218:5)
If a generic function contains a generic borrow of a struct that takes N type parameters Ty1, Ty2, ..., TyN, then all the type parameters have to appear as the first N type parameters of the function. Otherwise, the move-dissasembler cannot generate the string represenation of the borrowed type in struct_type_info()
function in disaseembler.rs.
Here is an MWE that demonstrates the problem.
After compilation, the FooAX
module can be dissembled by move-dissasembler.
address 0x1 {
module FooAX {
struct C<T: copy + store + drop> has key { f: T }
fun foo<A: copy + store + drop, X>(x: X): X acquires C {
let _ = borrow_global<C<A>>(@0x1);
x
}
}
}
But move-disassembler failed to show the bytecode of the almost identical module FooXA
:
address 0x1 {
module FooXA {
struct C<T: copy + store + drop> has key { f: T }
fun foo<X, A: copy + store + drop>(x: X): X acquires C { // The order changes
let _ = borrow_global<C<A>>(@0x1);
x
}
}
}
The error info is:
thread 'main' panicked at 'Unable to dissassemble: Type parameter index 1 out of bounds while disassembling type signature', language/tools/move-disassembler/src/main.rs:128:58
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
move-dissembler should be able to handle both.
After some inspection of the source code, I found that when disassemble_instruction()
sees a BorrowGlobalGeneric, it uses struct_type_info()
, where signature
has index not within the length of struct_source_map.type_parameters
, which causes the error.
Right now when you run move package build --arch ethereum
, it always builds everything from scratch. We should detect whether the sources have changed and only rebuild if so.
Found RUSTSEC in dependencies in job https://github.com/move-language/move/actions/runs/2155593820
Fetching advisory database from `https://github.com/RustSec/advisory-db.git`
Loaded 404 security advisories (from /opt/cargo/advisory-db)
Updating crates.io index
Scanning Cargo.lock for vulnerabilities (487 crate dependencies)
Crate: chrono
Version: 0.4.19
Title: Potential segfault in `localtime_r` invocations
Date: 2020-11-10
ID: RUSTSEC-2020-0159
URL: https://rustsec.org/advisories/RUSTSEC-2020-0159
Solution: No safe upgrade is available!
Dependency tree:
chrono 0.4.19
βββ x 0.1.0
βββ tera 1.7.1
β βββ move-prover-boogie-backend 0.1.0
β βββ move-to-yul 0.1.0
β β βββ move-unit-test 0.1.0
β β β βββ move-table-extension 0.1.0
β β β β βββ move-vm-test-utils 0.1.0
β β β β β βββ test-generation 0.1.0
β β β β β βββ move-vm-integration-tests 0.1.0
β β β β β βββ move-unit-test 0.1.0
β β β β β βββ move-transactional-test-runner 0.1.0
β β β β β β βββ move-vm-transactional-tests 0.1.0
β β β β β β βββ move-ir-compiler-transactional-tests 0.1.0
β β β β β β βββ move-compiler-transactional-tests 0.1.0
β β β β β β βββ bytecode-verifier-transactional-tests 0.1.0
β β β β β βββ language-benchmarks 0.1.0
β β β β βββ move-vm-integration-tests 0.1.0
β β β β βββ move-unit-test 0.1.0
β β β β βββ move-cli 0.1.0
β β β β βββ move-transactional-test-runner 0.1.0
β β β β βββ move-table-extension 0.1.0
β β β β βββ move-stdlib 0.1.0
β β β β βββ test-generation 0.1.0
β β β β βββ move-vm-integration-tests 0.1.0
β β β β βββ move-unit-test 0.1.0
β β β β βββ move-transactional-test-runner 0.1.0
β β β β βββ move-to-yul 0.1.0
β β β β βββ move-table-extension 0.1.0
β β β β βββ move-stackless-bytecode 0.1.0
β β β β β βββ spec-flatten 0.1.0
β β β β β βββ read-write-set 0.1.0
β β β β β β βββ move-cli 0.1.0
β β β β β βββ prover-mutation 0.1.0
β β β β β βββ prover-lab 0.1.0
β β β β β βββ move-to-yul 0.1.0
β β β β β βββ move-stackless-bytecode-interpreter 0.1.0
β β β β β β βββ move-unit-test 0.1.0
β β β β β β βββ move-transactional-test-runner 0.1.0
β β β β β β βββ move-prover 0.1.0
β β β β β β β βββ spec-flatten 0.1.0
β β β β β β β βββ prover-mutation 0.1.0
β β β β β β β βββ prover-lab 0.1.0
β β β β β β β βββ move-stdlib 0.1.0
β β β β β β β βββ move-errmapgen 0.1.0
β β β β β β β β βββ move-stdlib 0.1.0
β β β β β β β β βββ move-prover 0.1.0
β β β β β β β β βββ move-package 0.1.0
β β β β β β β β β βββ move-table-extension 0.1.0
β β β β β β β β β βββ move-stdlib 0.1.0
β β β β β β β β β βββ move-cli 0.1.0
β β β β β β β β βββ move-cli 0.1.0
β β β β β β β βββ move-docgen 0.1.0
β β β β β β β β βββ move-stdlib 0.1.0
β β β β β β β β βββ move-prover 0.1.0
β β β β β β β β βββ move-package 0.1.0
β β β β β β β βββ move-cli 0.1.0
β β β β β β β βββ move-abigen 0.1.0
β β β β β β β βββ move-prover 0.1.0
β β β β β β β βββ move-package 0.1.0
β β β β β β βββ bytecode-interpreter-testsuite 0.1.0
β β β β β βββ move-prover-boogie-backend 0.1.0
β β β β β βββ move-prover 0.1.0
β β β β β βββ move-docgen 0.1.0
β β β β βββ move-compiler 0.0.1
β β β β β βββ test-generation 0.1.0
β β β β β βββ spec-flatten 0.1.0
β β β β β βββ move-vm-runtime 0.1.0
β β β β β β βββ test-generation 0.1.0
β β β β β β βββ move-vm-test-utils 0.1.0
β β β β β β βββ move-vm-integration-tests 0.1.0
β β β β β β βββ move-unit-test 0.1.0
β β β β β β βββ move-transactional-test-runner 0.1.0
β β β β β β βββ move-table-extension 0.1.0
β β β β β β βββ move-stdlib 0.1.0
β β β β β β βββ move-stackless-bytecode-interpreter 0.1.0
β β β β β β βββ move-cli 0.1.0
β β β β β β βββ move-async-vm 0.1.0
β β β β β β βββ language-benchmarks 0.1.0
β β β β β βββ move-vm-integration-tests 0.1.0
β β β β β βββ move-unit-test 0.1.0
β β β β β βββ move-transactional-test-runner 0.1.0
β β β β β βββ move-to-yul 0.1.0
β β β β β βββ move-table-extension 0.1.0
β β β β β βββ move-stdlib 0.1.0
β β β β β βββ move-prover 0.1.0
β β β β β βββ move-package 0.1.0
β β β β β βββ move-model 0.1.0
Right now the EVM specific attributes have general names like #[storage]
, #[event(...)]
, #[create(...)]
, ...
We should probably include a prefix to indicate that these are EVM specific attributes. e.g. #[evm_storage]
or #[evm(storage)]
.
Make a note in setup for SOLC_EXE for solidity tests
Is your feature request related to a problem? Please describe.
I was getting really confused why it was always telling me SOLC_EXE couldn't be found, then I realized you needed the solidity compiler for some compatibility tests. It's a little weird, and just would be great to call out / make these tests run separately when I just do cargo test
.
If I missed where this is mentioned in the docs lmk.
As highlighted in #127, abort_code
annotation in unit tests is not super expressive. We should support
For the location, suggested syntax:
#[test(abort_code = 0x42::M::2)]
// or
#[test(abort_code = 2, abort_location = 0x42::M)]
Note: annotation support is lacking for this right now
For status codes, suggested syntax:
#[test(status_code = "VECTOR_OPERATION_ERROR", sub_status = 1)]
Consider the following unpack statement:
let SomeStruct { some_field: value } = s;
In the statement above, the SomeStruct
identifier does not have its own identity (e.g., with respect to its location in the source file) but rather is an alias to the struct definition identifier. This will cause problems when trying to build use-def information for identifiers in the source code (e.g., for the purpose of displaying this information in an IDE).
A simple solution is to stick the location information into the Unpack
structure, but:
Name
) along with the alias to the struct definition)I made the previous change to make 0x more prevalent in the account address outputs, but it's clear to me that there are too many ways to display the account addresses and it adds a lot of confusion.
I'm going to clean it up so that there are less implementations and that it's straightforward at that point.
The function ExternalCall::test_for_move_to_yul
in hardhat-examples/contracts/ExternalCall/sources/
raises the following error. The error only occurs when the function is set to be callable
.
#[callable]
public fun test_for_move_to_yul(from: address, to: address, tokenId: U256, data: vector<u8>) {
// TODO: Uncomment the following line to see the error. The error occurs only when this function is set to be `callable`.
let _ = IERC721Receiver_try_call_onERC721Received(to, sender(), from, tokenId, data);
}
Error: Warning: Yul is still experimental. Please use the output with care.
Error: Variable name $field_ptr already taken in this scope.
--> <stdin>:162:25:
|
162 | let $field_ptr := $LoadU256(add($field_ptr, 0))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: Variable name $field_ptr already taken in this scope.
--> <stdin>:169:25:
|
169 | let $field_ptr := $LoadU256(add($field_ptr, 0))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: Variable name $field_ptr already taken in this scope.
--> <stdin>:176:25:
|
176 | let $field_ptr := $LoadU256(add($field_ptr, 0))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: Variable name $field_ptr already taken in this scope.
--> <stdin>:183:25:
|
183 | let $field_ptr := $LoadU256(add($field_ptr, 0))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
See ExternalCall.move
.
In the following code, it always falls into the ok
branch:
// TODO: the following code always aborts with "ok".
// if (ExternalResult::is_ok(&result)) {
// abort_with(b"ok");
// } else if (ExternalResult::is_err_reason(&result)) {
// abort_with(b"err_reason");
// } else if (ExternalResult::is_err_data(&result)) {
// abort_with(b"err_data");
// } else if (ExternalResult::is_panic(&result)) {
// abort_with(b"panic");
// } else {
// abort_with(b"other");
// }
However, it works fine if the "ok" branch is put at the end as follows:
// The following code works fine.
if (ExternalResult::is_err_reason(&result)) {
abort_with(b"err_reason");
} else if (ExternalResult::is_err_data(&result)) {
abort_with(b"err_data");
} else if (ExternalResult::is_panic(&result)) {
abort_with(b"panic");
} else if (ExternalResult::is_ok(&result)) {
abort_with(b"ok");
} else {
abort_with(b"other");
}
Test
the issue with "transaction ran out of gas" appears again.
this time, array arguments in external calls are suspicious.
See the following in ExternalCall.test.js
:
// TODO: Error with "Transaction ran out of gas"
// it('receiver reverting with error message', async function () {
// const ids = [1,2,3];
// const amounts = [10, 100, 1000];
// const data = '0x42';
// const receiver = await ERC1155Receiver.new(RECEIVER_SINGLE_MAGIC_VALUE, false, RECEIVER_BATCH_MAGIC_VALUE, true);
// await expectRevert(
// this.externalCall.doSafeBatchTransferAcceptanceCheck(this.externalCall.address, this.externalCall.address, receiver.address, ids, amounts, data),
// 'err_reason',
// );
// });
// TODO: Error with "Transaction ran out of gas"
// it('receiver reverting without error message', async function () {
// const ids = [1,2,3];
// const amounts = [10, 100, 1000];
// const data = '0x42';
// const receiver = await ERC721Receiver.new(RECEIVER_MAGIC_VALUE, Error.Panic);
// await expectRevert(
// this.externalCall.doSafeBatchTransferAcceptanceCheck(this.externalCall.address, this.externalCall.address, receiver.address, ids, amounts, data),
// 'err_data',
// );
// });
The nursery should be cleaned up and outdated designs be removed, so it can better serve as a way to share Move library evolution with the community.
Move compatibility in general. There were already some compatibility challenges due to differences in frameworks (e.g., libraries that depend on DiemAccount
aren't compatible with ones that depend on StarcoinAccount
), and Sui Move's data model that differs from core Move's global storage will throw another wrench in the works. Some incompatibility is to be expected given the nature of Move (a platform-independent language that gives platform designers a lot of flexibility to customize both the Move runtime and libraries for their platform). But of course, we should still strive for as much compatibility as possible and suggest best practices that will help with this.
Some early thoughts on this:
Math.move
module). They must (transitively) only depend on other tier 1 packages. These are fully generic and can be used by any platform.ASCII::String
in the stdlib). They must (transitively) only depend on other tier 1-2 packages. These can be used by any platform in principle, but there's nothing that stops two platforms from (e.g.) defining and reusing type-incompatible versions of UTF8::String
. We should try to avoid this by working as a Move community to build canonical libraries of these types.borrow_global
, Table
). These must (transitively) only depend on other tier 1-5 packages. These are only reusable across platforms with the same entrypoint structure and global storage.I'm not sure whether this tiering system should just be an informal guideline, or also something that we try to enforce programmatically in the package system and/or linters. It's worth noting that packages are not organized according to this tiering system today, although some are close (e.g., there's very little global storage used in the Move stdlib). But the overwhelming tendency is toward monolithic tier 6 packages, which I think we should change.
Once we have reorganized packages using these principles, I think there will be a lot more boxes in your diagram above, but the tiering system will make it easier to figure out where we can/should draw dependency arrows and where we shouldn't.
(copied from original discussion in diem/move#91)
to get tokenURI with base URI.
In Solidity, it's
bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
Basically, we want to mirror the following Solidity function in Move:
function uri(uint256 _tokenid) override public pure returns (string memory) {
return string(
abi.encodePacked(
"https://ipfs.io/ipfs/bafybeihjjkwdrxxjnuwevlqtqmh3iegcadc32sio4wmo7bv2gbf34qs34a/",
Strings.toString(_tokenid),".json"
)
);
}
or
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory baseURI = _baseURI();
return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
}
Is your feature request related to a problem? Please describe.
To provide unit test or e2e tests for move-resource-viewer since there is not sufficient test coverage for this component.
See ExternalCall.move
.
As the "TODO" says, it's expected to revert with the reason string which come from the callee. However, it reverts without any string.
// TODO: The following lines results in reverting without a reason string.
// However, it is expected to revert with "ERC721ReceiverMock: reverting".
let reason = ExternalResult::unwrap_err_reason(result);
abort_with(reason);
This note suggests a different, potentially more efficient, simpler and 100% safe implementation of the VMs value representation. The sketched design is influenced by the recent implementation of Move on the EVM.
There are three major components to this alternative model:
*mut
, but ensure the public value API is safe.Borrow semantics is a model for linear addressable memory, including pointer indirection and address arithmetic. The claim here is that even though this model is tailored for microprocessors, it is also the best for a virtual machine.
Given this approach, values are simply represented as regions of linear memory. The interpretation of the data in this memory is discussed later.
struct Value<'a>(*mut[u8], PhantomData<&'a ()>);
The lifetime 'a
here is bound to a heap of values, e.g.associated with a Move VM session. The implementation ensures safety for all usages of Value<'a>
, guaranteed by Rust lifetime checking. The heap can be a simple arena, as sessions are short living. (This is how the EVM does it.), but more investigation is needed here. Similar to the heap, there is a stack frame which is also linear addressable, as well as slots for global values.
Values are opaque. One needs a type to interpret a value., e.g.
let val: Value<'a>;
U8_TYPE.write(val, U8_TYPE.read(val)? + 1)?;
For native functions, types are either known statically, or are passed as parameters if those functions are generic.
We expect that conversion via types is safe. However, because of erasure of type information from values, only restricted forms of runtime checks can be performed (e.g. if the value's memory slice has the correct size). In case the wrong type is used on a value, this will be always safe for Rust, but may result in undetermined values for Move.
We otherwise expect that conversions should be very fast. Specifically, Rust already has builtin primitives to convert [u8,N]
into a u8/u64/u128; this can be expected to compile to single machine instructions.
A struct is represented by a slice of memory where the field data is packed into consecutive bytes. That is if the struct has two consecutive u8 and u128 fields, the first one will occupy the first byte and the 2nd one the remaining 16 bytes; the size of the struct value's memory slice thus is 17.
Borrowing a field from a struct is then simply sub-slicing the struct's slice (Value(r) => Value(r[offs..offs+size])
).
Vectors, because they are dynamically sized, need to be represented by a reference to some other place on the heap, that is as an embedded Value<'a>
. How can we ensure safety if we read such a value from a struct? The answer here is to simply range check whether the memory slice represented by the read value is defined for the currently allocated Rust memory of the heap. Β One simple solution for being able to do so is to never give memory allocated for values back to Rust for the `'a' lifetime. This is adequate because sessions are short living.
For nested structs, two options exist: they can be inlined, or they can be represented similar like vectors via an embedded value. Both approaches have advantages and disadvantages: the first is faster and more compact for access, but also makes moving the nested struct requiring a memcpy.
In the current VM implementation, values are represented by nested Rust enums:
enum ValueImpl {
Β Β U8(u8),
Β Β U64(u64),
Β Β ...
Β Β Container(Container),
}
enum Container {
Β Β Locals(Rc<RefCell<Vec<ValueImpl>>>),
Β Β Vec(Rc<RefCell<Vec<ValueImpl>>>),
Β Β ...
}
This representation leads to multiple indirections and memory allocations, and heavy case switching in the code. The suggested representation is expected to be significantly more compact and efficient regards access and mutation. It should moreover be able to minimize memory fragmentation, specifically if an arena style allocator is used, which can be very important for performance of modern processor architectures.
Right now if you run move package test
inside a package that depends on MoveStdlib and MoveStdlib only, for the first time it'll succeed:
BUILDING MoveStdlib
BUILDING Foo
Running Move unit tests
[ PASS ] 0x1::A::one_plus_one
[ PASS ] 0x1::A::should_panic
[ PASS ] 0x1::A::test_with_arg
Test result: OK. Total tests: 3; passed: 3; failed: 0
However if you run this command for the second time, it complains about not being able to find a source file:
CACHED MoveStdlib
BUILDING Foo
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: No such file or directory './build/MoveStdlib/sources/ASCIITests.move'', language/tools/move-cli/src/package/cli.rs:510:83
struct Foo {
a: u64,
}
#[test]
fun ice() {
use Std::Vector;
let v = Vector::empty();
Vector::push_back(&mut v, Foo {a: 10});
let b = Vector::borrow(&v, 0);
while (true) {
b = &Vector::pop_back(&mut v);
let Foo {a: _} = *b;
};
Vector::destroy_empty(v);
}
this piece of code caused "ICE invalid assign tmp local"
The Discord invite on the README is expired.
As script function can support more flexible parameters, we plan to enable passing signer reference instead of signer in script and script function to reduce redundant code. Ex: developer has to write script function taking signer and a internal version of script function to take &signer so that they can test with internal version of function without worrying about the signer value being "moved". This leads to lot of code duplication and force developer to understand unnecessary language details
However,
First, the ABIgen current still assumes all non-signer args are actually function arguments. while passing &signer, it is treated as true txn arguments passed by users leading to abigen failed.
second, the move viewer also has the same assumption that should be relaxed.
Describe the solution you'd like
relax the assumption in abigen so that both signer and non-mutable signer reference are not txn args.
Right now, various places in the package system and CLI (e.g. running builds, tests, or the prover) have no way to access any options which might have been defined in the Move.toml
, like language flavor, bytecode version, or other compiler or tool chain flags. This is because there is no design in place for sharing such global config info; rather there are a lot of static functions or struct methods on different data types. As an ugly workaround, we use environment variables like MOVE_BYTECODE_VERSION
.
We should device a configuration model which gives uniform access to command line flags, configuration files, and Move.toml
from everywhere. We may also want to leverage clap's capabilities to aggregate option structs to not have to redefine flags from independent tools for the package system.
Possibly because Move unit test when embedded in Rust tests don't lead to a test failure, we have a few vector test failures which sneaked into the main branch. From running move-stdlib tests:
[ FAIL ] 0x1::VectorTests::borrow_out_of_range
[ FAIL ] 0x1::VectorTests::destroy_non_empty
[ FAIL ] 0x1::VectorTests::pop_out_of_range
[ FAIL ] 0x1::VectorTests::swap_empty
[ FAIL ] 0x1::VectorTests::swap_out_of_range
Those failures do not need lead to Rust test failure, and therefore passed by CI.
The failures have this funny shape:
βββ borrow_out_of_range ββββββ
β error[E11001]: test failure
β ββ /home/wrwg/gh/move/language/move-stdlib/./tests/VectorTests.move:97:9
β β
β 94 β fun borrow_out_of_range() {
β β ------------------- In this function in 0x1::VectorTests
β Β·
β 97 β V::borrow(&v, 1);
β β ^^^^^^^^^^^^^^^^ Test did not abort with expected code. Expected test to abort with 1 but instead it aborted with 1 here
β
β
βββββββββββββββββββ
So 1 was expected as an abort code but 1 was found...
Perhaps the failures are related to the new vector operations introduced in #37.
I'm rolling up PR #125 to fix the issue that Move unit tests don't produce a test failure, but will have to disable some tests temporarily.
Found RUSTSEC in dependencies in job https://github.com/move-language/move/actions/runs/3198096435
Fetching advisory database from `https://github.com/RustSec/advisory-db.git`
Loaded 459 security advisories (from /opt/cargo/advisory-db)
Updating crates.io index
Scanning Cargo.lock for vulnerabilities (625 crate dependencies)
Crate: chrono
Version: 0.4.19
Title: Potential segfault in `localtime_r` invocations
Date: 2020-11-10
ID: RUSTSEC-2020-0159
URL: https://rustsec.org/advisories/RUSTSEC-2020-0159
Solution: Upgrade to >=0.4.20
Dependency tree:
chrono 0.4.19
βββ x 0.1.0
βββ tera 1.16.0
β βββ move-prover-boogie-backend 0.1.0
β βββ move-to-yul 0.1.0
β β βββ move-unit-test 0.1.0
β β β βββ move-table-extension 0.1.0
β β β β βββ move-vm-test-utils 0.1.0
β β β β β βββ test-generation 0.1.0
β β β β β βββ move-vm-integration-tests 0.1.0
β β β β β βββ move-unit-test 0.1.0
β β β β β βββ move-transactional-test-runner 0.1.0
β β β β β β βββ move-vm-transactional-tests 0.1.0
β β β β β β βββ move-ir-compiler-transactional-tests 0.1.0
β β β β β β βββ move-compiler-transactional-tests 0.1.0
β β β β β β βββ bytecode-verifier-transactional-tests 0.1.0
β β β β β βββ move-cli 0.1.0
β β β β β β βββ move-transactional-test-runner 0.1.0
β β β β β β βββ move-table-extension 0.1.0
β β β β β β βββ move-stdlib 0.1.1
β β β β β β β βββ test-generation 0.1.0
β β β β β β β βββ move-vm-integration-tests 0.1.0
β β β β β β β βββ move-unit-test 0.1.0
β β β β β β β βββ move-transactional-test-runner 0.1.0
β β β β β β β βββ move-to-yul 0.1.0
β β β β β β β βββ move-table-extension 0.1.0
β β β β β β β βββ move-stackless-bytecode 0.1.0
β β β β β β β β βββ spec-flatten 0.1.0
β β β β β β β β βββ read-write-set 0.1.0
β β β β β β β β β βββ move-cli 0.1.0
β β β β β β β β βββ prover-mutation 0.1.0
β β β β β β β β βββ prover-lab 0.1.0
β β β β β β β β βββ move-to-yul 0.1.0
β β β β β β β β βββ move-stackless-bytecode-interpreter 0.1.0
β β β β β β β β β βββ move-unit-test 0.1.0
β β β β β β β β β βββ move-transactional-test-runner 0.1.0
β β β β β β β β β βββ bytecode-interpreter-testsuite 0.1.0
β β β β β β β β βββ move-prover-boogie-backend 0.1.0
β β β β β β β β βββ move-prover 0.1.0
β β β β β β β β βββ spec-flatten 0.1.0
β β β β β β β β βββ prover-mutation 0.1.0
β β β β β β β β βββ prover-lab 0.1.0
β β β β β β β β βββ move-stdlib 0.1.1
β β β β β β β β βββ move-errmapgen 0.1.0
β β β β β β β β β βββ move-stdlib 0.1.1
β β β β β β β β β βββ move-prover 0.1.0
β β β β β β β β β βββ move-cli 0.1.0
β β β β β β β β βββ move-docgen 0.1.0
β β β β β β β β β βββ move-stdlib 0.1.1
β β β β β β β β β βββ move-prover 0.1.0
β β β β β β β β β βββ move-package 0.1.0
β β β β β β β β β β βββ move-table-extension 0.1.0
β β β β β β β β β β βββ move-stdlib 0.1.1
β β β β β β β β β β βββ move-cli 0.1.0
β β β β β β β β β β βββ move-analyzer 1.0.0
β β β β β β β β β βββ move-cli 0.1.0
β β β β β β β β βββ move-cli 0.1.0
β β β β β β β β βββ move-abigen 0.1.0
β β β β β β β β βββ move-prover 0.1.0
β β β β β β β β βββ move-package 0.1.0
β β β β β β β βββ move-compiler 0.0.1
β β β β β β β β βββ test-generation 0.1.0
β β β β β β β β βββ spec-flatten 0.1.0
β β β β β β β β βββ prover-mutation 0.1.0
β β β β β β β β βββ prover-lab 0.1.0
β β β β β β β β βββ move-vm-runtime 0.1.0
β β β β β β β β β βββ test-generation 0.1.0
β β β β β β β β β βββ move-vm-integration-tests 0.1.0
β β β β β β β β β βββ move-unit-test 0.1.0
β β β β β β β β β βββ move-transactional-test-runner 0.1.0
β β β β β β β β β βββ move-table-extension 0.1.0
β β β β β β β β β βββ move-stdlib 0.1.1
β β β β β β β β β βββ move-cli 0.1.0
β β β β β β β β β βββ move-async-vm 0.1.0
β β β β β β β β β βββ language-benchmarks 0.1.0
β β β β β β β β β βββ diem-framework-natives 0.0.0
β β β β β β β β β βββ df-cli 0.1.0
β β β β β β β β βββ move-vm-integration-tests 0.1.0
β β β β β β β β βββ move-unit-test 0.1.0
β β β β β β β β βββ move-transactional-test-runner 0.1.0
β β β β β β β β βββ move-to-yul 0.1.0
β β β β β β β β βββ move-stdlib 0.1.1
β β β β β β β β βββ move-stackless-bytecode 0.1.0
β β β β β β β β βββ move-prover 0.1.0
β β β β β β β β βββ move-package 0.1.0
β β β β β β β β βββ move-model 0.1.0
β β β β β β β β β βββ spec-flatten 0.1.0
β β β β β β β β β βββ read-write-set 0.1.0
Before publish a module, vm checks if itβs abi compatible with existing one. (https://github.com/diem/move/blob/180a066094704b2411d3970758b2a05d2e406213/language/move-vm/runtime/src/runtime.rs#L115)
vm has a loader that caches the deserialized module if itβs loaded before otherwise it loads from the data cache. (https://github.com/diem/move/blob/180a066094704b2411d3970758b2a05d2e406213/language/move-vm/runtime/src/loader.rs#L841)
a successful module publish goes to data cache directly but does not invalidate the loaderβs cache. (https://github.com/diem/move/blob/180a066094704b2411d3970758b2a05d2e406213/language/move-vm/runtime/src/runtime.rs#L193)
to reproduce the bug, imagine thereβre 3 txn tries to publish the same module with different version V1, V2, V3. V1 is compatible with V2 and V3, but V2 is not compatible with V3.
if theyβre executed in a single block, [V1, V2, V3], the following happens
Multiple different errors all mapped to MiscellaneousError ex:
The impact is user lacks a clear idea of what went wrong when their txn failed. Ex:
when users published modules, both the linker_error and MODULE_ADDRESS_DOES_NOT_MATCH_SENDER are mapped to this MiscellaneousError, which doesn't help user to understand what went wrong.
Describe the solution you'd like
Keep the finer granular status code when returning the MiscellaneousError to provide more detailed error message to the users
move --ethereum package build
and move package test --evm
move-cli
rebuild_after_touching_manifest
may fail (due to a preexisting build directory?)--arch ethereum/move/async-move
evm-backend
move package test
panics when cache is hot
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.