github.com/diadata-org/diadata@v1.4.593/pkg/dia/helpers/substrate-helper/gsrpc/registry/decoder.go (about)

     1  package registry
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  
     7  	"github.com/diadata-org/diadata/pkg/dia/helpers/substrate-helper/gsrpc/scale"
     8  	"github.com/diadata-org/diadata/pkg/dia/helpers/substrate-helper/gsrpc/types"
     9  	"github.com/diadata-org/diadata/pkg/dia/helpers/substrate-helper/gsrpc/types/extrinsic"
    10  	"github.com/ethereum/go-ethereum/common/hexutil"
    11  )
    12  
    13  // FieldDecoder is the interface implemented by all the different types that are available.
    14  type FieldDecoder interface {
    15  	Decode(decoder *scale.Decoder) (any, error)
    16  }
    17  
    18  // NoopDecoder is a FieldDecoder that does not decode anything. It comes in handy for nil tuples or variants
    19  // with no inner types.
    20  type NoopDecoder struct{}
    21  
    22  func (n *NoopDecoder) Decode(_ *scale.Decoder) (any, error) {
    23  	return nil, nil
    24  }
    25  
    26  // VariantDecoder holds a FieldDecoder for each variant/enum.
    27  type VariantDecoder struct {
    28  	FieldDecoderMap map[byte]FieldDecoder
    29  }
    30  
    31  type VariantDecoderResult struct {
    32  	FieldName string
    33  	Value     any
    34  }
    35  
    36  func (v *VariantDecoder) Decode(decoder *scale.Decoder) (any, error) {
    37  	variantByte, err := decoder.ReadOneByte()
    38  
    39  	if err != nil {
    40  		return nil, ErrVariantByteDecoding.Wrap(err)
    41  	}
    42  
    43  	variantDecoder, ok := v.FieldDecoderMap[variantByte]
    44  
    45  	if !ok {
    46  		return nil, ErrVariantFieldDecoderNotFound.WithMsg("variant '%d'", variantByte)
    47  	}
    48  
    49  	if _, ok := variantDecoder.(*NoopDecoder); ok {
    50  		return variantByte, nil
    51  	}
    52  
    53  	var fieldName string
    54  	if _, ok := variantDecoder.(*CompositeDecoder); ok {
    55  		fieldName = variantDecoder.(*CompositeDecoder).FieldName
    56  	}
    57  
    58  	value, err := variantDecoder.Decode(decoder)
    59  	if err != nil {
    60  		return nil, err
    61  	}
    62  
    63  	return VariantDecoderResult{fieldName, value}, nil
    64  }
    65  
    66  // ArrayDecoder holds information about the length of the array and the FieldDecoder used for its items.
    67  type ArrayDecoder struct {
    68  	Length      uint
    69  	ItemDecoder FieldDecoder
    70  }
    71  
    72  func (a *ArrayDecoder) Decode(decoder *scale.Decoder) (any, error) {
    73  	if a.ItemDecoder == nil {
    74  		return nil, ErrArrayItemDecoderNotFound
    75  	}
    76  
    77  	slice := make([]any, 0, a.Length)
    78  
    79  	for i := uint(0); i < a.Length; i++ {
    80  		item, err := a.ItemDecoder.Decode(decoder)
    81  
    82  		if err != nil {
    83  			return nil, ErrArrayItemDecoding.Wrap(err)
    84  		}
    85  
    86  		slice = append(slice, item)
    87  	}
    88  
    89  	return slice, nil
    90  }
    91  
    92  // SliceDecoder holds a FieldDecoder for the items of a vector/slice.
    93  type SliceDecoder struct {
    94  	ItemDecoder FieldDecoder
    95  }
    96  
    97  func (s *SliceDecoder) Decode(decoder *scale.Decoder) (any, error) {
    98  	if s.ItemDecoder == nil {
    99  		return nil, ErrSliceItemDecoderNotFound
   100  	}
   101  
   102  	sliceLen, err := decoder.DecodeUintCompact()
   103  
   104  	if err != nil {
   105  		return nil, ErrSliceLengthDecoding.Wrap(err)
   106  	}
   107  
   108  	slice := make([]any, 0, sliceLen.Uint64())
   109  
   110  	for i := uint64(0); i < sliceLen.Uint64(); i++ {
   111  		item, err := s.ItemDecoder.Decode(decoder)
   112  
   113  		if err != nil {
   114  			return nil, ErrSliceItemDecoding.Wrap(err)
   115  		}
   116  
   117  		slice = append(slice, item)
   118  	}
   119  
   120  	return slice, nil
   121  }
   122  
   123  // CompositeDecoder holds all the information required to decoder a struct/composite.
   124  type CompositeDecoder struct {
   125  	FieldName string
   126  	Fields    []*Field
   127  }
   128  
   129  func (e *CompositeDecoder) Decode(decoder *scale.Decoder) (any, error) {
   130  	var decodedFields DecodedFields
   131  
   132  	for _, field := range e.Fields {
   133  		value, err := field.FieldDecoder.Decode(decoder)
   134  
   135  		if err != nil {
   136  			return nil, ErrCompositeFieldDecoding.Wrap(err)
   137  		}
   138  
   139  		decodedFields = append(decodedFields, &DecodedField{
   140  			Name:        field.Name,
   141  			Value:       value,
   142  			LookupIndex: field.LookupIndex,
   143  		})
   144  	}
   145  
   146  	return decodedFields, nil
   147  }
   148  
   149  // ValueDecoder decodes a primitive type.
   150  type ValueDecoder[T any] struct{}
   151  
   152  func (v *ValueDecoder[T]) Decode(decoder *scale.Decoder) (any, error) {
   153  	var t T
   154  
   155  	if err := decoder.Decode(&t); err != nil {
   156  		return nil, ErrValueDecoding.Wrap(err)
   157  	}
   158  
   159  	return t, nil
   160  }
   161  
   162  // RecursiveDecoder is a wrapper for a FieldDecoder that is recursive.
   163  type RecursiveDecoder struct {
   164  	FieldDecoder FieldDecoder
   165  }
   166  
   167  func (r *RecursiveDecoder) Decode(decoder *scale.Decoder) (any, error) {
   168  	if r.FieldDecoder == nil {
   169  		return nil, ErrRecursiveFieldDecoderNotFound
   170  	}
   171  
   172  	return r.FieldDecoder.Decode(decoder)
   173  }
   174  
   175  // BitSequenceDecoder holds decoding information for a bit sequence.
   176  type BitSequenceDecoder struct {
   177  	FieldName string
   178  	BitOrder  types.BitOrder
   179  }
   180  
   181  func (b *BitSequenceDecoder) Decode(decoder *scale.Decoder) (any, error) {
   182  	bitVec := types.NewBitVec(b.BitOrder)
   183  
   184  	if err := bitVec.Decode(*decoder); err != nil {
   185  		return nil, ErrBitVecDecoding.Wrap(err)
   186  	}
   187  
   188  	return map[string]string{
   189  		b.FieldName: bitVec.String(),
   190  	}, nil
   191  }
   192  
   193  // TypeDecoder holds all information required to decode a particular type.
   194  type TypeDecoder struct {
   195  	Name   string
   196  	Fields []*Field
   197  }
   198  
   199  func (t *TypeDecoder) Decode(decoder *scale.Decoder) (DecodedFields, error) {
   200  	if t == nil {
   201  		return nil, ErrNilTypeDecoder
   202  	}
   203  
   204  	var decodedFields DecodedFields
   205  
   206  	for _, field := range t.Fields {
   207  		decodedField, err := field.Decode(decoder)
   208  
   209  		if err != nil {
   210  			return nil, ErrTypeFieldDecoding.Wrap(err)
   211  		}
   212  
   213  		decodedFields = append(decodedFields, decodedField)
   214  	}
   215  
   216  	return decodedFields, nil
   217  }
   218  
   219  // getPrimitiveDecoder parses a primitive type definition and returns a ValueDecoder.
   220  func getPrimitiveDecoder(primitiveTypeDef types.Si0TypeDefPrimitive) (FieldDecoder, error) {
   221  	switch primitiveTypeDef {
   222  	case types.IsBool:
   223  		return &ValueDecoder[bool]{}, nil
   224  	case types.IsChar:
   225  		return &ValueDecoder[byte]{}, nil
   226  	case types.IsStr:
   227  		return &ValueDecoder[string]{}, nil
   228  	case types.IsU8:
   229  		return &ValueDecoder[types.U8]{}, nil
   230  	case types.IsU16:
   231  		return &ValueDecoder[types.U16]{}, nil
   232  	case types.IsU32:
   233  		return &ValueDecoder[types.U32]{}, nil
   234  	case types.IsU64:
   235  		return &ValueDecoder[types.U64]{}, nil
   236  	case types.IsU128:
   237  		return &ValueDecoder[types.U128]{}, nil
   238  	case types.IsU256:
   239  		return &ValueDecoder[types.U256]{}, nil
   240  	case types.IsI8:
   241  		return &ValueDecoder[types.I8]{}, nil
   242  	case types.IsI16:
   243  		return &ValueDecoder[types.I16]{}, nil
   244  	case types.IsI32:
   245  		return &ValueDecoder[types.I32]{}, nil
   246  	case types.IsI64:
   247  		return &ValueDecoder[types.I64]{}, nil
   248  	case types.IsI128:
   249  		return &ValueDecoder[types.I128]{}, nil
   250  	case types.IsI256:
   251  		return &ValueDecoder[types.I256]{}, nil
   252  	default:
   253  		return nil, ErrPrimitiveTypeNotSupported.WithMsg("primitive type %v", primitiveTypeDef)
   254  	}
   255  }
   256  
   257  // Field represents one field of a TypeDecoder.
   258  type Field struct {
   259  	Name         string
   260  	FieldDecoder FieldDecoder
   261  	LookupIndex  int64
   262  }
   263  
   264  func (f *Field) Decode(decoder *scale.Decoder) (*DecodedField, error) {
   265  	if f == nil {
   266  		return nil, ErrNilField
   267  	}
   268  
   269  	if f.FieldDecoder == nil {
   270  		return nil, ErrNilFieldDecoder
   271  	}
   272  
   273  	value, err := f.FieldDecoder.Decode(decoder)
   274  
   275  	if err != nil {
   276  		return nil, err
   277  	}
   278  
   279  	return &DecodedField{
   280  		Name:        f.Name,
   281  		Value:       value,
   282  		LookupIndex: f.LookupIndex,
   283  	}, nil
   284  }
   285  
   286  // DecodedField holds the name, value and lookup index of a field that was decoded.
   287  type DecodedField struct {
   288  	Name        string
   289  	Value       any
   290  	LookupIndex int64
   291  }
   292  
   293  func (d DecodedField) Encode(encoder scale.Encoder) error {
   294  	if d.Value == nil {
   295  		return nil
   296  	}
   297  
   298  	return encoder.Encode(d.Value)
   299  }
   300  
   301  type DecodedFields []*DecodedField
   302  
   303  type DecodedFieldPredicateFn func(fieldIndex int, field *DecodedField) bool
   304  type DecodedValueProcessingFn[T any] func(value any) (T, error)
   305  
   306  // ProcessDecodedFieldValue applies the processing func to the value of the field
   307  // that matches the provided predicate func.
   308  func ProcessDecodedFieldValue[T any](
   309  	decodedFields DecodedFields,
   310  	fieldPredicateFn DecodedFieldPredicateFn,
   311  	valueProcessingFn DecodedValueProcessingFn[T],
   312  ) (T, error) {
   313  	var t T
   314  
   315  	for decodedFieldIndex, decodedField := range decodedFields {
   316  		if !fieldPredicateFn(decodedFieldIndex, decodedField) {
   317  			continue
   318  		}
   319  
   320  		res, err := valueProcessingFn(decodedField.Value)
   321  
   322  		if err != nil {
   323  			return t, ErrDecodedFieldValueProcessingError.Wrap(err)
   324  		}
   325  
   326  		return res, nil
   327  	}
   328  
   329  	return t, ErrDecodedFieldNotFound
   330  }
   331  
   332  // GetDecodedFieldAsType returns the value of the field that matches the provided predicate func
   333  // as the provided generic argument.
   334  func GetDecodedFieldAsType[T any](
   335  	decodedFields DecodedFields,
   336  	fieldPredicateFn DecodedFieldPredicateFn,
   337  ) (T, error) {
   338  	return ProcessDecodedFieldValue(
   339  		decodedFields,
   340  		fieldPredicateFn,
   341  		func(value any) (T, error) {
   342  			if res, ok := value.(T); ok {
   343  				return res, nil
   344  			}
   345  
   346  			var t T
   347  
   348  			err := fmt.Errorf("expected %T, got %T", t, value)
   349  
   350  			return t, ErrDecodedFieldValueTypeMismatch.Wrap(err)
   351  		},
   352  	)
   353  }
   354  
   355  // GetDecodedFieldAsSliceOfType returns the value of the field that matches the provided predicate func
   356  // as a slice of the provided generic argument.
   357  func GetDecodedFieldAsSliceOfType[T any](
   358  	decodedFields DecodedFields,
   359  	fieldPredicateFn DecodedFieldPredicateFn,
   360  ) ([]T, error) {
   361  	return ProcessDecodedFieldValue(
   362  		decodedFields,
   363  		fieldPredicateFn,
   364  		func(value any) ([]T, error) {
   365  			v, ok := value.([]any)
   366  
   367  			if !ok {
   368  				return nil, ErrDecodedFieldValueNotAGenericSlice
   369  			}
   370  
   371  			res, err := convertSliceToType[T](v)
   372  
   373  			if err != nil {
   374  				return nil, ErrDecodedFieldValueTypeMismatch.Wrap(err)
   375  			}
   376  
   377  			return res, nil
   378  		},
   379  	)
   380  }
   381  
   382  func convertSliceToType[T any](slice []any) ([]T, error) {
   383  	res := make([]T, 0)
   384  
   385  	for _, item := range slice {
   386  		if v, ok := item.(T); ok {
   387  			res = append(res, v)
   388  			continue
   389  		}
   390  
   391  		var t T
   392  
   393  		return nil, fmt.Errorf("expected %T, got %T", t, item)
   394  	}
   395  
   396  	return res, nil
   397  }
   398  
   399  // DecodedExtrinsic is the type returned when an extrinsic is decoded.
   400  type DecodedExtrinsic struct {
   401  	Version       byte
   402  	DecodedFields DecodedFields
   403  }
   404  
   405  // IsSigned returns true if the extrinsic is signed.
   406  func (d DecodedExtrinsic) IsSigned() bool {
   407  	return d.Version&extrinsic.BitSigned == extrinsic.BitSigned
   408  }
   409  
   410  // ExtrinsicDecoder holds all the decoders for all the fields of an extrinsic.
   411  type ExtrinsicDecoder struct {
   412  	Fields []*Field
   413  }
   414  
   415  func (d *ExtrinsicDecoder) getFieldWithName(fieldName string) (*Field, error) {
   416  	for _, field := range d.Fields {
   417  		if field.Name == fieldName {
   418  			return field, nil
   419  		}
   420  	}
   421  
   422  	return nil, ErrExtrinsicFieldNotFound.WithMsg("expected field name '%s'", fieldName)
   423  }
   424  
   425  func (d *ExtrinsicDecoder) decodeField(fieldName string, decoder *scale.Decoder) (*DecodedField, error) {
   426  	extrinsicField, err := d.getFieldWithName(fieldName)
   427  
   428  	if err != nil {
   429  		return nil, err
   430  	}
   431  
   432  	decodedField, err := extrinsicField.Decode(decoder)
   433  
   434  	if err != nil {
   435  		return nil, ErrExtrinsicFieldDecoding.Wrap(err).WithMsg("field name - '%s'", fieldName)
   436  	}
   437  
   438  	return decodedField, nil
   439  }
   440  
   441  func (d *ExtrinsicDecoder) DecodeHex(hexEncodedExtrinsic string) (*DecodedExtrinsic, error) {
   442  	extrinsicBytes, err := hexutil.Decode(hexEncodedExtrinsic)
   443  
   444  	if err != nil {
   445  		return nil, err
   446  	}
   447  
   448  	decoder := scale.NewDecoder(bytes.NewReader(extrinsicBytes))
   449  
   450  	return d.Decode(decoder)
   451  }
   452  
   453  // Decode is used to decode the fields of an extrinsic in the following order:
   454  //
   455  // 1. Address
   456  // 2. Signature
   457  // 3. Extra
   458  // 4. Call
   459  //
   460  // NOTE - the decoding order is different from the order of the Extrinsic parameters provided in the metadata.
   461  func (d *ExtrinsicDecoder) Decode(decoder *scale.Decoder) (*DecodedExtrinsic, error) {
   462  	if d == nil {
   463  		return nil, ErrNilExtrinsicDecoder
   464  	}
   465  
   466  	decodedExtrinsic := &DecodedExtrinsic{}
   467  
   468  	// compact length encoding (1, 2, or 4 bytes) (may not be there for Extrinsics older than Jan 11 2019)
   469  	_, err := decoder.DecodeUintCompact()
   470  
   471  	if err != nil {
   472  		return nil, ErrExtrinsicCompactLengthDecoding.Wrap(err)
   473  	}
   474  
   475  	if err := decoder.Decode(&decodedExtrinsic.Version); err != nil {
   476  		return nil, ErrExtrinsicVersionDecoding.Wrap(err)
   477  	}
   478  
   479  	var decodedFields DecodedFields
   480  
   481  	if decodedExtrinsic.IsSigned() {
   482  		decodedAddress, err := d.decodeField(ExtrinsicAddressName, decoder)
   483  
   484  		if err != nil {
   485  			return nil, err
   486  		}
   487  
   488  		decodedFields = append(decodedFields, decodedAddress)
   489  
   490  		decodedSignature, err := d.decodeField(ExtrinsicSignatureName, decoder)
   491  
   492  		if err != nil {
   493  			return nil, err
   494  		}
   495  
   496  		decodedFields = append(decodedFields, decodedSignature)
   497  
   498  		decodedExtraField, err := d.decodeField(ExtrinsicExtraName, decoder)
   499  
   500  		if err != nil {
   501  			return nil, err
   502  		}
   503  
   504  		decodedFields = append(decodedFields, decodedExtraField)
   505  	}
   506  
   507  	decodedCall, err := d.decodeField(ExtrinsicCallName, decoder)
   508  
   509  	if err != nil {
   510  		return nil, err
   511  	}
   512  
   513  	decodedFields = append(decodedFields, decodedCall)
   514  
   515  	decodedExtrinsic.DecodedFields = decodedFields
   516  
   517  	return decodedExtrinsic, nil
   518  }