From a1bca659dd7d14216f274694aa073567e470916d Mon Sep 17 00:00:00 2001 From: Radosvet M Date: Tue, 17 Oct 2023 12:20:13 +0300 Subject: [PATCH] test(execution/types): unchecked extrinsic (#245) * test(execution/types): unchecked extrinsic --- execution/types/unchecked_extrinsic.go | 45 +-- execution/types/unchecked_extrinsic_test.go | 351 ++++++++++++++++++ mocks/account_id_lookup.go | 20 + mocks/call.go | 1 - mocks/signed_extra.go | 5 +- mocks/signed_payload.go | 42 +++ .../types/extrinsic_signature_payload.go | 61 ++- primitives/types/lookup.go | 20 +- 8 files changed, 493 insertions(+), 52 deletions(-) create mode 100644 execution/types/unchecked_extrinsic_test.go create mode 100644 mocks/account_id_lookup.go create mode 100644 mocks/signed_payload.go diff --git a/execution/types/unchecked_extrinsic.go b/execution/types/unchecked_extrinsic.go index bff4d594..45ebb7e8 100644 --- a/execution/types/unchecked_extrinsic.go +++ b/execution/types/unchecked_extrinsic.go @@ -20,31 +20,31 @@ const ( ExtrinsicUnmaskVersion = 0b0111_1111 ) +type PayloadInitializer = func(call primitives.Call, extra primitives.SignedExtra) ( + primitives.SignedPayload, primitives.TransactionValidityError, +) + type uncheckedExtrinsic struct { version sc.U8 // The signature, address, number of extrinsics have come before from // the same signer and an era describing the longevity of this transaction, // if this is a signed extrinsic. - signature sc.Option[primitives.ExtrinsicSignature] - function primitives.Call - extra primitives.SignedExtra - crypto io.Crypto + signature sc.Option[primitives.ExtrinsicSignature] + function primitives.Call + extra primitives.SignedExtra + initializePayload PayloadInitializer + crypto io.Crypto } // NewUncheckedExtrinsic returns a new instance of an unchecked extrinsic. -func NewUncheckedExtrinsic( - version sc.U8, - signature sc.Option[primitives.ExtrinsicSignature], - function primitives.Call, - extra primitives.SignedExtra, -) uncheckedExtrinsic { - +func NewUncheckedExtrinsic(version sc.U8, signature sc.Option[primitives.ExtrinsicSignature], function primitives.Call, extra primitives.SignedExtra) primitives.UncheckedExtrinsic { return uncheckedExtrinsic{ - version: version, - signature: signature, - function: function, - extra: extra, - crypto: io.NewCrypto(), + version: version, + signature: signature, + function: function, + extra: extra, + initializePayload: primitives.NewSignedPayload, + crypto: io.NewCrypto(), } } @@ -57,6 +57,7 @@ func NewUnsignedUncheckedExtrinsic(function primitives.Call) primitives.Unchecke crypto: io.NewCrypto(), } } + func (uxt uncheckedExtrinsic) Encode(buffer *bytes.Buffer) { tempBuffer := &bytes.Buffer{} @@ -95,21 +96,21 @@ func (uxt uncheckedExtrinsic) Check(lookup primitives.AccountIdLookup) (sc.Optio if uxt.signature.HasValue { signer, signature, extra := uxt.signature.Value.Signer, uxt.signature.Value.Signature, uxt.signature.Value.Extra - signedAddress, err := lookup.Lookup(signer) + signerAddress, err := lookup.Lookup(signer) if err != nil { return sc.NewOption[primitives.Address32](nil), err } - rawPayload, err := primitives.NewSignedPayload(uxt.function, extra) + rawPayload, err := uxt.initializePayload(uxt.function, extra) if err != nil { return sc.NewOption[primitives.Address32](nil), err } - if !uxt.verify(signature, rawPayload.UsingEncoded(), signedAddress) { + if !uxt.verify(signature, rawPayload.UsingEncoded(), signerAddress) { return sc.NewOption[primitives.Address32](nil), primitives.NewTransactionValidityError(primitives.NewInvalidTransactionBadProof()) } - return sc.NewOption[primitives.Address32](signedAddress), nil + return sc.NewOption[primitives.Address32](signerAddress), nil } return sc.NewOption[primitives.Address32](nil), nil @@ -126,8 +127,8 @@ func (uxt uncheckedExtrinsic) verify(signature primitives.MultiSignature, msg sc sigBytes := sc.FixedSequenceU8ToBytes(signature.AsSr25519().H512.FixedSequence) return uxt.crypto.Sr25519Verify(sigBytes, msgBytes, signerBytes) } else if signature.IsEcdsa() { - // TODO: return true + // TODO: // let m = sp_io::hashing::blake2_256(msg.get()); // match sp_io::crypto::secp256k1_ecdsa_recover_compressed(sig.as_ref(), &m) { // Ok(pubkey) => @@ -136,6 +137,8 @@ func (uxt uncheckedExtrinsic) verify(signature primitives.MultiSignature, msg sc // _ => false, // } } + log.Critical("invalid MultiSignature type in Verify") + panic("unreachable") } diff --git a/execution/types/unchecked_extrinsic_test.go b/execution/types/unchecked_extrinsic_test.go new file mode 100644 index 00000000..fa261da4 --- /dev/null +++ b/execution/types/unchecked_extrinsic_test.go @@ -0,0 +1,351 @@ +package types + +import ( + "bytes" + "testing" + + sc "github.com/LimeChain/goscale" + "github.com/LimeChain/gosemble/mocks" + "github.com/LimeChain/gosemble/primitives/io" + "github.com/LimeChain/gosemble/primitives/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" +) + +const ( + version = sc.U8(5) +) + +var ( + unknownTransactionCannotLookupError = types.NewTransactionValidityError( + types.NewUnknownTransactionCannotLookup(), + ) + invalidTransactionAncientBirthBlockError = types.NewTransactionValidityError( + types.NewInvalidTransactionAncientBirthBlock(), + ) + invalidTransactionBadProofError = types.NewTransactionValidityError( + types.NewInvalidTransactionBadProof(), + ) + + signerAddressBytes = []byte{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + } + signerAddress = types.NewAddress32(sc.BytesToSequenceU8(signerAddressBytes)...) + signer = types.NewMultiAddressId(types.AccountId{Address32: signerAddress}) + + signatureBytes = []byte{ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, + } + signatureEd25519 = types.NewMultiSignatureEd25519( + types.NewEd25519( + sc.BytesToFixedSequenceU8(signatureBytes)..., + ), + ) + signatureSr25519 = types.NewMultiSignatureSr25519( + types.NewSr25519( + sc.BytesToFixedSequenceU8(signatureBytes)..., + ), + ) + + unknownMultisignature = types.MultiSignature{ + VaryingData: sc.NewVaryingData(sc.U8(3), signatureEd25519), + } + + additionalSigned = sc.NewVaryingData( + types.H256{ + FixedSequence: sc.FixedSequence[sc.U8]{ + 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, + 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, + 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, + 0x37, 0x37, + }, + }, + ) + + encodedPayloadBytes = []byte{0x38, 0x38, 0x38} +) + +var ( + targetSigned uncheckedExtrinsic + targetUnsigned uncheckedExtrinsic + + extrinsicSignature sc.Option[types.ExtrinsicSignature] + + mockCall *mocks.Call + mockSignedExtra *mocks.SignedExtra + mockAccountIdLookup *mocks.AccountIdLookup + mocksSignedPayload *mocks.SignedPayload + mockCrypto *mocks.IoCrypto +) + +func setup(signature types.MultiSignature) { + mockCall = new(mocks.Call) + mockSignedExtra = new(mocks.SignedExtra) + mockAccountIdLookup = new(mocks.AccountIdLookup) + mocksSignedPayload = new(mocks.SignedPayload) + mockCrypto = new(mocks.IoCrypto) + + extrinsicSignature = sc.NewOption[types.ExtrinsicSignature]( + types.ExtrinsicSignature{ + Signer: signer, + Signature: signature, + Extra: mockSignedExtra, + }, + ) + + targetUnsigned = newTestUnsignedExtrinsic(mockCall) + + targetSigned = newTestSignedExtrinsic( + extrinsicSignature, + mockCall, + mockSignedExtra, + mocksSignedPayload, + mockCrypto, + ) +} + +func newTestUnsignedExtrinsic(call types.Call) uncheckedExtrinsic { + return NewUnsignedUncheckedExtrinsic(call).(uncheckedExtrinsic) +} + +func newTestSignedExtrinsic( + signature sc.Option[types.ExtrinsicSignature], + call types.Call, + extra types.SignedExtra, + signedPayload types.SignedPayload, + crypto io.Crypto) uncheckedExtrinsic { + + initializer := func(call types.Call, extra types.SignedExtra) (types.SignedPayload, types.TransactionValidityError) { + return signedPayload, nil + } + + uxt := NewUncheckedExtrinsic(version, signature, call, extra).(uncheckedExtrinsic) + uxt.initializePayload = initializer + uxt.crypto = crypto + + return uxt +} + +func Test_Encode_UncheckedExtrinsic_Unsigned(t *testing.T) { + setup(signatureEd25519) + + buffer := &bytes.Buffer{} + mockCall.On("Encode", mock.Anything) + + targetUnsigned.Encode(buffer) + + mockCall.AssertCalled(t, "Encode", mock.Anything) + mockSignedExtra.AssertNotCalled(t, "Encode") + assert.Equal(t, []byte{0x4, 0x4}, buffer.Bytes()) +} + +func Test_Encode_UncheckedExtrinsic_Signed(t *testing.T) { + setup(signatureEd25519) + + buffer := &bytes.Buffer{} + mockCall.On("Encode", mock.Anything) + mockSignedExtra.On("Encode", mock.Anything) + + targetSigned.Encode(buffer) + + mockCall.AssertCalled(t, "Encode", mock.Anything) + mockSignedExtra.AssertCalled(t, "Encode", mock.Anything) + assert.Equal(t, []byte{ + 0x8d, 0x1, // length + 5, // version + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // signer + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, // signature, + // extra + // call + }, buffer.Bytes()) +} + +func Test_Bytes_UncheckedExtrinsic_Unsigned(t *testing.T) { + setup(signatureEd25519) + + mockCall.On("Encode", mock.Anything) + + encoded := targetUnsigned.Bytes() + + mockCall.AssertCalled(t, "Encode", mock.Anything) + assert.Equal(t, []byte{0x4, 0x4}, encoded) +} + +func Test_Bytes_UncheckedExtrinsic_Signed(t *testing.T) { + setup(signatureEd25519) + + mockCall.On("Encode", mock.Anything) + mockSignedExtra.On("Encode", mock.Anything) + + encoded := targetSigned.Bytes() + + mockCall.AssertCalled(t, "Encode", mock.Anything) + mockSignedExtra.AssertCalled(t, "Encode", mock.Anything) + assert.Equal(t, []byte{ + 0x8d, 0x1, // length + 5, // version + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // signer + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, // signature, + // extra + // call + }, encoded) +} + +func Test_Signature(t *testing.T) { + setup(signatureEd25519) + + assert.Equal(t, extrinsicSignature, targetSigned.Signature()) +} + +func Test_Function(t *testing.T) { + setup(signatureEd25519) + + assert.Equal(t, mockCall, targetSigned.Function()) +} + +func Test_Extra(t *testing.T) { + setup(signatureEd25519) + + assert.Equal(t, mockSignedExtra, targetSigned.Extra()) +} + +func Test_IsSigned(t *testing.T) { + setup(signatureEd25519) + + assert.Equal(t, false, targetUnsigned.IsSigned()) + assert.Equal(t, true, targetSigned.IsSigned()) +} + +func Test_Check_UnsignedUncheckedExtrinsic(t *testing.T) { + setup(signatureEd25519) + + lookup := types.DefaultAccountIdLookup() + + signer, err := targetUnsigned.Check(lookup) + + assert.Nil(t, err) + assert.Equal(t, sc.NewOption[types.Address32](nil), signer) +} + +func Test_Check_SignedUncheckedExtrinsic_LookupError(t *testing.T) { + setup(signatureEd25519) + + mockAccountIdLookup.On("Lookup", extrinsicSignature.Value.Signer). + Return(types.Address32{}, unknownTransactionCannotLookupError) + + res, err := targetSigned.Check(mockAccountIdLookup) + + mockAccountIdLookup.AssertCalled(t, "Lookup", extrinsicSignature.Value.Signer) + mockSignedExtra.AssertNotCalled(t, "AdditionalSigned") + mocksSignedPayload.AssertNotCalled(t, "UsingEncoded") + mockCrypto.AssertNotCalled(t, "Ed25519Verify", mock.Anything, mock.Anything, mock.Anything) + assert.Equal(t, unknownTransactionCannotLookupError, err) + assert.Equal(t, sc.NewOption[types.Address32](nil), res) +} + +func Test_Check_SignedUncheckedExtrinsic_AncientBirthBlockError(t *testing.T) { + setup(signatureEd25519) + + targetSigned.initializePayload = types.NewSignedPayload + mockAccountIdLookup.On("Lookup", extrinsicSignature.Value.Signer).Return(signerAddress, nil) + mockSignedExtra.On("AdditionalSigned").Return(types.AdditionalSigned{}, invalidTransactionAncientBirthBlockError) + + res, err := targetSigned.Check(mockAccountIdLookup) + + mockAccountIdLookup.AssertCalled(t, "Lookup", extrinsicSignature.Value.Signer) + mockSignedExtra.AssertCalled(t, "AdditionalSigned") + mocksSignedPayload.AssertNotCalled(t, "UsingEncoded") + mockCrypto.AssertNotCalled(t, "Ed25519Verify", mock.Anything, mock.Anything, mock.Anything) + assert.Equal(t, invalidTransactionAncientBirthBlockError, err) + assert.Equal(t, sc.NewOption[types.Address32](nil), res) +} + +func Test_Check_SignedUncheckedExtrinsic_BadProofError(t *testing.T) { + setup(signatureEd25519) + + mockAccountIdLookup.On("Lookup", extrinsicSignature.Value.Signer).Return(signerAddress, nil) + mocksSignedPayload.On("UsingEncoded").Return(sc.BytesToSequenceU8(encodedPayloadBytes)) + mockCrypto.On("Ed25519Verify", signatureBytes, encodedPayloadBytes, signerAddressBytes).Return(false) + + res, err := targetSigned.Check(mockAccountIdLookup) + + mockAccountIdLookup.AssertCalled(t, "Lookup", extrinsicSignature.Value.Signer) + mocksSignedPayload.AssertCalled(t, "UsingEncoded") + mockCrypto.AssertCalled(t, "Ed25519Verify", signatureBytes, encodedPayloadBytes, signerAddressBytes) + assert.Equal(t, invalidTransactionBadProofError, err) + assert.Equal(t, sc.NewOption[types.Address32](nil), res) +} + +func Test_Check_SignedUncheckedExtrinsic_LongEncoding_BadProofError(t *testing.T) { + setup(signatureEd25519) + + blakeHashBytes := []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09} + + mockAccountIdLookup.On("Lookup", extrinsicSignature.Value.Signer).Return(signerAddress, nil) + mocksSignedPayload.On("UsingEncoded").Return(sc.BytesToSequenceU8(blakeHashBytes)) + mockCrypto.On("Ed25519Verify", signatureBytes, blakeHashBytes, signerAddressBytes).Return(false) + + res, err := targetSigned.Check(mockAccountIdLookup) + + mockAccountIdLookup.AssertCalled(t, "Lookup", extrinsicSignature.Value.Signer) + mocksSignedPayload.AssertCalled(t, "UsingEncoded") + mockCrypto.AssertCalled(t, "Ed25519Verify", signatureBytes, blakeHashBytes, signerAddressBytes) + assert.Equal(t, invalidTransactionBadProofError, err) + assert.Equal(t, sc.NewOption[types.Address32](nil), res) +} + +func Test_Check_SignedUncheckedExtrinsic_Success(t *testing.T) { + setup(signatureEd25519) + + mockAccountIdLookup.On("Lookup", extrinsicSignature.Value.Signer).Return(signerAddress, nil) + mocksSignedPayload.On("UsingEncoded").Return(sc.BytesToSequenceU8(encodedPayloadBytes)) + mockCrypto.On("Ed25519Verify", signatureBytes, encodedPayloadBytes, signerAddressBytes).Return(true) + + res, err := targetSigned.Check(mockAccountIdLookup) + + mockAccountIdLookup.AssertCalled(t, "Lookup", extrinsicSignature.Value.Signer) + mocksSignedPayload.AssertCalled(t, "UsingEncoded") + mockCrypto.AssertCalled(t, "Ed25519Verify", signatureBytes, encodedPayloadBytes, signerAddressBytes) + assert.Nil(t, err) + assert.Equal(t, sc.NewOption[types.Address32](signerAddress), res) +} + +func Test_Check_SignedUncheckedExtrinsic_Success_Sr25519(t *testing.T) { + setup(signatureSr25519) + + mockAccountIdLookup.On("Lookup", extrinsicSignature.Value.Signer).Return(signerAddress, nil) + mocksSignedPayload.On("UsingEncoded").Return(sc.BytesToSequenceU8(encodedPayloadBytes)) + mockCrypto.On("Sr25519Verify", signatureBytes, encodedPayloadBytes, signerAddressBytes).Return(true) + + res, err := targetSigned.Check(mockAccountIdLookup) + + mockAccountIdLookup.AssertCalled(t, "Lookup", extrinsicSignature.Value.Signer) + mocksSignedPayload.AssertCalled(t, "UsingEncoded") + mockCrypto.AssertCalled(t, "Sr25519Verify", signatureBytes, encodedPayloadBytes, signerAddressBytes) + assert.Nil(t, err) + assert.Equal(t, sc.NewOption[types.Address32](signerAddress), res) +} + +func Test_Check_SignedUncheckedExtrinsic_UnknownSignatureType(t *testing.T) { + setup(unknownMultisignature) + + mockAccountIdLookup.On("Lookup", extrinsicSignature.Value.Signer).Return(signerAddress, nil) + mocksSignedPayload.On("UsingEncoded").Return(sc.BytesToSequenceU8(encodedPayloadBytes)) + + assert.PanicsWithValue(t, "invalid MultiSignature type in Verify", func() { + targetSigned.Check(mockAccountIdLookup) + }) + + mockAccountIdLookup.AssertCalled(t, "Lookup", extrinsicSignature.Value.Signer) + mocksSignedPayload.AssertCalled(t, "UsingEncoded") + mockCrypto.AssertNotCalled(t, "Sr25519Verify", mock.Anything, mock.Anything, mock.Anything) +} diff --git a/mocks/account_id_lookup.go b/mocks/account_id_lookup.go new file mode 100644 index 00000000..5e106a6c --- /dev/null +++ b/mocks/account_id_lookup.go @@ -0,0 +1,20 @@ +package mocks + +import ( + "github.com/LimeChain/gosemble/primitives/types" + "github.com/stretchr/testify/mock" +) + +type AccountIdLookup struct { + mock.Mock +} + +func (l *AccountIdLookup) Lookup(a types.MultiAddress) (types.Address32, types.TransactionValidityError) { + args := l.Called(a) + + if args.Get(1) == nil { + return args.Get(0).(types.Address32), nil + } + + return args.Get(0).(types.Address32), args.Get(1).(types.TransactionValidityError) +} diff --git a/mocks/call.go b/mocks/call.go index 98e1ad30..36765a56 100644 --- a/mocks/call.go +++ b/mocks/call.go @@ -18,7 +18,6 @@ func (m *Call) Encode(buffer *bytes.Buffer) { func (m *Call) Bytes() []byte { args := m.Called() - return args.Get(0).([]byte) } diff --git a/mocks/signed_extra.go b/mocks/signed_extra.go index f3453d8a..f9eb597a 100644 --- a/mocks/signed_extra.go +++ b/mocks/signed_extra.go @@ -17,7 +17,6 @@ func (m *SignedExtra) Encode(buffer *bytes.Buffer) { } func (m *SignedExtra) Bytes() []byte { args := m.Called() - return args.Get(0).([]byte) } @@ -26,15 +25,15 @@ func (m *SignedExtra) Decode(buffer *bytes.Buffer) { } func (m *SignedExtra) AdditionalSigned() (types.AdditionalSigned, types.TransactionValidityError) { - args := m.Called(0) + args := m.Called() if args.Get(1) != nil { return args.Get(0).(types.AdditionalSigned), args.Get(1).(types.TransactionValidityError) } return args.Get(0).(types.AdditionalSigned), nil - } + func (m *SignedExtra) Validate(who types.Address32, call types.Call, info *types.DispatchInfo, length sc.Compact) (types.ValidTransaction, types.TransactionValidityError) { args := m.Called(who, call, info, length) diff --git a/mocks/signed_payload.go b/mocks/signed_payload.go new file mode 100644 index 00000000..6f971640 --- /dev/null +++ b/mocks/signed_payload.go @@ -0,0 +1,42 @@ +package mocks + +import ( + "bytes" + + sc "github.com/LimeChain/goscale" + primitives "github.com/LimeChain/gosemble/primitives/types" + "github.com/stretchr/testify/mock" +) + +type SignedPayload struct { + mock.Mock +} + +func (sp *SignedPayload) Encode(buffer *bytes.Buffer) { + sp.Called(buffer) +} + +func (sp *SignedPayload) Bytes() []byte { + args := sp.Called() + return args.Get(0).([]byte) +} + +func (sp *SignedPayload) AdditionalSigned() primitives.AdditionalSigned { + args := sp.Called() + return args.Get(0).(primitives.AdditionalSigned) +} + +func (sp *SignedPayload) Call() primitives.Call { + args := sp.Called() + return args.Get(0).(primitives.Call) +} + +func (sp *SignedPayload) Extra() primitives.SignedExtra { + args := sp.Called() + return args.Get(0).(primitives.SignedExtra) +} + +func (sp *SignedPayload) UsingEncoded() sc.Sequence[sc.U8] { + args := sp.Called() + return args.Get(0).(sc.Sequence[sc.U8]) +} diff --git a/primitives/types/extrinsic_signature_payload.go b/primitives/types/extrinsic_signature_payload.go index 000446ec..11026a37 100644 --- a/primitives/types/extrinsic_signature_payload.go +++ b/primitives/types/extrinsic_signature_payload.go @@ -7,6 +7,18 @@ import ( "github.com/LimeChain/gosemble/primitives/io" ) +type SignedPayload interface { + sc.Encodable + + AdditionalSigned() AdditionalSigned + Call() Call + Extra() SignedExtra + + UsingEncoded() sc.Sequence[sc.U8] +} + +type AdditionalSigned = sc.VaryingData + // SignedPayload A payload that has been signed for an unchecked extrinsics. // // Note that the payload that we sign to produce unchecked extrinsic signature @@ -15,11 +27,11 @@ import ( // // TODO: make it generic // generic::SignedPayload; -type SignedPayload struct { - AdditionalSigned - Call Call - Extra SignedExtra - hashing io.Hashing +type signedPayload struct { + additionalSigned AdditionalSigned + call Call + extra SignedExtra + hashing io.Hashing } // NewSignedPayload creates a new `SignedPayload`. @@ -27,34 +39,45 @@ type SignedPayload struct { func NewSignedPayload(call Call, extra SignedExtra) (SignedPayload, TransactionValidityError) { additionalSigned, err := extra.AdditionalSigned() if err != nil { - return SignedPayload{}, err + return signedPayload{}, err } - return SignedPayload{ - Call: call, - Extra: extra, - AdditionalSigned: additionalSigned, + return signedPayload{ + call: call, + extra: extra, + additionalSigned: additionalSigned, hashing: io.NewHashing(), }, nil } -type AdditionalSigned = sc.VaryingData - -func (sp SignedPayload) Encode(buffer *bytes.Buffer) { - sp.Call.Encode(buffer) - sp.Extra.Encode(buffer) - sp.AdditionalSigned.Encode(buffer) +func (sp signedPayload) Encode(buffer *bytes.Buffer) { + sp.call.Encode(buffer) + sp.extra.Encode(buffer) + sp.additionalSigned.Encode(buffer) } -func (sp SignedPayload) Bytes() []byte { +func (sp signedPayload) Bytes() []byte { return sc.EncodedBytes(sp) } -func (sp SignedPayload) UsingEncoded() sc.Sequence[sc.U8] { +func (sp signedPayload) AdditionalSigned() AdditionalSigned { + return sp.additionalSigned +} + +func (sp signedPayload) Call() Call { + return sp.call +} + +func (sp signedPayload) Extra() SignedExtra { + return sp.extra +} + +func (sp signedPayload) UsingEncoded() sc.Sequence[sc.U8] { enc := sp.Bytes() if len(enc) > 256 { - return sc.BytesToSequenceU8(sp.hashing.Blake256(enc)) + hash := sp.hashing.Blake256(enc) + return sc.BytesToSequenceU8(hash) } else { return sc.BytesToSequenceU8(enc) } diff --git a/primitives/types/lookup.go b/primitives/types/lookup.go index 4c4ddb31..b9bcd609 100644 --- a/primitives/types/lookup.go +++ b/primitives/types/lookup.go @@ -2,18 +2,22 @@ package types import sc "github.com/LimeChain/goscale" +type AccountIdLookup interface { + Lookup(a MultiAddress) (Address32, TransactionValidityError) +} + // AccountIdLookup A lookup implementation returning the `AccountId` from a `MultiAddress`. -type AccountIdLookup struct { // TODO: make it generic [AccountId, AccountIndex] +type accountIdLookup struct { // TODO: make it generic [AccountId, AccountIndex] // TODO: PhantomData[(AccountId, AccountIndex)] } -func DefaultAccountIdLookup() AccountIdLookup { - return AccountIdLookup{} +func DefaultAccountIdLookup() accountIdLookup { + return accountIdLookup{} } // TODO: MultiAddress[AccountId, AccountIndex] -func (l AccountIdLookup) Lookup(a MultiAddress) (Address32, TransactionValidityError) { - address := LookupAddress(a) +func (l accountIdLookup) Lookup(a MultiAddress) (Address32, TransactionValidityError) { + address := lookupAddress(a) if address.HasValue { return address.Value, nil } @@ -22,7 +26,7 @@ func (l AccountIdLookup) Lookup(a MultiAddress) (Address32, TransactionValidityE } // LookupAddress Lookup an address to get an Id, if there's one there. -func LookupAddress(a MultiAddress) sc.Option[Address32] { // TODO: MultiAddress[AccountId, AccountIndex] +func lookupAddress(a MultiAddress) sc.Option[Address32] { // TODO: MultiAddress[AccountId, AccountIndex] if a.IsAccountId() { return sc.NewOption[Address32](a.AsAccountId().Address32) } @@ -32,14 +36,14 @@ func LookupAddress(a MultiAddress) sc.Option[Address32] { // TODO: MultiAddress[ } if a.IsAccountIndex() { - return sc.NewOption[Address32](LookupIndex(a.AsAccountIndex())) + return sc.NewOption[Address32](lookupIndex(a.AsAccountIndex())) } return sc.NewOption[Address32](nil) } // LookupIndex Lookup an T::AccountIndex to get an Id, if there's one there. -func LookupIndex(index AccountIndex) sc.Option[Address32] { +func lookupIndex(index AccountIndex) sc.Option[Address32] { // TODO: return sc.NewOption[Address32](nil) }