Skip to content

Commit

Permalink
Merge branch 'master' into holykol/sails-builder
Browse files Browse the repository at this point in the history
  • Loading branch information
holykol committed May 3, 2024
2 parents a54ceb4 + 6cfea1b commit b957bae
Show file tree
Hide file tree
Showing 32 changed files with 529 additions and 273 deletions.
272 changes: 156 additions & 116 deletions Cargo.lock

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ members = [
anyhow = "1"
convert-case = { package = "convert_case", version = "0.6" }
futures = { version = "0.3", default-features = false }
gear-core-errors = "1.1.1"
gear-core-errors = "1.3.0"
git-download = "0.1"
gstd = "1.1.1"
gtest = "1.1.1"
gwasm-builder = { package = "gear-wasm-builder", version = "1.1.1" }
gstd = "1.3.0"
gtest = "1.3.0"
gwasm-builder = { package = "gear-wasm-builder", version = "1.3.0" }
handlebars = "4.4"
hashbrown = "0.14"
hex = { version = "0.4", default-features = false }
Expand Down
1 change: 1 addition & 0 deletions client-gen/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ impl CtorTraitGenerator {

impl<'ast> Visitor<'ast> for CtorTraitGenerator {
fn visit_ctor(&mut self, ctor: &'ast Ctor) {
self.code.push_str("#[allow(dead_code)]\n");
self.code.push_str(&format!(
"pub trait {}Factory<A: Default> {{\n",
self.service_name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ pub struct SlotPart {
}
pub mod traits {
use super::*;
#[allow(dead_code)]
pub trait RmrkCatalogFactory<A: Default> {
#[allow(clippy::new_ret_no_self)]
fn new(remoting: impl Remoting<A>) -> impl Activation<A>;
Expand Down
1 change: 1 addition & 0 deletions client-gen/src/snapshots/sails_clientgen__tests__full.snap
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ pub enum T {
}
pub mod traits {
use super::*;
#[allow(dead_code)]
pub trait ServiceFactory<A: Default> {
#[allow(clippy::new_ret_no_self)]
fn new(remoting: impl Remoting<A>, a: u32) -> impl Activation<A>;
Expand Down
69 changes: 54 additions & 15 deletions examples/rmrk/resource/wasm/tests/resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ fn adding_resource_to_storage_by_admin_succeeds() {
assert!(run_result.contains(&(ADMIN_ID, expected_response)));

let expected_event = [
resources::RESOURCE_SERVICE_NAME.encode().as_slice(),
"ResourceAdded".encode().as_slice(),
&ResourceStorageEvent::ResourceAdded {
resource_id: RESOURCE_ID,
Expand Down Expand Up @@ -196,53 +197,91 @@ fn adding_non_existing_part_to_resource_fails() {

struct Fixture<'a> {
admin_id: u64,
net_client: GTestRemoting,
program_space: GTestRemoting,
catalog_program: OnceCell<Program<'a>>,
resource_program: OnceCell<Program<'a>>,
}

impl<'a> Fixture<'a> {
fn new(admin_id: u64) -> Self {
let net_client = GTestRemoting::new();
net_client.system().init_logger();
let program_space = GTestRemoting::new();
program_space.system().init_logger();

Self {
admin_id,
net_client,
program_space,
catalog_program: OnceCell::new(),
resource_program: OnceCell::new(),
}
}

fn net_client(&self) -> &GTestRemoting {
&self.net_client
fn program_space(&self) -> &GTestRemoting {
&self.program_space
}

fn catalog_program(&'a self) -> &Program<'a> {
self.catalog_program.get_or_init(|| {
let program = Program::from_file(self.net_client.system(), CATALOG_PROGRAM_WASM_PATH);
let program =
Program::from_file(self.program_space.system(), CATALOG_PROGRAM_WASM_PATH);
let encoded_request = catalog::CTOR_FUNC_NAME.encode();
program.send_bytes(self.admin_id, encoded_request);
program
})
}

fn resource_program(&'a self) -> &Program<'a> {
fn resource_program_for_async(&'a self) -> &Program<'a> {
println!("For async");
self.resource_program.get_or_init(|| {
let program = Program::from_file(self.net_client.system(), RESOURCE_PROGRAM_WASM_PATH);
let program =
Program::from_file(self.program_space.system(), RESOURCE_PROGRAM_WASM_PATH);
let encoded_request = resources::CTOR_FUNC_NAME.encode();
program.send_bytes(self.admin_id, encoded_request);
program
})
}

fn resource_program_for_sync(&'a self) -> &Program<'a> {
println!("For sync");
self.resource_program.get_or_init(|| {
tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap()
.block_on(async {
self.__spin_up_program(
RESOURCE_PROGRAM_WASM_PATH,
&resources::CTOR_FUNC_NAME.encode(),
)
.await
})
})
}

async fn __spin_up_program(&'a self, program_path: &str, payload: &[u8]) -> Program<'a> {
let code_id = self.program_space().system().submit_code(program_path);
let program_space = self.program_space().clone();
let reply = program_space
.activate(
code_id.as_ref().into(),
"123",
payload,
0,
GTestArgs::new(self.admin_id.into()),
)
.await
.unwrap();
self.program_space()
.system()
.get_program(*reply.await.unwrap().0.as_ref())
}

fn add_resource(
&'a self,
actor_id: u64,
resource_id: ResourceId,
resource: &Resource,
) -> RunResult {
let program = self.resource_program();
let program = self.resource_program_for_sync();
let encoded_request = [
resources::RESOURCE_SERVICE_NAME.encode(),
resources::ADD_RESOURCE_ENTRY_FUNC_NAME.encode(),
Expand All @@ -266,10 +305,10 @@ impl<'a> Fixture<'a> {
resource.encode(),
]
.concat();
let net_client = self.net_client().clone();
let reply = net_client
let program_space = self.program_space().clone();
let reply = program_space
.message(
self.resource_program().id().as_ref().into(),
self.resource_program_for_async().id().as_ref().into(),
encoded_request,
0,
GTestArgs::new(actor_id.into()),
Expand All @@ -284,7 +323,7 @@ impl<'a> Fixture<'a> {
resource_id: ResourceId,
part_id: PartId,
) -> RunResult {
let program = self.resource_program();
let program = self.resource_program_for_sync();
let encoded_request = [
resources::RESOURCE_SERVICE_NAME.encode(),
resources::ADD_PART_TO_RESOURCE_FUNC_NAME.encode(),
Expand All @@ -300,7 +339,7 @@ impl<'a> Fixture<'a> {
actor_id: u64,
resource_id: ResourceId,
) -> Option<ResourceStorageResult<Resource>> {
let program = self.resource_program();
let program = self.resource_program_for_sync();
let encoded_service_name = resources::RESOURCE_SERVICE_NAME.encode();
let encoded_func_name = resources::RESOURCE_FUNC_NAME.encode();
let encoded_request = [
Expand Down
1 change: 1 addition & 0 deletions examples/this-that-svc/app/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use gstd::{debug, prelude::*};
use primitive_types::{H256, U256};
use sails_macros::gservice;

#[derive(Default)]
pub struct MyService;

#[gservice]
Expand Down
12 changes: 6 additions & 6 deletions js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,20 +83,20 @@ The key of the object is the name of the event and the value is an object with t
```

### Get function name and decode bytes
Use `sails.getServiceName` method to get the service name from the payload bytes.
Use `sails.getFnName` method to get the function name from the payload bytes.
Use `getServiceNamePrefix` function to get the service name from the payload bytes.
Use `getFnNamePrefix` method to get the function or event name from the payload bytes.
Use `sails.services.ServiceName.functions.FuncitonName.decodePayload` method of the function object to decode the payload bytes of the send message.
Use `sails.services.ServiceName.functions.FuncitonName.decodeResult` method of the function object to decode the result bytes of the received message.

```javascript
import { getServiceNamePrefix, getFnNamePrefix } from 'sails-js';
const payloadOfSentMessage = '0x<some bytes>';
const serviceName = sails.getServiceName(payloadOfSentMessage);
const functionName = sails.getFnName(payloadOfSentMessage);
const serviceName = getServiceNamePrefix(payloadOfSentMessage);
const functionName = getFnNamePrefix(payloadOfSentMessage);
console.log(sails.services[serviceName].functions[functionName].decodeResult(payloadOfSentMessage));

const payloadOfReceivedMessage = '0x<some bytes>';
const functionName = sails.getFunctionName(payloadOfReceivedMessage);
console.log(sails.functions[functionName].decodePayload(payloadOfReceivedMessage));
console.log(sails.service[serviceName].functions[functionName].decodePayload(payloadOfReceivedMessage));
```

The same approach can be used to encode/decode bytes of the contructor or event.
Expand Down
6 changes: 3 additions & 3 deletions js/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sails-js",
"version": "0.1.0",
"version": "0.1.1",
"description": "Parser and typescript code generator from Sails IDL files",
"main": "lib/index.js",
"preferGlobal": true,
Expand Down Expand Up @@ -33,8 +33,8 @@
},
"scripts": {
"prebuild": "rm -rf lib",
"build": "rm -rf lib && rollup --config rollup.config.js && node compress-parser.js",
"pretest": "yarn build && node test/modify-import.js",
"build": "rm -rf lib && rollup --config rollup.config.js && node compress-parser.js",
"test": "yarn node --no-warnings --experimental-vm-modules $(yarn bin jest) --detectOpenHandles"
},
"peerDependencies": {
Expand All @@ -43,7 +43,7 @@
"@polkadot/types": "^10.12.3"
},
"devDependencies": {
"@gear-js/api": "0.37.2",
"@gear-js/api": "0.38.0",
"@polkadot/api": "10.12.6",
"@polkadot/types": "10.12.6",
"@rollup/plugin-commonjs": "25.0.7",
Expand Down
30 changes: 15 additions & 15 deletions js/src/generate/service-gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ const getFuncName = (name: string) => {

const createPayload = (serviceName: string, fnName: string, params: FuncParam[]) => {
if (params.length === 0) {
return `const payload = this._program.registry.createType('(String, String)', '[${serviceName}, ${fnName}]').toU8a()`;
return `const payload = this._program.registry.createType('(String, String)', '[${serviceName}, ${fnName}]').toHex()`;
} else {
return `const payload = this._program.registry.createType('(String, String, ${params
.map(({ def }) => getScaleCodecDef(def))
.join(', ')})', ['${serviceName}', '${fnName}', ${params.map(({ name }) => name).join(', ')}]).toU8a()`;
.join(', ')})', ['${serviceName}', '${fnName}', ${params.map(({ name }) => name).join(', ')}]).toHex()`;
}
};

Expand Down Expand Up @@ -220,7 +220,8 @@ export class ServiceGenerator {
this._out
.firstLine(`const ZERO_ADDRESS = u8aToHex(new Uint8Array(32))`)
.import('@polkadot/util', 'u8aToHex')
.import('@polkadot/util', 'compactFromU8aLim');
.import('sails-js', 'getServiceNamePrefix')
.import('sails-js', 'getFnNamePrefix');
}

for (const event of service.events) {
Expand All @@ -243,19 +244,18 @@ export class ServiceGenerator {
},
)
.line()
.line(`const payload = message.payload.toU8a()`)
.line(`const [offset, limit] = compactFromU8aLim(payload)`)
.line(
`const name = this._program.registry.createType('String', payload.subarray(offset, limit)).toString()`,
.line(`const payload = message.payload.toHex()`)
.block(
`if (getServiceNamePrefix(payload) === '${service.name}' && getFnNamePrefix(payload) === '${event.name}')`,
() => {
this._out.line(
`callback(this._program.registry.createType('(String, String, ${getScaleCodecDef(
event.def,
true,
)})', message.payload)[2].toJSON() as ${jsType})`,
);
},
)
.block(`if (name === '${event.name}')`, () => {
this._out.line(
`callback(this._program.registry.createType('(String, ${getScaleCodecDef(
event.def,
true,
)})', message.payload)[1].toJSON() as ${jsType})`,
);
})
.reduceIndent()
.line(`})`);
},
Expand Down
1 change: 1 addition & 0 deletions js/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { Sails } from './sails.js';
export { TransactionBuilder } from './transaction-builder.js';
export { getServiceNamePrefix, getFnNamePrefix } from './utils/index.js';
10 changes: 10 additions & 0 deletions js/src/parser/visitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,8 @@ export enum EPrimitiveType {
ActorId,
CodeId,
MessageId,
H256,
U256,
}

export class PrimitiveDef {
Expand Down Expand Up @@ -329,6 +331,14 @@ export class PrimitiveDef {
get isMessageId(): boolean {
return this.value === EPrimitiveType.MessageId;
}

get isH256(): boolean {
return this.value === EPrimitiveType.H256;
}

get isU256(): boolean {
return this.value === EPrimitiveType.U256;
}
}

export class OptionalDef extends WithDef {}
Expand Down
Loading

0 comments on commit b957bae

Please sign in to comment.