Skip to content

Commit

Permalink
Merge pull request #207 from ElrondNetwork/hotfix-PR-198
Browse files Browse the repository at this point in the history
Redo PR #198 for erdjs 9x.
  • Loading branch information
andreibancioiu authored May 3, 2022
2 parents 22bbcc4 + 30d1a41 commit 455a29b
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 64 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/erdjs-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ jobs:
echo "" >> notes.txt
RELEASE_TAG=v$(node -p "require('./package.json').version")
gh release create $RELEASE_TAG --target=$GITHUB_SHA --title="$RELEASE_TAG" --generate-notes --notes-file=notes.txt
gh release create --prerelease $RELEASE_TAG --target=$GITHUB_SHA --title="$RELEASE_TAG" --generate-notes --notes-file=notes.txt
- run: npm ci
- run: npm test

- name: Publish to npmjs
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
run: npm publish --access=public
run: npm publish --access=public --tag=older
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@elrondnetwork/erdjs",
"version": "9.2.5",
"version": "9.2.6",
"description": "Smart Contracts interaction framework",
"main": "out/index.js",
"types": "out/index.d.js",
Expand Down
15 changes: 15 additions & 0 deletions src/smartcontracts/typesystem/abiRegistry.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,19 @@ describe("test abi registry", () => {
);
assert.equal(result.valueOf().name, "SendTransferExecute");
});

