-
Notifications
You must be signed in to change notification settings - Fork 130
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
chore (pkg/scale) scale babe integration #1670
Changes from 4 commits
7caf8d4
197a7cf
fa33327
07bdba2
b170d62
295eda3
aef1240
87fa1f7
4230d5b
3f02bf3
427eb8e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,8 +17,7 @@ import ( | |
"errors" | ||
"fmt" | ||
|
||
"github.com/ChainSafe/gossamer/lib/common/optional" | ||
"github.com/ChainSafe/gossamer/lib/scale" | ||
"github.com/ChainSafe/gossamer/pkg/scale" | ||
) | ||
|
||
var ( | ||
|
@@ -81,88 +80,220 @@ func (e TransactionValidityError) Error() string { | |
return fmt.Sprintf("transaction validity error: %s", e.msg) | ||
} | ||
|
||
func determineCustomModuleErr(res []byte) error { | ||
if len(res) < 3 { | ||
return errInvalidResult | ||
} | ||
errMsg, err := optional.NewBytes(false, nil).DecodeBytes(res[2:]) | ||
if err != nil { | ||
return err | ||
} | ||
return fmt.Errorf("index: %d code: %d message: %s", res[0], res[1], errMsg.String()) | ||
// A UnmarshalError is when unmarshalling fails | ||
type UnmarshalError struct { | ||
msg string | ||
} | ||
|
||
func determineDispatchErr(res []byte) error { | ||
switch res[0] { | ||
case 0: | ||
unKnownError, _ := scale.Decode(res[1:], []byte{}) | ||
return &DispatchOutcomeError{fmt.Sprintf("unknown error: %s", string(unKnownError.([]byte)))} | ||
case 1: | ||
return &DispatchOutcomeError{"failed lookup"} | ||
case 2: | ||
return &DispatchOutcomeError{"bad origin"} | ||
case 3: | ||
return &DispatchOutcomeError{fmt.Sprintf("custom module error: %s", determineCustomModuleErr(res[1:]))} | ||
} | ||
return errInvalidResult | ||
func (e UnmarshalError) Error() string { | ||
return fmt.Sprintf("unmarshal error: %s", e.msg) | ||
} | ||
|
||
// Other Some error occurred | ||
type Other string | ||
|
||
// Index Returns VDT index | ||
func (err Other) Index() uint { return 0 } | ||
|
||
// CannotLookup Failed to lookup some data | ||
type CannotLookup struct{} | ||
|
||
// Index Returns VDT index | ||
func (err CannotLookup) Index() uint { return 1 } | ||
|
||
// BadOrigin A bad origin | ||
type BadOrigin struct{} | ||
|
||
// Index Returns VDT index | ||
func (err BadOrigin) Index() uint { return 2 } | ||
|
||
// Module A custom error in a module | ||
type Module struct { | ||
Idx uint8 | ||
Err uint8 | ||
Message *string | ||
} | ||
|
||
func determineInvalidTxnErr(res []byte) error { | ||
switch res[0] { | ||
case 0: | ||
// Index Returns VDT index | ||
func (err Module) Index() uint { return 3 } | ||
|
||
func (err Module) string() string { | ||
return fmt.Sprintf("index: %d code: %d message: %x", err.Idx, err.Err, *err.Message) | ||
} | ||
|
||
// ValidityCannotLookup Could not lookup some information that is required to validate the transaction | ||
type ValidityCannotLookup struct{} | ||
|
||
// Index Returns VDT index | ||
func (err ValidityCannotLookup) Index() uint { return 0 } | ||
|
||
// NoUnsignedValidator No validator found for the given unsigned transaction | ||
type NoUnsignedValidator struct{} | ||
|
||
// Index Returns VDT index | ||
func (err NoUnsignedValidator) Index() uint { return 1 } | ||
|
||
// UnknownCustom Any other custom unknown validity that is not covered | ||
type UnknownCustom uint8 | ||
|
||
// Index Returns VDT index | ||
func (err UnknownCustom) Index() uint { return 2 } | ||
|
||
// Call The call of the transaction is not expected | ||
type Call struct{} | ||
|
||
// Index Returns VDT index | ||
func (err Call) Index() uint { return 0 } | ||
|
||
// Payment General error to do with the inability to pay some fees (e.g. account balance too low) | ||
type Payment struct{} | ||
|
||
// Index Returns VDT index | ||
func (err Payment) Index() uint { return 1 } | ||
|
||
// Future General error to do with the transaction not yet being valid (e.g. nonce too high) | ||
type Future struct{} | ||
|
||
// Index Returns VDT index | ||
func (err Future) Index() uint { return 2 } | ||
|
||
// Stale General error to do with the transaction being outdated (e.g. nonce too low) | ||
type Stale struct{} | ||
|
||
// Index Returns VDT index | ||
func (err Stale) Index() uint { return 3 } | ||
|
||
// BadProof General error to do with the transaction’s proofs (e.g. signature) | ||
type BadProof struct{} | ||
|
||
// Index Returns VDT index | ||
func (err BadProof) Index() uint { return 4 } | ||
|
||
// AncientBirthBlock The transaction birth block is ancient | ||
type AncientBirthBlock struct{} | ||
|
||
// Index Returns VDT index | ||
func (err AncientBirthBlock) Index() uint { return 5 } | ||
|
||
// ExhaustsResources The transaction would exhaust the resources of current block | ||
type ExhaustsResources struct{} | ||
|
||
// Index Returns VDT index | ||
func (err ExhaustsResources) Index() uint { return 6 } | ||
|
||
// InvalidCustom Any other custom invalid validity that is not covered | ||
type InvalidCustom uint8 | ||
|
||
// Index Returns VDT index | ||
func (err InvalidCustom) Index() uint { return 7 } | ||
|
||
// BadMandatory An extrinsic with a Mandatory dispatch resulted in Error | ||
type BadMandatory struct{} | ||
|
||
// Index Returns VDT index | ||
func (err BadMandatory) Index() uint { return 8 } | ||
|
||
// MandatoryDispatch A transaction with a mandatory dispatch | ||
type MandatoryDispatch struct{} | ||
|
||
// Index Returns VDT index | ||
func (err MandatoryDispatch) Index() uint { return 9 } | ||
|
||
func determineErrType(vdt scale.VaryingDataType) error { | ||
switch val := vdt.Value().(type) { | ||
case Other: | ||
return &DispatchOutcomeError{fmt.Sprintf("unknown error: %s", val)} | ||
case CannotLookup: | ||
return &DispatchOutcomeError{"failed lookup"} | ||
case BadOrigin: | ||
return &DispatchOutcomeError{"bad origin"} | ||
case Module: | ||
return &DispatchOutcomeError{fmt.Sprintf("custom module error: %s", val.string())} | ||
case Call: | ||
return &TransactionValidityError{"call of the transaction is not expected"} | ||
case 1: | ||
case Payment: | ||
return &TransactionValidityError{"invalid payment"} | ||
case 2: | ||
case Future: | ||
return &TransactionValidityError{"invalid transaction"} | ||
case 3: | ||
case Stale: | ||
return &TransactionValidityError{"outdated transaction"} | ||
case 4: | ||
case BadProof: | ||
return &TransactionValidityError{"bad proof"} | ||
case 5: | ||
case AncientBirthBlock: | ||
return &TransactionValidityError{"ancient birth block"} | ||
case 6: | ||
case ExhaustsResources: | ||
return &TransactionValidityError{"exhausts resources"} | ||
case 7: | ||
return &TransactionValidityError{fmt.Sprintf("unknown error: %d", res[1])} | ||
case 8: | ||
case InvalidCustom: | ||
return &TransactionValidityError{fmt.Sprintf("unknown error: %d", val)} | ||
case BadMandatory: | ||
return &TransactionValidityError{"mandatory dispatch error"} | ||
case 9: | ||
case MandatoryDispatch: | ||
return &TransactionValidityError{"invalid mandatory dispatch"} | ||
} | ||
return errInvalidResult | ||
} | ||
|
||
func determineUnknownTxnErr(res []byte) error { | ||
switch res[0] { | ||
case 0: | ||
case ValidityCannotLookup: | ||
return &TransactionValidityError{"lookup failed"} | ||
case 1: | ||
case NoUnsignedValidator: | ||
return &TransactionValidityError{"validator not found"} | ||
case 2: | ||
return &TransactionValidityError{fmt.Sprintf("unknown error: %d", res[1])} | ||
case UnknownCustom: | ||
return &TransactionValidityError{fmt.Sprintf("unknown error: %d", val)} | ||
} | ||
|
||
return errInvalidResult | ||
} | ||
|
||
func determineErr(res []byte) error { | ||
switch res[0] { | ||
case 0: // DispatchOutcome | ||
switch res[1] { | ||
case 0: | ||
return nil | ||
case 1: | ||
return determineDispatchErr(res[2:]) | ||
var other Other | ||
var invalidCustom InvalidCustom | ||
var unknownCustom UnknownCustom | ||
|
||
dispatchError := scale.MustNewVaryingDataType(other, CannotLookup{}, BadOrigin{}, Module{}) | ||
invalid := scale.MustNewVaryingDataType(Call{}, Payment{}, Future{}, Stale{}, BadProof{}, AncientBirthBlock{}, | ||
ExhaustsResources{}, invalidCustom, BadMandatory{}, MandatoryDispatch{}) | ||
unknown := scale.MustNewVaryingDataType(ValidityCannotLookup{}, NoUnsignedValidator{}, unknownCustom) | ||
|
||
okRes := scale.NewResult(nil, dispatchError) | ||
errRes := scale.NewResult(invalid, unknown) | ||
result := scale.NewResult(okRes, errRes) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think these could be declared as package vars since they wouldn't ever change? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yup you are right, will do. I will just have to declare the custom string types there as well (like other and invalidCustom) |
||
|
||
err := scale.Unmarshal(res, &result) | ||
if err != nil { | ||
return &UnmarshalError{err.Error()} | ||
} | ||
|
||
ok, err := result.Unwrap() | ||
if err != nil { | ||
switch o := err.(type) { | ||
case scale.WrappedErr: | ||
errResult := o.Err.(scale.Result) | ||
ok, err = errResult.Unwrap() | ||
if err != nil { | ||
switch err := err.(type) { | ||
case scale.WrappedErr: | ||
return determineErrType(err.Err.(scale.VaryingDataType)) | ||
default: | ||
return errInvalidResult | ||
} | ||
} else { | ||
return determineErrType(ok.(scale.VaryingDataType)) | ||
} | ||
default: | ||
return errInvalidResult | ||
} | ||
case 1: // TransactionValidityError | ||
switch res[1] { | ||
case 0: | ||
return determineInvalidTxnErr(res[2:]) | ||
case 1: | ||
return determineUnknownTxnErr(res[2:]) | ||
} else { | ||
switch o := ok.(type) { | ||
case scale.Result: | ||
_, err = o.Unwrap() | ||
if err != nil { | ||
switch err := err.(type) { | ||
case scale.WrappedErr: | ||
return determineErrType(err.Err.(scale.VaryingDataType)) | ||
default: | ||
return errInvalidResult | ||
} | ||
} else { | ||
return nil | ||
} | ||
default: | ||
return errInvalidResult | ||
} | ||
} | ||
return errInvalidResult | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.