Skip to content

Commit

Permalink
Merge branch 'development' into eclesio/grandpa-final-round-metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
EclesioMeloJunior committed Jul 6, 2021
2 parents 2b3436a + 7ecada2 commit b07413d
Show file tree
Hide file tree
Showing 16 changed files with 956 additions and 391 deletions.
27 changes: 14 additions & 13 deletions dot/rpc/modules/author.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ func NewAuthorModule(logger log.Logger, coreAPI CoreAPI, runtimeAPI RuntimeAPI,
}

// InsertKey inserts a key into the keystore
func (cm *AuthorModule) InsertKey(r *http.Request, req *KeyInsertRequest, res *KeyInsertResponse) error {
func (am *AuthorModule) InsertKey(r *http.Request, req *KeyInsertRequest, res *KeyInsertResponse) error {
keyReq := *req

pkDec, err := common.HexToBytes(keyReq[1])
Expand All @@ -119,22 +119,22 @@ func (cm *AuthorModule) InsertKey(r *http.Request, req *KeyInsertRequest, res *K
return fmt.Errorf("generated public key does not equal provide public key")
}

cm.coreAPI.InsertKey(keyPair)
cm.logger.Info("inserted key into keystore", "key", keyPair.Public().Hex())
am.coreAPI.InsertKey(keyPair)
am.logger.Info("inserted key into keystore", "key", keyPair.Public().Hex())
return nil
}

// HasKey Checks if the keystore has private keys for the given public key and key type.
func (cm *AuthorModule) HasKey(r *http.Request, req *[]string, res *bool) error {
func (am *AuthorModule) HasKey(r *http.Request, req *[]string, res *bool) error {
reqKey := *req
var err error
*res, err = cm.coreAPI.HasKey(reqKey[0], reqKey[1])
*res, err = am.coreAPI.HasKey(reqKey[0], reqKey[1])
return err
}

// PendingExtrinsics Returns all pending extrinsics
func (cm *AuthorModule) PendingExtrinsics(r *http.Request, req *EmptyRequest, res *PendingExtrinsicsResponse) error {
pending := cm.txStateAPI.Pending()
func (am *AuthorModule) PendingExtrinsics(r *http.Request, req *EmptyRequest, res *PendingExtrinsicsResponse) error {
pending := am.txStateAPI.Pending()
resp := make([]string, len(pending))
for idx, tx := range pending {
resp[idx] = common.BytesToHex(tx.Extrinsic)
Expand All @@ -145,29 +145,30 @@ func (cm *AuthorModule) PendingExtrinsics(r *http.Request, req *EmptyRequest, re
}

// RemoveExtrinsic Remove given extrinsic from the pool and temporarily ban it to prevent reimporting
func (cm *AuthorModule) RemoveExtrinsic(r *http.Request, req *ExtrinsicOrHashRequest, res *RemoveExtrinsicsResponse) error {
func (am *AuthorModule) RemoveExtrinsic(r *http.Request, req *ExtrinsicOrHashRequest, res *RemoveExtrinsicsResponse) error {
return nil
}

// RotateKeys Generate new session keys and returns the corresponding public keys
func (cm *AuthorModule) RotateKeys(r *http.Request, req *EmptyRequest, res *KeyRotateResponse) error {
func (am *AuthorModule) RotateKeys(r *http.Request, req *EmptyRequest, res *KeyRotateResponse) error {
return nil
}

// SubmitAndWatchExtrinsic Submit and subscribe to watch an extrinsic until unsubscribed
func (cm *AuthorModule) SubmitAndWatchExtrinsic(r *http.Request, req *Extrinsic, res *ExtrinsicStatus) error {
func (am *AuthorModule) SubmitAndWatchExtrinsic(r *http.Request, req *Extrinsic, res *ExtrinsicStatus) error {
return nil
}

// SubmitExtrinsic Submit a fully formatted extrinsic for block inclusion
func (cm *AuthorModule) SubmitExtrinsic(r *http.Request, req *Extrinsic, res *ExtrinsicHashResponse) error {
func (am *AuthorModule) SubmitExtrinsic(r *http.Request, req *Extrinsic, res *ExtrinsicHashResponse) error {
extBytes, err := common.HexToBytes(req.Data)
if err != nil {
return err
}

ext := types.Extrinsic(extBytes)
err = cm.coreAPI.HandleSubmittedExtrinsic(ext)
am.logger.Crit("[rpc]", "extrinsic", ext)

*res = ExtrinsicHashResponse(ext.Hash().String())
err = am.coreAPI.HandleSubmittedExtrinsic(ext)
return err
}
268 changes: 268 additions & 0 deletions dot/rpc/modules/author_integration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
// +build integration

package modules

import (
"fmt"
"os"
"reflect"
"testing"

"github.com/ChainSafe/gossamer/dot/network"
"github.com/ChainSafe/gossamer/dot/state"
"github.com/ChainSafe/gossamer/dot/types"
"github.com/ChainSafe/gossamer/lib/common"
"github.com/ChainSafe/gossamer/lib/keystore"
"github.com/ChainSafe/gossamer/lib/runtime"
"github.com/ChainSafe/gossamer/lib/runtime/wasmer"
"github.com/ChainSafe/gossamer/lib/transaction"
log "github.com/ChainSafe/log15"
"github.com/stretchr/testify/require"
)

// https://github.com/paritytech/substrate/blob/5420de3face1349a97eb954ae71c5b0b940c31de/core/transaction-pool/src/tests.rs#L95
var testExt = common.MustHexToBytes("0x410284ffd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d01f8efbe48487e57a22abf7e3acd491b7f3528a33a111b1298601554863d27eb129eaa4e718e1365414ff3d028b62bebc651194c6b5001e5c2839b982757e08a8c0000000600ff8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a480b00c465f14670")

// invalid transaction (above tx, with last byte changed)
//nolint
var testInvalidExt = []byte{1, 212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125, 142, 175, 4, 21, 22, 135, 115, 99, 38, 201, 254, 161, 126, 37, 252, 82, 135, 97, 54, 147, 201, 18, 144, 156, 178, 38, 170, 71, 148, 242, 106, 72, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 216, 5, 113, 87, 87, 40, 221, 120, 247, 252, 137, 201, 74, 231, 222, 101, 85, 108, 102, 39, 31, 190, 210, 14, 215, 124, 19, 160, 180, 203, 54, 110, 167, 163, 149, 45, 12, 108, 80, 221, 65, 238, 57, 237, 199, 16, 10, 33, 185, 8, 244, 184, 243, 139, 5, 87, 252, 245, 24, 225, 37, 154, 163, 143}

func TestMain(m *testing.M) {
wasmFilePaths, err := runtime.GenerateRuntimeWasmFile()
if err != nil {
log.Error("failed to generate runtime wasm file", err)
os.Exit(1)
}

// Start all tests
code := m.Run()

runtime.RemoveFiles(wasmFilePaths)
os.Exit(code)
}

func TestAuthorModule_Pending(t *testing.T) {
txQueue := state.NewTransactionState()
auth := NewAuthorModule(nil, nil, nil, txQueue)

res := new(PendingExtrinsicsResponse)
err := auth.PendingExtrinsics(nil, nil, res)
if err != nil {
t.Fatal(err)
}

if !reflect.DeepEqual(*res, PendingExtrinsicsResponse([]string{})) {
t.Errorf("Fail: expected: %+v got: %+v\n", *res, PendingExtrinsicsResponse([]string{}))
}

vtx := &transaction.ValidTransaction{
Extrinsic: types.NewExtrinsic(testExt),
Validity: new(transaction.Validity),
}

_, err = txQueue.Push(vtx)
require.NoError(t, err)

err = auth.PendingExtrinsics(nil, nil, res)
if err != nil {
t.Fatal(err)
}

expected := common.BytesToHex(vtx.Extrinsic)
if !reflect.DeepEqual(*res, PendingExtrinsicsResponse([]string{expected})) {
t.Errorf("Fail: expected: %+v got: %+v\n", res, PendingExtrinsicsResponse([]string{expected}))
}
}

func TestAuthorModule_SubmitExtrinsic_Integration(t *testing.T) {
t.Skip()
// setup auth module
txQueue := state.NewTransactionState()

auth := setupAuthModule(t, txQueue)

// create and submit extrinsic
ext := Extrinsic{fmt.Sprintf("0x%x", testExt)}

res := new(ExtrinsicHashResponse)

err := auth.SubmitExtrinsic(nil, &ext, res)
require.Nil(t, err)

// setup expected results
val := &transaction.Validity{
Priority: 69,
Requires: [][]byte{},
Provides: [][]byte{{146, 157, 61, 99, 63, 98, 30, 242, 128, 49, 150, 90, 140, 165, 187, 249}},
Longevity: 64,
Propagate: true,
}
expected := &transaction.ValidTransaction{
Extrinsic: types.NewExtrinsic(testExt),
Validity: val,
}
expectedHash := ExtrinsicHashResponse("0xb20777f4db60ea55b1aeedde2d7b7aff3efeda736b7e2a840b5713348f766078")

inQueue := txQueue.Pop()

// compare results
require.Equal(t, expected, inQueue)
require.Equal(t, expectedHash, *res)
}

func TestAuthorModule_SubmitExtrinsic_invalid(t *testing.T) {
t.Skip()
// setup service
// setup auth module
txQueue := state.NewTransactionState()
auth := setupAuthModule(t, txQueue)

// create and submit extrinsic
ext := Extrinsic{fmt.Sprintf("0x%x", testInvalidExt)}

res := new(ExtrinsicHashResponse)

err := auth.SubmitExtrinsic(nil, &ext, res)
require.EqualError(t, err, runtime.ErrInvalidTransaction.Message)
}

func TestAuthorModule_SubmitExtrinsic_invalid_input(t *testing.T) {
// setup service
// setup auth module
txQueue := state.NewTransactionState()
auth := setupAuthModule(t, txQueue)

// create and submit extrinsic
ext := Extrinsic{fmt.Sprintf("%x", "1")}

res := new(ExtrinsicHashResponse)
err := auth.SubmitExtrinsic(nil, &ext, res)
require.EqualError(t, err, "could not byteify non 0x prefixed string")
}

func TestAuthorModule_SubmitExtrinsic_InQueue(t *testing.T) {
t.Skip()
// setup auth module
txQueue := state.NewTransactionState()

auth := setupAuthModule(t, txQueue)

// create and submit extrinsic
ext := Extrinsic{fmt.Sprintf("0x%x", testExt)}

res := new(ExtrinsicHashResponse)

// setup expected results
val := &transaction.Validity{
Priority: 69,
Requires: [][]byte{},
Provides: [][]byte{{146, 157, 61, 99, 63, 98, 30, 242, 128, 49, 150, 90, 140, 165, 187, 249}},
Longevity: 64,
Propagate: true,
}
expected := &transaction.ValidTransaction{
Extrinsic: types.NewExtrinsic(testExt),
Validity: val,
}

_, err := txQueue.Push(expected)
require.Nil(t, err)

// this should cause error since transaction is already in txQueue
err = auth.SubmitExtrinsic(nil, &ext, res)
require.EqualError(t, err, transaction.ErrTransactionExists.Error())

}

func TestAuthorModule_InsertKey_Valid(t *testing.T) {
auth := setupAuthModule(t, nil)
req := &KeyInsertRequest{"babe", "0xb7e9185065667390d2ad952a5324e8c365c9bf503dcf97c67a5ce861afe97309", "0x6246ddf254e0b4b4e7dffefc8adf69d212b98ac2b579c362b473fec8c40b4c0a"}
res := &KeyInsertResponse{}
err := auth.InsertKey(nil, req, res)
require.Nil(t, err)
require.Len(t, *res, 0) // zero len result on success
}

func TestAuthorModule_InsertKey_Valid_gran_keytype(t *testing.T) {
auth := setupAuthModule(t, nil)
req := &KeyInsertRequest{"gran", "0xb7e9185065667390d2ad952a5324e8c365c9bf503dcf97c67a5ce861afe97309b7e9185065667390d2ad952a5324e8c365c9bf503dcf97c67a5ce861afe97309", "0xb7e9185065667390d2ad952a5324e8c365c9bf503dcf97c67a5ce861afe97309"}
res := &KeyInsertResponse{}
err := auth.InsertKey(nil, req, res)
require.Nil(t, err)

require.Len(t, *res, 0) // zero len result on success
}

func TestAuthorModule_InsertKey_InValid(t *testing.T) {
auth := setupAuthModule(t, nil)
req := &KeyInsertRequest{"babe", "0xb7e9185065667390d2ad952a5324e8c365c9bf503dcf97c67a5ce861afe97309", "0x0000000000000000000000000000000000000000000000000000000000000000"}
res := &KeyInsertResponse{}
err := auth.InsertKey(nil, req, res)
require.EqualError(t, err, "generated public key does not equal provide public key")
}

func TestAuthorModule_InsertKey_UnknownKeyType(t *testing.T) {
auth := setupAuthModule(t, nil)
req := &KeyInsertRequest{"mack", "0xb7e9185065667390d2ad952a5324e8c365c9bf503dcf97c67a5ce861afe97309", "0x6246ddf254e0b4b4e7dffefc8adf69d212b98ac2b579c362b473fec8c40b4c0a"}
res := &KeyInsertResponse{}
err := auth.InsertKey(nil, req, res)
require.EqualError(t, err, "cannot decode key: invalid key type")

}

func TestAuthorModule_HasKey_Integration(t *testing.T) {
auth := setupAuthModule(t, nil)
kr, err := keystore.NewSr25519Keyring()
require.Nil(t, err)

var res bool
req := []string{kr.Alice().Public().Hex(), "babe"}
err = auth.HasKey(nil, &req, &res)
require.NoError(t, err)
require.True(t, res)
}

func TestAuthorModule_HasKey_NotFound(t *testing.T) {
auth := setupAuthModule(t, nil)
kr, err := keystore.NewSr25519Keyring()
require.Nil(t, err)

var res bool
req := []string{kr.Bob().Public().Hex(), "babe"}
err = auth.HasKey(nil, &req, &res)
require.NoError(t, err)
require.False(t, res)
}

func TestAuthorModule_HasKey_InvalidKey(t *testing.T) {
auth := setupAuthModule(t, nil)

var res bool
req := []string{"0xaa11", "babe"}
err := auth.HasKey(nil, &req, &res)
require.EqualError(t, err, "cannot create public key: input is not 32 bytes")
require.False(t, res)
}

func TestAuthorModule_HasKey_InvalidKeyType(t *testing.T) {
auth := setupAuthModule(t, nil)
kr, err := keystore.NewSr25519Keyring()
require.Nil(t, err)

var res bool
req := []string{kr.Alice().Public().Hex(), "xxxx"}
err = auth.HasKey(nil, &req, &res)
require.EqualError(t, err, "unknown key type: xxxx")
require.False(t, res)
}

func setupAuthModule(t *testing.T, txq *state.TransactionState) *AuthorModule {
fmt.Println("calling setupAuthModule")
cs := newCoreService(t, nil)
fmt.Println("called newCoreService")
rt := wasmer.NewTestInstance(t, runtime.NODE_RUNTIME)
t.Cleanup(func() {
rt.Stop()
})
return NewAuthorModule(nil, cs, rt, txq)
}

0 comments on commit b07413d

Please sign in to comment.