it("should load ABI containing arrayN and nested structs", async () => {
let registry = await loadAbiRegistry(["src/testdata/array-in-nested-structs.abi.json"]);
let dummyType = registry.getStruct("Dummy");
let fooType = registry.getStruct("Foo");
let barType = registry.getStruct("Bar");
let fooTypeFromBarType = <StructType>barType.getFieldDefinition("foo")!.type;
let dummyTypeFromFooTypeFromBarType = <StructType>fooTypeFromBarType.getFieldDefinition("dummy")!.type;

assert.equal(dummyType.getClassName(), StructType.ClassName);
assert.equal(fooType.getClassName(), StructType.ClassName);
assert.equal(barType.getClassName(), StructType.ClassName);
assert.isTrue(fooType == fooTypeFromBarType);
assert.isTrue(dummyType == dummyTypeFromFooTypeFromBarType);
});
});
3 changes: 1 addition & 2 deletions src/smartcontracts/typesystem/abiRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,13 @@ export class AbiRegistry {
* The result is an equivalent, more explicit ABI registry.
*/
remapToKnownTypes(): AbiRegistry {
let mapper = new TypeMapper(this.customTypes);
let mapper = new TypeMapper([]);
let newCustomTypes: CustomType[] = [];
let newInterfaces: ContractInterface[] = [];
// First, remap custom types (actually, under the hood, this will remap types of struct fields)
for (const type of this.customTypes) {
const mappedTyped = mapper.mapType(type);
newCustomTypes.push(mappedTyped);
mapper.feedCustomType(mappedTyped);
}
// Then, remap types of all endpoint parameters.
// But we'll use an enhanced mapper, that takes into account the results from the previous step.
Expand Down
6 changes: 5 additions & 1 deletion src/smartcontracts/typesystem/enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,13 @@ export class EnumVariantDefinition {
return new EnumVariantDefinition(json.name, json.discriminant, definitions);
}

getFieldsDefinitions() {
getFieldsDefinitions(): FieldDefinition[] {
return this.fieldsDefinitions;
}

getFieldDefinition(name: string): FieldDefinition | undefined {
return this.fieldsDefinitions.find(item => item.name == name);
}
}

export class EnumValue extends TypedValue {
Expand Down
6 changes: 5 additions & 1 deletion src/smartcontracts/typesystem/struct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,13 @@ export class StructType extends CustomType {
return new StructType(json.name, definitions);
}

getFieldsDefinitions() {
getFieldsDefinitions(): FieldDefinition[] {
return this.fieldsDefinitions;
}

getFieldDefinition(name: string): FieldDefinition | undefined {
return this.fieldsDefinitions.find(item => item.name == name);
}
}

// TODO: implement setField(), convenience method.
Expand Down
58 changes: 36 additions & 22 deletions src/smartcontracts/typesystem/typeMapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ type TypeFactory = (...typeParameters: Type[]) => Type;
export class TypeMapper {
private readonly openTypesFactories: Map<string, TypeFactory>;
private readonly closedTypesMap: Map<string, Type>;
private readonly learnedTypesMap: Map<string, Type>;

constructor(customTypes: CustomType[] = []) {
constructor(learnedTypes: CustomType[] = []) {
this.openTypesFactories = new Map<string, TypeFactory>([
["Option", (...typeParameters: Type[]) => new OptionType(typeParameters[0])],
["List", (...typeParameters: Type[]) => new ListType(typeParameters[0])],
Expand All @@ -61,7 +62,7 @@ export class TypeMapper {
["tuple7", (...typeParameters: Type[]) => new TupleType(...typeParameters)],
["tuple8", (...typeParameters: Type[]) => new TupleType(...typeParameters)],
// Known-length arrays.
// TODO: Handle these in typeExpressionParser, perhaps?
// TODO: Handle these in typeExpressionParser!
["array20", (...typeParameters: Type[]) => new ArrayVecType(20, typeParameters[0])],
["array32", (...typeParameters: Type[]) => new ArrayVecType(32, typeParameters[0])],
["array46", (...typeParameters: Type[]) => new ArrayVecType(46, typeParameters[0])],
Expand Down Expand Up @@ -93,14 +94,41 @@ export class TypeMapper {
["AsyncCall", new NothingType()]
]);

for (const customType of customTypes) {
this.closedTypesMap.set(customType.getName(), customType);
this.learnedTypesMap = new Map<string, Type>();

// Boostrap from previously learned types, if any.
for (const type of learnedTypes) {
this.learnedTypesMap.set(type.getName(), type);
}
}

mapType(type: Type): Type {
let mappedType = this.mapRecursiveType(type);
if (mappedType) {
// We do not learn generic types (that also have type parameters)
if (!mappedType.isGenericType()) {
this.learnType(mappedType);
}

return mappedType;
}

throw new errors.ErrTypingSystem(`Cannot map the type "${type.getName()}" to a known type`);
}

mapRecursiveType(type: Type): Type | null {
let isGeneric = type.isGenericType();

let previouslyLearnedType = this.learnedTypesMap.get(type.getName());
if (previouslyLearnedType) {
return previouslyLearnedType;
}

let knownClosedType = this.closedTypesMap.get(type.getName());
if (knownClosedType) {
return knownClosedType;
}

if (type.hasExactClass(EnumType.ClassName)) {
// This will call mapType() recursively, for all the enum variant fields.
return this.mapEnumType(<EnumType>type);
Expand All @@ -115,27 +143,13 @@ export class TypeMapper {
// This will call mapType() recursively, for all the type parameters.
return this.mapGenericType(type);
}

return null;
}

mapType(type: Type): Type {
let mappedType = this.mapRecursiveType(type);
if (mappedType !== null) {
return mappedType;
}

let knownClosedType = this.closedTypesMap.get(type.getName());
if (!knownClosedType) {
throw new errors.ErrTypingSystem(`Cannot map the type "${type.getName()}" to a known type`);
}

return this.mapRecursiveType(knownClosedType) ?? knownClosedType;
return null;
}

feedCustomType(type: Type): void {
this.closedTypesMap.delete(type.getName());
this.closedTypesMap.set(type.getName(), type);
private learnType(type: Type): void {
this.learnedTypesMap.delete(type.getName());
this.learnedTypesMap.set(type.getName(), type);
}

private mapStructType(type: StructType): StructType {
Expand Down
33 changes: 33 additions & 0 deletions src/testdata/array-in-nested-structs.abi.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "ArraysSample",
"endpoints": [],
"types": {
"Dummy": {
"type": "struct",
"fields": [
{
"name": "raw",
"type": "array20<u8>"
}
]
},
"Foo": {
"type": "struct",
"fields": [
{
"name": "dummy",
"type": "Dummy"
}
]
},
"Bar": {
"type": "struct",
"fields": [
{
"name": "foo",
"type": "Foo"
}
]
}
}
}
68 changes: 34 additions & 34 deletions src/testdata/esdt-nft-marketplace.abi.json
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,40 @@
],
"hasCallback": false,
"types": {
"EsdtToken": {
"type": "struct",
"fields": [
{
"name": "token_type",
"type": "TokenIdentifier"
},
{
"name": "nonce",
"type": "u64"
}
]
},
"AuctionType": {
"type": "enum",
"variants": [
{
"name": "None",
"discriminant": 0
},
{
"name": "Nft",
"discriminant": 1
},
{
"name": "SftAll",
"discriminant": 2
},
{
"name": "SftOnePerPayment",
"discriminant": 3
}
]
},
"Auction": {
"type": "struct",
"fields": [
Expand Down Expand Up @@ -459,40 +493,6 @@
"type": "BigUint"
}
]
},
"AuctionType": {
"type": "enum",
"variants": [
{
"name": "None",
"discriminant": 0
},
{
"name": "Nft",
"discriminant": 1
},
{
"name": "SftAll",
"discriminant": 2
},
{
"name": "SftOnePerPayment",
"discriminant": 3
}
]
},
"EsdtToken": {
"type": "struct",
"fields": [
{
"name": "token_type",
"type": "TokenIdentifier"
},
{
"name": "nonce",
"type": "u64"
}
]
}
}
}

0 comments on commit 455a29b

Please sign in to comment.