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

lib/runtime: implement ext_network_state #1108

Merged
merged 7 commits into from
Sep 28, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions dot/core/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -374,10 +374,12 @@ func (s *Service) handleRuntimeChanges(header *types.Header) error {
}

cfg := &runtime.Config{
Storage: ts,
Keystore: s.keys.Acco.(*keystore.GenericKeystore),
Imports: runtime.RegisterImports_NodeRuntime,
LogLvl: -1, // don't change runtime package log level
Storage: ts,
Keystore: s.keys.Acco.(*keystore.GenericKeystore),
Imports: runtime.RegisterImports_NodeRuntime,
LogLvl: -1, // don't change runtime package log level
NodeStorage: s.rt.NodeStorage(), // todo determine if we should use existing NodeStore or instantiate a new one (since runtime has changed)
edwardmack marked this conversation as resolved.
Show resolved Hide resolved
Network: s.rt.NetworkService(),
}

s.rt, err = runtime.NewRuntime(code, cfg)
Expand Down
3 changes: 2 additions & 1 deletion dot/network/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,8 @@ func (s *Service) Health() common.Health {
// NetworkState returns information about host needed for the rpc server and the runtime
func (s *Service) NetworkState() common.NetworkState {
return common.NetworkState{
PeerID: s.host.id().String(),
PeerID: s.host.id().String(),
Multiaddrs: s.host.multiaddrs(),
}
}

Expand Down
4 changes: 2 additions & 2 deletions dot/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ func NewNode(cfg *Config, ks *keystore.GlobalKeystore, stopFunc func()) (*Node,
)

var nodeSrvcs []services.Service
var networkSrvc *network.Service

// State Service

Expand All @@ -236,7 +237,7 @@ func NewNode(cfg *Config, ks *keystore.GlobalKeystore, stopFunc func()) (*Node,
}

// create runtime
rt, err := createRuntime(cfg, stateSrvc, ks.Acco.(*keystore.GenericKeystore))
rt, err := createRuntime(cfg, stateSrvc, ks.Acco.(*keystore.GenericKeystore), networkSrvc)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -278,7 +279,6 @@ func NewNode(cfg *Config, ks *keystore.GlobalKeystore, stopFunc func()) (*Node,
}

// Network Service
var networkSrvc *network.Service

// check if network service is enabled
if enabled := networkServiceEnabled(cfg); enabled {
Expand Down
2 changes: 1 addition & 1 deletion dot/rpc/modules/system_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func TestSystemModule_NetworkState(t *testing.T) {

testNetworkState := net.NetworkState()

if res.NetworkState != testNetworkState {
if res.NetworkState.PeerID != testNetworkState.PeerID {
t.Errorf("System.NetworkState: expected: %+v got: %+v\n", testNetworkState, res.NetworkState)
}
}
Expand Down
3 changes: 2 additions & 1 deletion dot/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func createStateService(cfg *Config) (*state.Service, error) {
return stateSrvc, nil
}

func createRuntime(cfg *Config, st *state.Service, ks *keystore.GenericKeystore) (*runtime.Runtime, error) {
func createRuntime(cfg *Config, st *state.Service, ks *keystore.GenericKeystore, net *network.Service) (*runtime.Runtime, error) {
// load runtime code from trie
code, err := st.Storage.GetStorage(nil, []byte(":code"))
if err != nil {
Expand Down Expand Up @@ -103,6 +103,7 @@ func createRuntime(cfg *Config, st *state.Service, ks *keystore.GenericKeystore)
LogLvl: lvl,
NodeStorage: ns,
Role: cfg.Core.Roles,
Network: net,
}

// create runtime executor
Expand Down
18 changes: 9 additions & 9 deletions dot/services_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,11 @@ func TestCreateCoreService(t *testing.T) {
ed25519Keyring, _ := keystore.NewEd25519Keyring()
ks.Gran.Insert(ed25519Keyring.Alice())

rt, err := createRuntime(cfg, stateSrvc, ks.Acco.(*keystore.GenericKeystore))
require.NoError(t, err)

networkSrvc := &network.Service{}

rt, err := createRuntime(cfg, stateSrvc, ks.Acco.(*keystore.GenericKeystore), networkSrvc)
require.NoError(t, err)

dh, err := createDigestHandler(stateSrvc, nil, nil)
require.NoError(t, err)

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

ks := keystore.NewGlobalKeystore()
require.NotNil(t, ks)
rt, err := createRuntime(cfg, stateSrvc, ks.Acco.(*keystore.GenericKeystore))
rt, err := createRuntime(cfg, stateSrvc, ks.Acco.(*keystore.GenericKeystore), &network.Service{})
require.NoError(t, err)

cfg.Core.BabeThreshold = nil
Expand All @@ -143,7 +143,7 @@ func TestCreateSyncService(t *testing.T) {

ks := keystore.NewGlobalKeystore()
require.NotNil(t, ks)
rt, err := createRuntime(cfg, stateSrvc, ks.Acco.(*keystore.GenericKeystore))
rt, err := createRuntime(cfg, stateSrvc, ks.Acco.(*keystore.GenericKeystore), &network.Service{})
require.NoError(t, err)

cfg.Core.BabeThreshold = nil
Expand Down Expand Up @@ -207,7 +207,7 @@ func TestCreateRPCService(t *testing.T) {
ed25519Keyring, _ := keystore.NewEd25519Keyring()
ks.Gran.Insert(ed25519Keyring.Alice())

rt, err := createRuntime(cfg, stateSrvc, ks.Acco.(*keystore.GenericKeystore))
rt, err := createRuntime(cfg, stateSrvc, ks.Acco.(*keystore.GenericKeystore), networkSrvc)
require.NoError(t, err)

dh, err := createDigestHandler(stateSrvc, nil, nil)
Expand Down Expand Up @@ -252,7 +252,7 @@ func TestCreateBABEService(t *testing.T) {
require.Nil(t, err)
ks.Babe.Insert(kr.Alice())

rt, err := createRuntime(cfg, stateSrvc, ks.Acco.(*keystore.GenericKeystore))
rt, err := createRuntime(cfg, stateSrvc, ks.Acco.(*keystore.GenericKeystore), &network.Service{})
require.NoError(t, err)

bs, err := createBABEService(cfg, rt, stateSrvc, ks.Babe)
Expand Down Expand Up @@ -284,7 +284,7 @@ func TestCreateGrandpaService(t *testing.T) {
require.NoError(t, err)
ks.Gran.Insert(kr.Alice())

rt, err := createRuntime(cfg, stateSrvc, ks.Acco.(*keystore.GenericKeystore))
rt, err := createRuntime(cfg, stateSrvc, ks.Acco.(*keystore.GenericKeystore), &network.Service{})
require.NoError(t, err)

dh, err := createDigestHandler(stateSrvc, nil, nil)
Expand Down Expand Up @@ -334,7 +334,7 @@ func TestNewWebSocketServer(t *testing.T) {
ks := keystore.NewGlobalKeystore()
ed25519Keyring, _ := keystore.NewEd25519Keyring()
ks.Gran.Insert(ed25519Keyring.Alice())
rt, err := createRuntime(cfg, stateSrvc, ks.Acco.(*keystore.GenericKeystore))
rt, err := createRuntime(cfg, stateSrvc, ks.Acco.(*keystore.GenericKeystore), networkSrvc)
require.NoError(t, err)

dh, err := createDigestHandler(stateSrvc, nil, nil)
Expand Down
5 changes: 4 additions & 1 deletion lib/common/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package common

import ma "github.com/multiformats/go-multiaddr"

// Health is network information about host needed for the rpc server
type Health struct {
Peers int
Expand All @@ -25,7 +27,8 @@ type Health struct {

// NetworkState is network information about host needed for the rpc server and the runtime
type NetworkState struct {
PeerID string
PeerID string
Multiaddrs []ma.Multiaddr
}

// PeerInfo is network information about peers needed for the rpc server
Expand Down
29 changes: 27 additions & 2 deletions lib/runtime/imports_old.go
Original file line number Diff line number Diff line change
Expand Up @@ -766,8 +766,33 @@ func ext_local_storage_compare_and_set(context unsafe.Pointer, kind, key, keyLen
//export ext_network_state
func ext_network_state(context unsafe.Pointer, writtenOut int32) int32 {
logger.Trace("[ext_network_state] executing...")
logger.Warn("[ext_network_state] Not yet implemented.")
return 0
instanceContext := wasm.IntoInstanceContext(context)
memory := instanceContext.Memory().Data()
runtimeCtx := instanceContext.Data().(*Ctx)
if runtimeCtx.network == nil {
return 0
}

nsEnc, err := scale.Encode(runtimeCtx.network.NetworkState())
if err != nil {
logger.Error("[ext_network_state]", "error", err)
return 0
}

// copy network state length to memory writtenOut location
nsEncLen := uint32(len(nsEnc))
buf := make([]byte, 4)
binary.LittleEndian.PutUint32(buf, nsEncLen)
copy(memory[writtenOut:writtenOut+4], buf)

// allocate memory for value and copy value to memory
ptr, err := runtimeCtx.allocator.Allocate(nsEncLen)
if err != nil {
logger.Error("[ext_network_state]", "error", err)
return 0
}
copy(memory[ptr:ptr+nsEncLen], nsEnc)
return int32(ptr)
}

//export ext_submit_transaction
Expand Down
25 changes: 25 additions & 0 deletions lib/runtime/imports_old_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1267,3 +1267,28 @@ func TestExt_is_validator(t *testing.T) {
require.NoError(t, err)
require.Equal(t, int32(0), res.ToI32())
}

func TestExt_network_state(t *testing.T) {
runtime := NewTestRuntime(t, TEST_RUNTIME)
memory := runtime.vm.Memory.Data()

testFunc, ok := runtime.vm.Exports["test_ext_network_state"]
if !ok {
t.Fatal("could not find exported function")
}

writtenOutPtr, err := runtime.ctx.allocator.Allocate(4)
require.NoError(t, err)

resPtr, err := testFunc(int32(writtenOutPtr))
require.NoError(t, err)

writtenOutValue := binary.LittleEndian.Uint32(memory[writtenOutPtr : writtenOutPtr+4])

resData := memory[resPtr.ToI32() : resPtr.ToI32()+int32(writtenOutValue)]

expected := runtime.ctx.network.NetworkState()
expectedEnc, err := scale.Encode(expected)
require.NoError(t, err)
require.Equal(t, expectedEnc, resData)
}
5 changes: 5 additions & 0 deletions lib/runtime/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ type Storage interface {
GetBalance(key [32]byte) (uint64, error)
}

// BasicNetwork interface for functions used by runtime network state function
type BasicNetwork interface {
NetworkState() common.NetworkState
}

// BasicStorage interface for functions used by runtime offchain workers
type BasicStorage interface {
Put(key []byte, value []byte) error
Expand Down
19 changes: 16 additions & 3 deletions lib/runtime/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@ type Ctx struct {
storage Storage
allocator *FreeingBumpHeapAllocator
keystore *keystore.GenericKeystore
nodeStorage NodeStorage
validator bool
nodeStorage NodeStorage
network BasicNetwork
}

// Config represents a runtime configuration
Expand All @@ -56,8 +57,9 @@ type Config struct {
Keystore *keystore.GenericKeystore
Imports func() (*wasm.Imports, error)
LogLvl log.Lvl
NodeStorage NodeStorage
Role byte
NodeStorage NodeStorage
Network BasicNetwork
}

// Runtime struct
Expand Down Expand Up @@ -117,8 +119,9 @@ func NewRuntime(code []byte, cfg *Config) (*Runtime, error) {
storage: cfg.Storage,
allocator: memAllocator,
keystore: cfg.Keystore,
nodeStorage: cfg.NodeStorage,
validator: validator,
nodeStorage: cfg.NodeStorage,
network: cfg.Network,
}

logger.Debug("NewRuntime", "runtimeCtx", runtimeCtx)
Expand Down Expand Up @@ -199,3 +202,13 @@ func (r *Runtime) malloc(size uint32) (uint32, error) {
func (r *Runtime) free(ptr uint32) error {
return r.ctx.allocator.Deallocate(ptr)
}

// NodeStorage to get reference to runtime node service
func (r *Runtime) NodeStorage() NodeStorage {
return r.ctx.nodeStorage
}

// NetworkService to get referernce to runtime network service
func (r *Runtime) NetworkService() BasicNetwork {
return r.ctx.network
}
23 changes: 23 additions & 0 deletions lib/runtime/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/ChainSafe/gossamer/lib/trie"
"github.com/ChainSafe/gossamer/lib/utils"
log "github.com/ChainSafe/log15"
ma "github.com/multiformats/go-multiaddr"
"github.com/stretchr/testify/require"
wasm "github.com/wasmerio/go-ext-wasm/wasmer"
)
Expand Down Expand Up @@ -66,6 +67,7 @@ func NewTestRuntimeWithTrie(t *testing.T, targetRuntime string, tt *trie.Trie, l
Imports: importsFunc,
LogLvl: lvl,
NodeStorage: ns,
Network: new(testRuntimeNetwork),
}

r, err := NewRuntimeFromFile(fp, cfg)
Expand Down Expand Up @@ -280,3 +282,24 @@ func (trs testRuntimeStorage) GetBalance(key [32]byte) (uint64, error) {

return binary.LittleEndian.Uint64(bal), nil
}

type testRuntimeNetwork struct {
}

func (trn testRuntimeNetwork) NetworkState() common.NetworkState {
testAddrs := []ma.Multiaddr(nil)

// create mock multiaddress
addr, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/7001/p2p/12D3KooWDcCNBqAemRvguPa7rtmsbn2hpgLqAz8KsMMFsF2rdCUP")
if err != nil {
// todo ed handle error
fmt.Printf("ERROR %v\n", err)
}
edwardmack marked this conversation as resolved.
Show resolved Hide resolved

testAddrs = append(testAddrs, addr)

return common.NetworkState{
PeerID: "12D3KooWDcCNBqAemRvguPa7rtmsbn2hpgLqAz8KsMMFsF2rdCUP",
Multiaddrs: testAddrs,
}
}