Skip to content
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

refactor: implement error interface and improve error resolving #295

Merged
merged 10 commits into from
Nov 23, 2023
18 changes: 8 additions & 10 deletions api/block_builder/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,18 +67,16 @@ func (m Module) ApplyExtrinsic(dataPtr int32, dataLen int32) int64 {
log.Critical(err.Error())
}

ok, errApplyExtr := m.executive.ApplyExtrinsic(uxt)
ok, err := m.executive.ApplyExtrinsic(uxt)
var applyExtrinsicResult primitives.ApplyExtrinsicResult
if errApplyExtr != nil {
applyExtrinsicResult, err = primitives.NewApplyExtrinsicResult(errApplyExtr)
if err != nil {
log.Critical(err.Error())
}
} else {
switch err.(type) {
case primitives.TransactionValidityError:
applyExtrinsicResult, err = primitives.NewApplyExtrinsicResult(err.(primitives.TransactionValidityError))
case nil:
applyExtrinsicResult, err = primitives.NewApplyExtrinsicResult(ok)
if err != nil {
log.Critical(err.Error())
}
}
if err != nil {
log.Critical(err.Error())
}

buffer.Reset()
Expand Down
27 changes: 25 additions & 2 deletions api/block_builder/module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package blockbuilder

import (
"bytes"
"errors"
"io"
"testing"

Expand Down Expand Up @@ -80,8 +81,8 @@ func Test_Module_ApplyExtrinsic_Fails(t *testing.T) {
bufferUxt := bytes.NewBuffer(bUxt)
outcome, err := primitives.NewDispatchOutcome(sc.Empty{})
assert.Nil(t, err)
validityError, err := primitives.NewTransactionValidityError(primitives.NewInvalidTransactionStale())
assert.Nil(t, err)
validityError, ok := primitives.NewTransactionValidityError(primitives.NewInvalidTransactionStale()).(primitives.TransactionValidityError)
assert.True(t, ok)
applyExtrinsicResultValidityErr, err := primitives.NewApplyExtrinsicResult(validityError)
assert.Nil(t, err)
bExtrinsicResult := applyExtrinsicResultValidityErr.Bytes()
Expand All @@ -100,6 +101,28 @@ func Test_Module_ApplyExtrinsic_Fails(t *testing.T) {
mockMemoryUtils.AssertCalled(t, "BytesToOffsetAndSize", bExtrinsicResult)
}

func Test_Module_ApplyExtrinsic_Panics(t *testing.T) {
target := setup()

bufferUxt := bytes.NewBuffer(bUxt)
outcome, err := primitives.NewDispatchOutcome(sc.Empty{})
assert.Nil(t, err)
expectedErr := errors.New("panic")

mockMemoryUtils.On("GetWasmMemorySlice", dataPtr, dataLen).Return(bUxt)
mockRuntimeDecoder.On("DecodeUncheckedExtrinsic", bufferUxt).Return(uxt, nil)
mockExecutive.On("ApplyExtrinsic", uxt).Return(outcome, expectedErr)

assert.PanicsWithValue(t,
expectedErr.Error(),
func() { target.ApplyExtrinsic(dataPtr, dataLen) },
)

mockMemoryUtils.AssertCalled(t, "GetWasmMemorySlice", dataPtr, dataLen)
mockRuntimeDecoder.AssertExpectations(t)
mockExecutive.AssertCalled(t, "ApplyExtrinsic", uxt)
}

func Test_Module_FinalizeBlock(t *testing.T) {
target := setup()

Expand Down
19 changes: 8 additions & 11 deletions api/tagged_transaction_queue/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,19 +69,16 @@ func (m Module) ValidateTransaction(dataPtr int32, dataLen int32) int64 {
log.Critical(err.Error())
}

ok, errTx := m.executive.ValidateTransaction(txSource, tx, blockHash)

ok, err := m.executive.ValidateTransaction(txSource, tx, blockHash)
var res primitives.TransactionValidityResult
if errTx != nil {
res, err = primitives.NewTransactionValidityResult(errTx)
if err != nil {
log.Critical(err.Error())
}
} else {
switch err.(type) {
case primitives.TransactionValidityError:
res, err = primitives.NewTransactionValidityResult(err.(primitives.TransactionValidityError))
case nil:
res, err = primitives.NewTransactionValidityResult(ok)
if err != nil {
log.Critical(err.Error())
}
}
if err != nil {
log.Critical(err.Error())
}

return m.memUtils.BytesToOffsetAndSize(res.Bytes())
Expand Down
30 changes: 28 additions & 2 deletions api/tagged_transaction_queue/module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package tagged_transaction_queue

import (
"bytes"
"errors"
"testing"

"github.com/ChainSafe/gossamer/lib/common"
Expand All @@ -24,9 +25,9 @@ var (
)}

validTx = primitives.DefaultValidTransaction()
txValidityError, _ = primitives.NewTransactionValidityError(primitives.NewInvalidTransactionStale())
txValidityError = primitives.NewTransactionValidityError(primitives.NewInvalidTransactionStale())
validitySuccessResult, _ = primitives.NewTransactionValidityResult(validTx)
validityFailResult, _ = primitives.NewTransactionValidityResult(txValidityError)
validityFailResult, _ = primitives.NewTransactionValidityResult(txValidityError.(primitives.TransactionValidityError))
)

var (
Expand Down Expand Up @@ -100,6 +101,31 @@ func Test_Module_ValidateTransaction_Fails(t *testing.T) {
mockMemoryUtils.AssertCalled(t, "BytesToOffsetAndSize", validityFailResult.Bytes())
}

func Test_Module_ValidateTransaction_Panics(t *testing.T) {
target := setup()

data := append(txSource.Bytes(), blockHash.Bytes()...)
expectBuffer := bytes.NewBuffer(data)
_, err := expectBuffer.ReadByte()
assert.Nil(t, err)

expectedErr := errors.New("panic")

mockMemoryUtils.On("GetWasmMemorySlice", dataPtr, dataLen).Return(data)
mockRuntimeDecoder.On("DecodeUncheckedExtrinsic", expectBuffer).Return(mockUxt, nil)
mockExecutive.On("ValidateTransaction", txSource, mockUxt, blockHash).
Return(primitives.ValidTransaction{}, expectedErr)

assert.PanicsWithValue(t,
expectedErr.Error(),
func() { target.ValidateTransaction(dataPtr, dataLen) },
)

mockMemoryUtils.AssertCalled(t, "GetWasmMemorySlice", dataPtr, dataLen)
mockRuntimeDecoder.AssertExpectations(t)
mockExecutive.AssertCalled(t, "ValidateTransaction", txSource, mockUxt, blockHash)
}

func Test_Module_Metadata(t *testing.T) {
target := setup()

Expand Down
Binary file modified build/runtime.wasm
Binary file not shown.
11 changes: 3 additions & 8 deletions execution/extrinsic/unsigned_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package extrinsic

import (
sc "github.com/LimeChain/goscale"
"github.com/LimeChain/gosemble/primitives/log"
primitives "github.com/LimeChain/gosemble/primitives/types"
)

Expand All @@ -18,7 +17,7 @@ func NewUnsignedValidatorForChecked(extrinsic RuntimeExtrinsic) primitives.Unsig

// PreDispatch validates the dispatch call before execution.
// Inherent call is accepted for being dispatched
func (v UnsignedValidatorForChecked) PreDispatch(call primitives.Call) (sc.Empty, primitives.TransactionValidityError) {
func (v UnsignedValidatorForChecked) PreDispatch(call primitives.Call) (sc.Empty, error) {
module, ok := v.runtimeExtrinsic.Module(call.ModuleIndex())
if !ok {
return sc.Empty{}, nil
Expand All @@ -29,14 +28,10 @@ func (v UnsignedValidatorForChecked) PreDispatch(call primitives.Call) (sc.Empty

// ValidateUnsigned returns the validity of the dispatch call.
// Inherent call is not validated as unsigned
func (v UnsignedValidatorForChecked) ValidateUnsigned(txSource primitives.TransactionSource, call primitives.Call) (primitives.ValidTransaction, primitives.TransactionValidityError) {
func (v UnsignedValidatorForChecked) ValidateUnsigned(txSource primitives.TransactionSource, call primitives.Call) (primitives.ValidTransaction, error) {
module, ok := v.runtimeExtrinsic.Module(call.ModuleIndex())
if !ok {
unknownTransactionNoUnsignedValidator, err := primitives.NewTransactionValidityError(primitives.NewUnknownTransactionNoUnsignedValidator())
if err != nil {
log.Critical(err.Error())
}
return primitives.ValidTransaction{}, unknownTransactionNoUnsignedValidator
return primitives.ValidTransaction{}, primitives.NewTransactionValidityError(primitives.NewUnknownTransactionNoUnsignedValidator())
}

return module.ValidateUnsigned(txSource, call)
Expand Down
6 changes: 3 additions & 3 deletions execution/extrinsic/unsigned_validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ var (
)

var (
expectedInvalidTransactionStaleErr, _ = primitives.NewTransactionValidityError(primitives.NewInvalidTransactionStale())
expectedUnknownTransactionNoUnsignedValidatorErr, _ = primitives.NewTransactionValidityError(primitives.NewUnknownTransactionNoUnsignedValidator())
expectInvalidTransactionPaymentErr, _ = primitives.NewTransactionValidityError(primitives.NewInvalidTransactionPayment())
expectedInvalidTransactionStaleErr = primitives.NewTransactionValidityError(primitives.NewInvalidTransactionStale())
expectedUnknownTransactionNoUnsignedValidatorErr = primitives.NewTransactionValidityError(primitives.NewUnknownTransactionNoUnsignedValidator())
expectInvalidTransactionPaymentErr = primitives.NewTransactionValidityError(primitives.NewInvalidTransactionPayment())
)

var (
Expand Down
4 changes: 2 additions & 2 deletions execution/types/checked_extrinsic.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func (c checkedExtrinsic) Function() primitives.Call {
return c.function
}

func (c checkedExtrinsic) Apply(validator primitives.UnsignedValidator, info *primitives.DispatchInfo, length sc.Compact) (primitives.DispatchResultWithPostInfo[primitives.PostDispatchInfo], primitives.TransactionValidityError) {
func (c checkedExtrinsic) Apply(validator primitives.UnsignedValidator, info *primitives.DispatchInfo, length sc.Compact) (primitives.DispatchResultWithPostInfo[primitives.PostDispatchInfo], error) {
var (
maybeWho sc.Option[primitives.AccountId[primitives.PublicKey]]
maybePre sc.Option[sc.Sequence[primitives.Pre]]
Expand Down Expand Up @@ -100,7 +100,7 @@ func (c checkedExtrinsic) Apply(validator primitives.UnsignedValidator, info *pr
return resWithInfo, c.extra.PostDispatch(maybePre, info, &postInfo, length, &dispatchResult)
}

func (c checkedExtrinsic) Validate(validator primitives.UnsignedValidator, source primitives.TransactionSource, info *primitives.DispatchInfo, length sc.Compact) (primitives.ValidTransaction, primitives.TransactionValidityError) {
func (c checkedExtrinsic) Validate(validator primitives.UnsignedValidator, source primitives.TransactionSource, info *primitives.DispatchInfo, length sc.Compact) (primitives.ValidTransaction, error) {
if c.signer.HasValue {
id := c.signer.Value
return c.extra.Validate(id, c.function, info, length)
Expand Down
26 changes: 13 additions & 13 deletions execution/types/checked_extrinsic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,16 @@ var (
)

var (
expectedInvalidTransactionStaleErr, _ = types.NewTransactionValidityError(types.NewInvalidTransactionStale())
expectedInvalidTransactionPaymentErr, _ = types.NewTransactionValidityError(types.NewInvalidTransactionPayment())
expectedUnknownTransactionNoUnsignedValidatorErr, _ = types.NewTransactionValidityError(types.NewUnknownTransactionNoUnsignedValidator())
expectedInvalidTransactionStaleErr = types.NewTransactionValidityError(types.NewInvalidTransactionStale())
expectedInvalidTransactionPaymentErr = types.NewTransactionValidityError(types.NewInvalidTransactionPayment())
expectedUnknownTransactionNoUnsignedValidatorErr = types.NewTransactionValidityError(types.NewUnknownTransactionNoUnsignedValidator())
)

var (
mockTransactional *mocks.IoTransactional[types.PostDispatchInfo, types.DispatchError]
mockUnsignedValidator *mocks.UnsignedValidator

mockWithStorageLayer = mock.AnythingOfType("func() (types.PostDispatchInfo, goscale.VaryingData)")
mockWithStorageLayer = mock.AnythingOfType("func() (types.PostDispatchInfo, types.DispatchError)")
)

func Test_CheckedExtrinsic_Function(t *testing.T) {
Expand All @@ -72,7 +72,7 @@ func Test_CheckedExtrinsic_Apply_Signed_Success(t *testing.T) {
mockTransactional.On("WithStorageLayer", mockWithStorageLayer).Return(postDispatchInfo, nil)
mockSignedExtra.
On("PostDispatch", optionPre, dispatchInfo, &postDispatchInfo, length, &dispatchResult).
Return(types.TransactionValidityError(nil))
Return(nil)

result, err := target.Apply(mockUnsignedValidator, dispatchInfo, length)

Expand Down Expand Up @@ -119,7 +119,7 @@ func Test_CheckedExtrinsic_Apply_Signed_WithStorageLayerErr(t *testing.T) {
mockTransactional.On("WithStorageLayer", mockWithStorageLayer).Return(errPostDispatchInfo.PostInfo, errPostDispatchInfo.Error)
mockSignedExtra.
On("PostDispatch", optionPre, dispatchInfo, &errPostDispatchInfo.PostInfo, length, &dispatchResult).
Return(types.TransactionValidityError(nil))
Return(nil)

result, err := target.Apply(mockUnsignedValidator, dispatchInfo, length)

Expand Down Expand Up @@ -201,12 +201,12 @@ func Test_CheckedExtrinsic_Apply_Unsigned_Success(t *testing.T) {

mockSignedExtra.
On("PreDispatchUnsigned", mockCall, dispatchInfo, length).
Return(types.TransactionValidityError(nil))
Return(nil)
mockUnsignedValidator.On("PreDispatch", mockCall).Return(sc.Empty{}, nil)
mockTransactional.On("WithStorageLayer", mockWithStorageLayer).Return(postDispatchInfo, nil)
mockSignedExtra.
On("PostDispatch", emptyOptionPre, dispatchInfo, &postDispatchInfo, length, &dispatchResult).
Return(types.TransactionValidityError(nil))
Return(nil)

result, err := target.Apply(mockUnsignedValidator, dispatchInfo, length)

Expand Down Expand Up @@ -246,7 +246,7 @@ func Test_CheckedExtrinsic_Apply_Unsigned_PreDispatch_Fails(t *testing.T) {

mockSignedExtra.
On("PreDispatchUnsigned", mockCall, dispatchInfo, length).
Return(types.TransactionValidityError(nil))
Return(nil)
mockUnsignedValidator.On("PreDispatch", mockCall).Return(sc.Empty{}, expectedInvalidTransactionStaleErr)

result, err := target.Apply(mockUnsignedValidator, dispatchInfo, length)
Expand All @@ -271,12 +271,12 @@ func Test_CheckedExtrinsic_Apply_Unsigned_WithStorageLayerErr(t *testing.T) {

mockSignedExtra.
On("PreDispatchUnsigned", mockCall, dispatchInfo, length).
Return(types.TransactionValidityError(nil))
Return(nil)
mockUnsignedValidator.On("PreDispatch", mockCall).Return(sc.Empty{}, nil)
mockTransactional.On("WithStorageLayer", mockWithStorageLayer).Return(errPostDispatchInfo.PostInfo, errPostDispatchInfo.Error)
mockSignedExtra.
On("PostDispatch", emptyOptionPre, dispatchInfo, &errPostDispatchInfo.PostInfo, length, &dispatchResult).
Return(types.TransactionValidityError(nil))
Return(nil)

result, err := target.Apply(mockUnsignedValidator, dispatchInfo, length)

Expand All @@ -303,7 +303,7 @@ func Test_CheckedExtrinsic_Apply_Unsigned_WithStorageLayerErr_PostDispatch_Fails

mockSignedExtra.
On("PreDispatchUnsigned", mockCall, dispatchInfo, length).
Return(types.TransactionValidityError(nil))
Return(nil)
mockUnsignedValidator.On("PreDispatch", mockCall).Return(sc.Empty{}, nil)
mockTransactional.On("WithStorageLayer", mockWithStorageLayer).Return(errPostDispatchInfo.PostInfo, errPostDispatchInfo.Error)
mockSignedExtra.
Expand Down Expand Up @@ -334,7 +334,7 @@ func Test_CheckedExtrinsic_Apply_Unsigned_PostDispatch_Fails(t *testing.T) {

mockSignedExtra.
On("PreDispatchUnsigned", mockCall, dispatchInfo, length).
Return(types.TransactionValidityError(nil))
Return(nil)
mockUnsignedValidator.On("PreDispatch", mockCall).Return(sc.Empty{}, nil)
mockTransactional.On("WithStorageLayer", mockWithStorageLayer).Return(postDispatchInfo, nil)
mockSignedExtra.
Expand Down
8 changes: 3 additions & 5 deletions execution/types/unchecked_extrinsic.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const (
)

type PayloadInitializer = func(call primitives.Call, extra primitives.SignedExtra) (
primitives.SignedPayload, primitives.TransactionValidityError,
primitives.SignedPayload, error,
)

type uncheckedExtrinsic struct {
Expand Down Expand Up @@ -107,7 +107,7 @@ func (uxt uncheckedExtrinsic) IsSigned() bool {
return bool(uxt.signature.HasValue)
}

func (uxt uncheckedExtrinsic) Check() (primitives.CheckedExtrinsic, primitives.TransactionValidityError) {
func (uxt uncheckedExtrinsic) Check() (primitives.CheckedExtrinsic, error) {
if uxt.signature.HasValue {
signer, signature, extra := uxt.signature.Value.Signer, uxt.signature.Value.Signature, uxt.signature.Value.Extra

Expand All @@ -122,9 +122,7 @@ func (uxt uncheckedExtrinsic) Check() (primitives.CheckedExtrinsic, primitives.T
}

if !uxt.verify(signature, uxt.usingEncoded(rawPayload), signerAddress) {
// https://github.com/LimeChain/gosemble/issues/271
invalidTransactionBadProof, _ := primitives.NewTransactionValidityError(primitives.NewInvalidTransactionBadProof())
return nil, invalidTransactionBadProof
return nil, primitives.NewTransactionValidityError(primitives.NewInvalidTransactionBadProof())
}

return NewCheckedExtrinsic(sc.NewOption[primitives.AccountId[primitives.PublicKey]](signerAddress), uxt.function, extra), nil
Expand Down
8 changes: 4 additions & 4 deletions execution/types/unchecked_extrinsic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ const (
)

var (
unknownTransactionCannotLookupError, _ = types.NewTransactionValidityError(
unknownTransactionCannotLookupError = types.NewTransactionValidityError(
types.NewUnknownTransactionCannotLookup(),
)
invalidTransactionAncientBirthBlockError, _ = types.NewTransactionValidityError(
invalidTransactionAncientBirthBlockError = types.NewTransactionValidityError(
types.NewInvalidTransactionAncientBirthBlock(),
)
invalidTransactionBadProofError, _ = types.NewTransactionValidityError(
invalidTransactionBadProofError = types.NewTransactionValidityError(
types.NewInvalidTransactionBadProof(),
)

Expand Down Expand Up @@ -110,7 +110,7 @@ func newTestSignedExtrinsic(
crypto io.Crypto,
hashing io.Hashing) uncheckedExtrinsic {

initializer := func(call types.Call, extra types.SignedExtra) (types.SignedPayload, types.TransactionValidityError) {
initializer := func(call types.Call, extra types.SignedExtra) (types.SignedPayload, error) {
return signedPayload, nil
}

Expand Down
8 changes: 3 additions & 5 deletions frame/aura/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,12 @@ func (m Module) Functions() map[sc.U8]primitives.Call {
return map[sc.U8]primitives.Call{}
}

func (m Module) PreDispatch(_ primitives.Call) (sc.Empty, primitives.TransactionValidityError) {
func (m Module) PreDispatch(_ primitives.Call) (sc.Empty, error) {
return sc.Empty{}, nil
}

func (m Module) ValidateUnsigned(_ primitives.TransactionSource, _ primitives.Call) (primitives.ValidTransaction, primitives.TransactionValidityError) {
// TODO https://github.com/LimeChain/gosemble/issues/271
unknownTransactionNoUnsignedValidator, _ := primitives.NewTransactionValidityError(primitives.NewUnknownTransactionNoUnsignedValidator())
return primitives.ValidTransaction{}, unknownTransactionNoUnsignedValidator
func (m Module) ValidateUnsigned(_ primitives.TransactionSource, _ primitives.Call) (primitives.ValidTransaction, error) {
return primitives.ValidTransaction{}, primitives.NewTransactionValidityError(primitives.NewUnknownTransactionNoUnsignedValidator())
}

func (m Module) KeyType() primitives.PublicKeyType {
Expand Down
2 changes: 1 addition & 1 deletion frame/aura/module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const (
)

var (
unknownTransactionNoUnsignedValidator, _ = types.NewTransactionValidityError(types.NewUnknownTransactionNoUnsignedValidator())
unknownTransactionNoUnsignedValidator = types.NewTransactionValidityError(types.NewUnknownTransactionNoUnsignedValidator())
)

var (
Expand Down
Loading