diff --git a/build/runtime.wasm b/build/runtime.wasm index 796ac17e..5af509f2 100755 Binary files a/build/runtime.wasm and b/build/runtime.wasm differ diff --git a/primitives/types/extra.go b/primitives/types/extra.go index c2b44751..fcfc29fb 100644 --- a/primitives/types/extra.go +++ b/primitives/types/extra.go @@ -155,10 +155,8 @@ func (e signedExtra) Metadata(constantsIdsMap map[string]int) (sc.Sequence[Metad signedExtensions := sc.Sequence[MetadataSignedExtension]{} for _, extra := range e.extras { - extraType, extension := generateExtraMetadata(extra, constantsIdsMap, &extraTypes) - ids = append(ids, extraType.Id) - extraTypes = append(extraTypes, extraType) - signedExtensions = append(signedExtensions, extension) + extraMetadataId := generateExtraMetadata(extra, constantsIdsMap, &extraTypes, &signedExtensions) + ids = append(ids, sc.ToCompact(extraMetadataId)) } signedExtraType := NewMetadataType(metadata.SignedExtra, "SignedExtra", NewMetadataTypeDefinitionTuple(ids)) @@ -166,56 +164,42 @@ func (e signedExtra) Metadata(constantsIdsMap map[string]int) (sc.Sequence[Metad return append(extraTypes, signedExtraType), signedExtensions } -// generateExtraMetadata generates the metadata for a signed extension. It may generate some new metadata types in the process. -func generateExtraMetadata(extra SignedExtension, metadataIds map[string]int, metadataTypes *sc.Sequence[MetadataType]) (MetadataType, MetadataSignedExtension) { +// generateExtraMetadata generates the metadata for a signed extension. It may generate some new metadata types in the process. Returns the metadata id for the extra +func generateExtraMetadata(extra SignedExtension, metadataIds map[string]int, metadataTypes *sc.Sequence[MetadataType], extensions *sc.Sequence[MetadataSignedExtension]) int { extraValue := reflect.ValueOf(extra) extraType := extraValue.Elem().Type() extraTypeName := extraType.Name() - lastIndex := len(metadataIds) - extraMetadataId, ok := metadataIds[extraTypeName] if !ok { - extraMetadataId = assignNewMetadataId(metadataIds, &lastIndex, &extraTypeName) + extraMetadataId = buildMetadataTypeRecursively(extraType, metadataIds, metadataTypes, true) + } else { + extraMetadata := getExtraMetadata(extraMetadataId, metadataTypes) + *metadataTypes = append(*metadataTypes, extraMetadata) } - var extension MetadataSignedExtension - var metadataTypeFields sc.Sequence[MetadataTypeDefinitionField] + constructExtension(extraValue, extraMetadataId, extensions, metadataIds, metadataTypes) - extraNumOfFields := extraType.NumField() + return extraMetadataId +} - for j := 0; j < extraNumOfFields; j++ { - field := extraValue.Elem().Field(j) - fieldTypeName := field.Type().Name() - fieldName := extraType.Field(j).Name - if fieldTypeName == moduleTypeName { // TODO: Exclude OnChargeTransaction as well - continue - } - if fieldName != additionalSignedTypeName { - fieldTypeId, ok := metadataIds[fieldTypeName] - if !ok { - fieldTypeId = assignNewMetadataId(metadataIds, &lastIndex, &fieldTypeName) - newType := generateNewType(fieldTypeId, field.Type()) - *metadataTypes = append(*metadataTypes, newType) - } - metadataTypeFields = append(metadataTypeFields, NewMetadataTypeDefinitionFieldWithName(fieldTypeId, sc.Str(fieldTypeName))) - continue +func getExtraMetadata(id int, metadataTypes *sc.Sequence[MetadataType]) MetadataType { + for _, t := range *metadataTypes { + if t.Id.ToBigInt().Int64() == int64(id) { + return t } - extension = constructExtension(extraTypeName, extraMetadataId, field, metadataTypes, metadataIds, lastIndex) } - - return NewMetadataTypeWithPath( - extraMetadataId, - extraTypeName, - sc.Sequence[sc.Str]{"extensions", sc.Str(strcase.ToSnake(extraTypeName)), sc.Str(extraTypeName)}, - NewMetadataTypeDefinitionComposite(metadataTypeFields)), extension + return MetadataType{} } -func generateNewType(id int, t reflect.Type) MetadataType { - typeFields := sc.Sequence[MetadataTypeDefinitionField]{} +// buildMetadataTypeRecursively build the metadata of the type recursively. +func buildMetadataTypeRecursively(t reflect.Type, metadataIds map[string]int, metadataTypes *sc.Sequence[MetadataType], isExtra bool) int { + typeId := assignNewMetadataId(metadataIds, t.Name()) typeName := t.Name() + metadataFields := sc.Sequence[MetadataTypeDefinitionField]{} + typeNumFields := 0 if t.Kind() == reflect.Struct { @@ -224,83 +208,82 @@ func generateNewType(id int, t reflect.Type) MetadataType { for i := 0; i < typeNumFields; i++ { fieldName := t.Field(i).Name - //fieldId, ok := metadataIds[fieldName] - //if !ok { - // generateNewType(id, t.Field(i).Type, metadataIds) - //} - typeFields = append(typeFields, NewMetadataTypeDefinitionFieldWithName(id, sc.Str(fieldName))) + fieldTypeName := t.Field(i).Type.Name() + if isIgnoredName(fieldName) || isIgnoredType(fieldTypeName) { + continue + } + fieldId, ok := metadataIds[fieldTypeName] + if !ok { + fieldId = buildMetadataTypeRecursively(t.Field(i).Type, metadataIds, metadataTypes, false) + } + metadataFields = append(metadataFields, NewMetadataTypeDefinitionFieldWithName(fieldId, sc.Str(fieldName))) } - return NewMetadataType( - id, - typeName, - NewMetadataTypeDefinitionComposite(typeFields), - ) -} + if isExtra { + metadataType := NewMetadataTypeWithPath(typeId, typeName, sc.Sequence[sc.Str]{"extensions", sc.Str(strcase.ToSnake(typeName)), sc.Str(typeName)}, NewMetadataTypeDefinitionComposite(metadataFields)) + *metadataTypes = append(*metadataTypes, metadataType) + return typeId + } -//func generateNewTypeRecursive(t reflect.Type, metadataIds map[string]int, metadataTypes *sc.Sequence[MetadataType]) { -// typeFields := sc.Sequence[MetadataTypeDefinitionField]{} -// -// typeName := t.Name() -// -// typeNumFields := 0 -// -// if t.Kind() == reflect.Struct { -// typeNumFields = t.NumField() -// } -// -// var fieldId int -// for i := 0; i < typeNumFields; i++ { -// fieldName := t.Field(i).Name -// fieldId, ok := metadataIds[fieldName] -// if !ok { -// generateNewType(t.Field(i).Type, metadataIds, metadataTypes) -// } -// typeFields = append(typeFields, NewMetadataTypeDefinitionFieldWithName(id, sc.Str(fieldName))) -// } -// -// *metadataTypes = append(*metadataTypes, -// NewMetadataType( -// fieldId, -// typeName, -// NewMetadataTypeDefinitionComposite(typeFields))) -//} + *metadataTypes = append(*metadataTypes, + NewMetadataType( + typeId, + typeName, + NewMetadataTypeDefinitionComposite(metadataFields))) + + return typeId +} func generateCompositeType(typeId int, typeName string, tupleIds sc.Sequence[sc.Compact]) MetadataType { return NewMetadataType(typeId, typeName, NewMetadataTypeDefinitionTuple(tupleIds)) } -func assignNewMetadataId(metadataIds map[string]int, lastIndex *int, name *string) int { - newId := *lastIndex + 1 - *lastIndex = *lastIndex + 1 - metadataIds[*name] = newId +func isIgnoredType(t string) bool { + return t == moduleTypeName +} + +func isIgnoredName(name string) bool { + return name == additionalSignedTypeName +} + +func assignNewMetadataId(metadataIds map[string]int, name string) int { + lastIndex := len(metadataIds) + newId := lastIndex + 1 + metadataIds[name] = newId return newId } -func constructExtension(extraTypeName string, extraMetadataId int, field reflect.Value, metadataTypes *sc.Sequence[MetadataType], metadataIds map[string]int, lastIndex int) MetadataSignedExtension { - var resultTypeId int +// constructExtension Iterates through the elements of the additionalSignedData slice and builds the extra extension. If an element in the slice is a type not present in the metadata map, it is generated. +func constructExtension(extra reflect.Value, extraMetadataId int, extensions *sc.Sequence[MetadataSignedExtension], metadataIds map[string]int, metadataTypes *sc.Sequence[MetadataType]) { var resultTypeName string var resultTupleIds sc.Sequence[sc.Compact] - numAdditionalSignedTypes := field.Len() - if numAdditionalSignedTypes == 0 { - return NewMetadataSignedExtension(sc.Str(extraTypeName), extraMetadataId, metadata.TypesEmptyTuple) - } - for i := 0; i < numAdditionalSignedTypes; i++ { - currentType := field.Index(i).Elem().Type() - currentTypeName := currentType.Name() - currentTypeId, ok := metadataIds[currentTypeName] + + extraType := extra.Elem().Type + extraName := extraType().Name() + + additionalSignedField := extra.Elem().FieldByName(additionalSignedTypeName) + + if additionalSignedField.IsValid() { + numAdditionalSignedTypes := additionalSignedField.Len() + if numAdditionalSignedTypes == 0 { + *extensions = append(*extensions, NewMetadataSignedExtension(sc.Str(extraName), extraMetadataId, metadata.TypesEmptyTuple)) + return + } + for i := 0; i < numAdditionalSignedTypes; i++ { + currentType := additionalSignedField.Index(i).Elem().Type() + currentTypeName := currentType.Name() + currentTypeId, ok := metadataIds[currentTypeName] + if !ok { + currentTypeId = buildMetadataTypeRecursively(currentType, metadataIds, metadataTypes, false) + } + resultTypeName = resultTypeName + currentTypeName + resultTupleIds = append(resultTupleIds, sc.ToCompact(currentTypeId)) + } + resultTypeId, ok := metadataIds[resultTypeName] if !ok { - currentTypeId = assignNewMetadataId(metadataIds, &lastIndex, ¤tTypeName) - newType := generateNewType(currentTypeId, currentType) - *metadataTypes = append(*metadataTypes, newType) + resultTypeId = assignNewMetadataId(metadataIds, resultTypeName) + *metadataTypes = append(*metadataTypes, generateCompositeType(resultTypeId, resultTypeName, resultTupleIds)) } - resultTypeName = resultTypeName + currentTypeName - resultTupleIds = append(resultTupleIds, sc.ToCompact(currentTypeId)) - } - resultTypeId, ok := metadataIds[resultTypeName] - if !ok { - resultTypeId = assignNewMetadataId(metadataIds, &lastIndex, &resultTypeName) - *metadataTypes = append(*metadataTypes, generateCompositeType(resultTypeId, resultTypeName, resultTupleIds)) + *extensions = append(*extensions, NewMetadataSignedExtension(sc.Str(extraName), extraMetadataId, resultTypeId)) } - return NewMetadataSignedExtension(sc.Str(extraTypeName), extraMetadataId, resultTypeId) } diff --git a/primitives/types/extra_test.go b/primitives/types/extra_test.go index 5468003f..dee160c7 100644 --- a/primitives/types/extra_test.go +++ b/primitives/types/extra_test.go @@ -51,8 +51,8 @@ var ( Params: sc.Sequence[MetadataTypeParameter]{}, Definition: NewMetadataTypeDefinitionComposite( sc.Sequence[MetadataTypeDefinitionField]{ - NewMetadataTypeDefinitionFieldWithName(metadata.PrimitiveTypesBool, "Bool"), - NewMetadataTypeDefinitionFieldWithName(metadata.PrimitiveTypesU32, "U32"), + NewMetadataTypeDefinitionFieldWithName(metadata.PrimitiveTypesBool, "hasError"), + NewMetadataTypeDefinitionFieldWithName(metadata.PrimitiveTypesU32, "value"), }, ), Docs: sc.Sequence[sc.Str]{"testExtraCheck"}, @@ -203,9 +203,9 @@ var ( expectedEraMetadataId, "Era", NewMetadataTypeDefinitionComposite(sc.Sequence[MetadataTypeDefinitionField]{ - NewMetadataTypeDefinitionFieldWithName(expectedEraMetadataId, "IsImmortal"), - NewMetadataTypeDefinitionFieldWithName(expectedEraMetadataId, "EraPeriod"), - NewMetadataTypeDefinitionFieldWithName(expectedEraMetadataId, "EraPhase")}), + NewMetadataTypeDefinitionFieldWithName(metadata.PrimitiveTypesBool, "IsImmortal"), + NewMetadataTypeDefinitionFieldWithName(metadata.PrimitiveTypesU64, "EraPeriod"), + NewMetadataTypeDefinitionFieldWithName(metadata.PrimitiveTypesU64, "EraPhase")}), ) testExtraCheckEmptyMetadataType = MetadataType{ @@ -213,7 +213,7 @@ var ( Path: sc.Sequence[sc.Str]{"extensions", "test_extra_check_empty", "testExtraCheckEmpty"}, Params: sc.Sequence[MetadataTypeParameter]{}, Definition: NewMetadataTypeDefinitionComposite( - nil, + sc.Sequence[MetadataTypeDefinitionField]{}, ), Docs: sc.Sequence[sc.Str]{"testExtraCheckEmpty"}, } @@ -224,7 +224,7 @@ var ( Params: sc.Sequence[MetadataTypeParameter]{}, Definition: NewMetadataTypeDefinitionComposite( sc.Sequence[MetadataTypeDefinitionField]{ - NewMetadataTypeDefinitionFieldWithName(expectedEraMetadataId, "Era"), + NewMetadataTypeDefinitionFieldWithName(expectedEraMetadataId, "era"), }, ), Docs: sc.Sequence[sc.Str]{"testExtraCheckEra"}, @@ -236,9 +236,9 @@ var ( Params: sc.Sequence[MetadataTypeParameter]{}, Definition: NewMetadataTypeDefinitionComposite( sc.Sequence[MetadataTypeDefinitionField]{ - NewMetadataTypeDefinitionFieldWithName(expectedEraMetadataId, "Era"), - NewMetadataTypeDefinitionFieldWithName(metadata.TypesH256, "H256"), - NewMetadataTypeDefinitionFieldWithName(metadata.PrimitiveTypesU64, "U64"), + NewMetadataTypeDefinitionFieldWithName(expectedEraMetadataId, "era"), + NewMetadataTypeDefinitionFieldWithName(metadata.TypesH256, "hash"), + NewMetadataTypeDefinitionFieldWithName(metadata.PrimitiveTypesU64, "value"), }, ), Docs: sc.Sequence[sc.Str]{"testExtraCheckComplex"}, @@ -248,8 +248,8 @@ var ( testExtraCheckEmptyMetadataType, eraMetadataType, // during the process of generating the metadata of testExtraCheckEra that has a field "Era", this metadata type was generated so we expect it included in the sequence of metadata types testExtraCheckEraMetadataType, - tupleAdditionalSignedMetadataType, // same here testExtraCheckComplexMetadataType, + tupleAdditionalSignedMetadataType, // same here signedExtraMdType, } ) @@ -257,20 +257,22 @@ var ( var ( // A map that does not contain the ids of types H512 and Ed25519PublicKey hence they need to be generated metadataIdsComplexSome = map[string]int{ - "Bool": metadata.PrimitiveTypesBool, - "String": metadata.PrimitiveTypesString, - "U8": metadata.PrimitiveTypesU8, - "U16": metadata.PrimitiveTypesU16, - "U32": metadata.PrimitiveTypesU32, - "U64": metadata.PrimitiveTypesU64, - "U128": metadata.PrimitiveTypesU128, - "U256": metadata.PrimitiveTypesU256, - "I8": metadata.PrimitiveTypesI8, - "I16": metadata.PrimitiveTypesI16, - "I32": metadata.PrimitiveTypesI32, - "I64": metadata.PrimitiveTypesI64, - "I128": metadata.PrimitiveTypesI128, - "H256": metadata.TypesH256, + "Bool": metadata.PrimitiveTypesBool, + "String": metadata.PrimitiveTypesString, + "U8": metadata.PrimitiveTypesU8, + "U16": metadata.PrimitiveTypesU16, + "U32": metadata.PrimitiveTypesU32, + "U64": metadata.PrimitiveTypesU64, + "U128": metadata.PrimitiveTypesU128, + "U256": metadata.PrimitiveTypesU256, + "I8": metadata.PrimitiveTypesI8, + "I16": metadata.PrimitiveTypesI16, + "I32": metadata.PrimitiveTypesI32, + "I64": metadata.PrimitiveTypesI64, + "I128": metadata.PrimitiveTypesI128, + "H256": metadata.TypesH256, + "H512": metadata.TypesFixedSequence64U8, + "Ed25519PublicKey": metadata.TypesFixedSequence64U8, } lastIndexComplexChecksSome = len(metadataIdsComplexSome) @@ -279,18 +281,14 @@ var ( expectedCheckEraMetadataIdSome = lastIndexComplexChecksSome + 2 expectedEraMetadataIdSome = lastIndexComplexChecksSome + 3 expectedExtraCheckComplexIdSome = lastIndexComplexChecksSome + 4 - expectedH512Id = lastIndexComplexChecksSome + 5 - expectedEd25519Id = lastIndexComplexChecksSome + 6 - expectedTupleAdditionalSignedMetadataIdSome = lastIndexComplexChecksSome + 7 + expectedTupleAdditionalSignedMetadataIdSome = lastIndexComplexChecksSome + 5 testExtraCheckEmptyMetadataTypeSome = MetadataType{ - Id: sc.ToCompact(expectedEmptyCheckMetadataIdSome), - Path: sc.Sequence[sc.Str]{"extensions", "test_extra_check_empty", "testExtraCheckEmpty"}, - Params: sc.Sequence[MetadataTypeParameter]{}, - Definition: NewMetadataTypeDefinitionComposite( - nil, - ), - Docs: sc.Sequence[sc.Str]{"testExtraCheckEmpty"}, + Id: sc.ToCompact(expectedEmptyCheckMetadataIdSome), + Path: sc.Sequence[sc.Str]{"extensions", "test_extra_check_empty", "testExtraCheckEmpty"}, + Params: sc.Sequence[MetadataTypeParameter]{}, + Definition: NewMetadataTypeDefinitionComposite(sc.Sequence[MetadataTypeDefinitionField]{}), + Docs: sc.Sequence[sc.Str]{"testExtraCheckEmpty"}, } testExtraCheckEraMetadataTypeSome = MetadataType{ @@ -299,7 +297,7 @@ var ( Params: sc.Sequence[MetadataTypeParameter]{}, Definition: NewMetadataTypeDefinitionComposite( sc.Sequence[MetadataTypeDefinitionField]{ - NewMetadataTypeDefinitionFieldWithName(expectedEraMetadataIdSome, "Era"), + NewMetadataTypeDefinitionFieldWithName(expectedEraMetadataIdSome, "era"), }, ), Docs: sc.Sequence[sc.Str]{"testExtraCheckEra"}, @@ -309,31 +307,19 @@ var ( expectedEraMetadataIdSome, "Era", NewMetadataTypeDefinitionComposite(sc.Sequence[MetadataTypeDefinitionField]{ - NewMetadataTypeDefinitionFieldWithName(expectedEraMetadataIdSome, "IsImmortal"), - NewMetadataTypeDefinitionFieldWithName(expectedEraMetadataIdSome, "EraPeriod"), - NewMetadataTypeDefinitionFieldWithName(expectedEraMetadataIdSome, "EraPhase"), + NewMetadataTypeDefinitionFieldWithName(metadata.PrimitiveTypesBool, "IsImmortal"), + NewMetadataTypeDefinitionFieldWithName(metadata.PrimitiveTypesU64, "EraPeriod"), + NewMetadataTypeDefinitionFieldWithName(metadata.PrimitiveTypesU64, "EraPhase"), }), ) - h512MetadataType = NewMetadataType( - expectedH512Id, - "H512", - NewMetadataTypeDefinitionComposite(sc.Sequence[MetadataTypeDefinitionField]{NewMetadataTypeDefinitionFieldWithName(expectedH512Id, "FixedSequence")}), - ) - - ed25519PublicKeyMetadataType = NewMetadataType( - expectedEd25519Id, - "Ed25519PublicKey", - NewMetadataTypeDefinitionComposite(sc.Sequence[MetadataTypeDefinitionField]{NewMetadataTypeDefinitionFieldWithName(expectedEd25519Id, "FixedSequence")}), - ) - tupleAdditionalSignedMetadataTypeSome = NewMetadataType(expectedTupleAdditionalSignedMetadataIdSome, "H256U32U64H512Ed25519PublicKey", NewMetadataTypeDefinitionTuple(sc.Sequence[sc.Compact]{ sc.ToCompact(metadata.TypesH256), sc.ToCompact(metadata.PrimitiveTypesU32), sc.ToCompact(metadata.PrimitiveTypesU64), - sc.ToCompact(expectedH512Id), - sc.ToCompact(expectedEd25519Id)})) + sc.ToCompact(metadata.TypesFixedSequence64U8), + sc.ToCompact(metadata.TypesFixedSequence64U8)})) testExtraCheckComplexMetadataTypeSome = MetadataType{ Id: sc.ToCompact(expectedExtraCheckComplexIdSome), @@ -341,9 +327,9 @@ var ( Params: sc.Sequence[MetadataTypeParameter]{}, Definition: NewMetadataTypeDefinitionComposite( sc.Sequence[MetadataTypeDefinitionField]{ - NewMetadataTypeDefinitionFieldWithName(expectedEraMetadataIdSome, "Era"), - NewMetadataTypeDefinitionFieldWithName(metadata.TypesH256, "H256"), - NewMetadataTypeDefinitionFieldWithName(metadata.PrimitiveTypesU64, "U64"), + NewMetadataTypeDefinitionFieldWithName(expectedEraMetadataIdSome, "era"), + NewMetadataTypeDefinitionFieldWithName(metadata.TypesH256, "hash"), + NewMetadataTypeDefinitionFieldWithName(metadata.PrimitiveTypesU64, "value"), }, ), Docs: sc.Sequence[sc.Str]{"testExtraCheckComplex"}, @@ -361,10 +347,8 @@ var ( testExtraCheckEmptyMetadataTypeSome, eraMetadataTypeSome, testExtraCheckEraMetadataTypeSome, - h512MetadataType, - ed25519PublicKeyMetadataType, - tupleAdditionalSignedMetadataTypeSome, testExtraCheckComplexMetadataTypeSome, + tupleAdditionalSignedMetadataTypeSome, signedExtraMdTypeSome, } diff --git a/primitives/types/testExtraCheckEmpty_test.go b/primitives/types/testExtraCheckEmpty_test.go index 033a06dc..5665dcbc 100644 --- a/primitives/types/testExtraCheckEmpty_test.go +++ b/primitives/types/testExtraCheckEmpty_test.go @@ -12,7 +12,7 @@ type testExtraCheckEmpty struct { func newTestExtraCheckEmpty() SignedExtension { return &testExtraCheckEmpty{ - additionalSignedData: sc.VaryingData{}, + additionalSignedData: sc.NewVaryingData(), } } diff --git a/primitives/types/testExtraCheckEra_test.go b/primitives/types/testExtraCheckEra_test.go index 01dfbe83..a838c2de 100644 --- a/primitives/types/testExtraCheckEra_test.go +++ b/primitives/types/testExtraCheckEra_test.go @@ -15,7 +15,7 @@ type testExtraCheckEra struct { func newtTestExtraCheckEra() SignedExtension { return &testExtraCheckEra{ era: Era{}, - additionalSignedData: sc.VaryingData{H256{}}, + additionalSignedData: sc.NewVaryingData(H256{}), } }