Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ink! ABI #104

Merged
merged 117 commits into from Aug 14, 2019
Merged

ink! ABI #104

merged 117 commits into from Aug 14, 2019

Conversation

Robbepop
Copy link
Collaborator

@Robbepop Robbepop commented May 29, 2019

Prototype implementation of ink! meta data.
This will eventually replace the current system of API description generation.

ink_abi will be the library behind the two-phase ABI file generation and provides the data structures and serialization routines that are going to be constructed by ink_lang during compilation of a smart contract.

It can handle type aliases, differentiate types with the same name.

Future plans are to also integrate storage layout description as well as custom type layout description into it.

TODO

  • Implement type-metadata crate for handling runtime type information.
  • Implement ink_abi sub-crate providing traits and mechanics for ABI generation.
  • Integrate ink_abi trait implementations into ink_core.
  • Adjust ink_cli template for ink! smart contract generation.
  • Implement ABI generation into ink_lang
  • Implement 2-phase ABI generation procedure in cargo-contract (not needed with chosen design)
  • Remove deprecated ABI generation (via generate-api-description crate feature)
  • Implement derive macros for HasLayout
  • Adjust the rest of the examples to new ink_abi project structure
  • Fix remaining failing ink_lang tests
  • Write docs about how to generate ABI files using ink_abi
  • Open questions:
    • Shall we rename .tool directory to .ink ? (same as .git)
  • Minor issues:
    • Trim generated doc strings so that they no longer include = \" and \" as start and end respectively.
    • Mirror storage layout of ExecEnv<State> instead of directly taking State
    • Fix bug that test-env crate feature has to be enabled for ink-generate-abi

Code currently generated for Flipper example contract:

#[cfg(feature = "generate-abi")]
fn ink_generate_abi() -> ink_abi::InkProject {
    let contract = {
        ink_abi::ContractSpec::new("Flipper")
			.on_deploy(
				ink_abi::DeploySpec::new()
					.args(<[_]>::into_vec(box []))
					.docs(<[_]>::into_vec(box [
						"= \" Initializes our state to `false` upon deploying our smart contract.\""
					]))
					.done()
				)
			.messages(<[_]>::into_vec(box [
				ink_abi::MessageSpec::new("flip")
					.selector(970692492u32)
					.mutates(true)
					.args(<[_]>::into_vec(box []))
					.docs(<[_]>::into_vec(box [
						"= \" Flips the current state of our smart contract.\""
					]))
					.returns(ink_abi::ReturnTypeSpec::none())
					.done(),
                ink_abi::MessageSpec::new("get")
					.selector(4266279973u32)
					.mutates(false)
					.args(<[_]>::into_vec(box []))
					.docs(<[_]>::into_vec(box [
						"= \" Returns the current state.\""
					]))
					.returns(ink_abi::ReturnTypeSpec::new::<bool>())
					.done()
				])
			)
			.events(<[_]>::into_vec(box []))
			.docs(<[_]>::into_vec(box []))
			.done()
    };
    let layout = {
        impl ink_abi::HasLayout for Flipper {
            fn layout(&self) -> ink_abi::StorageLayout {
                {
                    ::std::rt::begin_panic(
                        "not yet implemented",
                        &("src/lib.rs", 26u32, 1u32),
                    )
                }
            }
        }
        unsafe {
            use ink_abi::HasLayout as _;
            use ink_core::storage::alloc::AllocateUsing as _;
            Flipper::allocate_using(
                &mut ink_core::storage::alloc::BumpAlloc::from_raw_parts(
                    ink_core::storage::Key([0x0; 32]),
                ),
            )
            .layout()
        }
    };
    ink_abi::InkProject::new(layout, contract)
}

Metadata created for the Flipper example contract:

{
  "registry": {
    "strings": [
      "Flipper",
      "flipper",
      "value",
      "Value",
      "ink_core",
      "storage",
      "cell",
      "SyncCell",
      "sync_cell",
      "Key",
      "key",
      "flip",
      "get"
    ],
    "types": [
      {
        "id": "bool",
        "def": "builtin"
      },
      {
        "id": "u8",
        "def": "builtin"
      },
      {
        "id": {
          "array.len": 32,
          "array.type": 7
        },
        "def": "builtin"
      },
      {
        "id": {
          "custom.name": 10,
          "custom.namespace": [
            5,
            6,
            11
          ],
          "custom.params": []
        },
        "def": {
          "tuple_struct.types": [
            6
          ]
        }
      },
      {
        "id": {
          "custom.name": 8,
          "custom.namespace": [
            5,
            6,
            7,
            9
          ],
          "custom.params": [
            3
          ]
        },
        "def": {
          "struct.fields": [
            {
              "name": 7,
              "type": 5
            }
          ]
        }
      },
      {
        "id": {
          "custom.name": 4,
          "custom.namespace": [
            5,
            6,
            3
          ],
          "custom.params": [
            3
          ]
        },
        "def": {
          "struct.fields": [
            {
              "name": 7,
              "type": 4
            }
          ]
        }
      },
      {
        "id": {
          "custom.name": 1,
          "custom.namespace": [
            2
          ],
          "custom.params": []
        },
        "def": {
          "struct.fields": [
            {
              "name": 3,
              "type": 2
            }
          ]
        }
      }
    ]
  },
  "storage": {
    "struct.type": 1,
    "struct.fields": [
      {
        "name": 3,
        "layout": {
          "struct.type": 2,
          "struct.fields": [
            {
              "name": 7,
              "layout": {
                "range.offset": [
                  0,
                  0,
                  0,
                  0,
                  0,
                  0,
                  0,
                  0,
                  0,
                  0,
                  0,
                  0,
                  0,
                  0,
                  0,
                  0,
                  0,
                  0,
                  0,
                  0,
                  0,
                  0,
                  0,
                  0,
                  0,
                  0,
                  0,
                  0,
                  0,
                  0,
                  0,
                  0
                ],
                "range.len": 1,
                "range.elem_type": 3
              }
            }
          ]
        }
      }
    ]
  },
  "contract": {
    "name": 1,
    "deploy": {
      "args": [],
      "docs": [
        "Initializes our state to `false` upon deploying our smart contract."
      ]
    },
    "messages": [
      {
        "name": 12,
        "selector": 970692492,
        "mutates": true,
        "args": [],
        "return_type": null,
        "docs": [
          "Flips the current state of our smart contract."
        ]
      },
      {
        "name": 13,
        "selector": 4266279973,
        "mutates": false,
        "args": [],
        "return_type": 3,
        "docs": [
          "Returns the current state."
        ]
      }
    ],
    "events": [],
    "docs": []
  }
}

@Robbepop Robbepop changed the title Ink abi ink! ABI prototype May 29, 2019
@Robbepop Robbepop added A-ink_metadata [ink_metadata] Work item B-enhancement New feature or request E-in-progress A task that is already being worked on. labels May 29, 2019
@codecov-io
Copy link

codecov-io commented May 31, 2019

Codecov Report

Merging #104 into master will decrease coverage by 6.15%.
The diff coverage is 23.39%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #104      +/-   ##
==========================================
- Coverage   85.83%   79.67%   -6.16%     
==========================================
  Files          61       67       +6     
  Lines        4899     4975      +76     
==========================================
- Hits         4205     3964     -241     
- Misses        694     1011     +317
Impacted Files Coverage Δ
core/src/storage/collections/vec/impls.rs 98.07% <ø> (ø) ⬆️
lang/src/tests/events.rs 100% <ø> (ø) ⬆️
core/src/storage/collections/hash_map/impls.rs 80.83% <ø> (ø) ⬆️
lang/src/tests/incrementer.rs 100% <ø> (ø) ⬆️
lang/src/contract.rs 54.54% <ø> (-12.13%) ⬇️
lang/src/tests/noop.rs 100% <ø> (ø) ⬆️
lang/src/tests/flipper.rs 100% <ø> (ø) ⬆️
lang/src/gen/build.rs 82% <ø> (ø) ⬆️
lang/src/lib.rs 25% <ø> (ø) ⬆️
abi/derive/src/impl_wrapper.rs 0% <0%> (ø)
... and 32 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 9525f2f...1ac2ebe. Read the comment docs.

Copy link
Collaborator

@ascjones ascjones left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WIP review: done the abi crate so far.

.travis.yml Outdated Show resolved Hide resolved
abi/Cargo.toml Outdated Show resolved Hide resolved
abi/src/specs.rs Show resolved Hide resolved
abi/src/specs.rs Outdated Show resolved Hide resolved
abi/src/specs.rs Show resolved Hide resolved
abi/src/specs.rs Outdated Show resolved Hide resolved
abi/src/specs.rs Outdated Show resolved Hide resolved
abi/src/specs.rs Show resolved Hide resolved
abi/src/specs.rs Show resolved Hide resolved
abi/derive/src/lib.rs Show resolved Hide resolved
Copy link
Collaborator

@ascjones ascjones left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First pass done. Looks good overall, just a few minor things. And the examples failing to build.

core/src/storage/collections/stash/impls.rs Outdated Show resolved Hide resolved
core/src/storage/collections/stash/impls.rs Outdated Show resolved Hide resolved
examples/lang/incrementer/.ink/abi_gen/main.rs Outdated Show resolved Hide resolved
examples/lang/incrementer/Cargo.toml Outdated Show resolved Hide resolved
lang/src/gen/abi.rs Outdated Show resolved Hide resolved
lang/src/hir.rs Show resolved Hide resolved
unreachable!("invalid arg name encountered")
}
}
_ => unreachable!("encountered invalid argument syntax: the only allowed is `ident : type`"),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Identical code block to above in generate_abi_deploy_handler

Copy link
Collaborator

@ascjones ascjones left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, but examples still not building (on my machine) with:

error[E0412]: cannot find type `Vec` in this scope
   --> /home/andrew/code/paritytech/ink/abi/src/specs.rs:457:28
    |
457 |                 .collect::<Vec<_>>(),
    |                            ^^^ not found in this scope
help: possible candidates are found in other modules, you can import them into scope
    |
17  | use alloc::prelude::v1::Vec;
    |
17  | use alloc::vec::Vec;
    |
17  | use serde::export::Vec;
    |

.travis.yml Outdated Show resolved Hide resolved
ascjones
ascjones previously approved these changes Aug 13, 2019
Copy link
Collaborator

@ascjones ascjones left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! 🌮

@Robbepop
Copy link
Collaborator Author

LGTM! 🌮

🍰

Copy link
Collaborator

@ascjones ascjones left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🥇

@Robbepop Robbepop merged commit fa6b006 into master Aug 14, 2019
@HCastano HCastano deleted the ink-abi branch July 29, 2022 17:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ink_metadata [ink_metadata] Work item B-enhancement New feature or request E-in-progress A task that is already being worked on.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants