github.com/shyftnetwork/go-empyrean@v1.8.3-0.20191127201940-fbfca9338f04/node/node_test.go (about)

     1  // Copyright 2015 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package node
    18  
    19  import (
    20  	"errors"
    21  	"io/ioutil"
    22  	"os"
    23  	"reflect"
    24  	"testing"
    25  	"time"
    26  
    27  	"math/big"
    28  
    29  	"github.com/ShyftNetwork/go-empyrean/accounts/abi/bind"
    30  	"github.com/ShyftNetwork/go-empyrean/accounts/abi/bind/backends"
    31  	"github.com/ShyftNetwork/go-empyrean/core"
    32  	"github.com/ShyftNetwork/go-empyrean/crypto"
    33  	"github.com/ShyftNetwork/go-empyrean/generated_bindings"
    34  	"github.com/ShyftNetwork/go-empyrean/p2p"
    35  	"github.com/ShyftNetwork/go-empyrean/rpc"
    36  	whisper "github.com/ShyftNetwork/go-empyrean/whisper/whisperv6"
    37  )
    38  
    39  var (
    40  	testNodeKey, _ = crypto.GenerateKey()
    41  )
    42  
    43  func testNodeConfig() *Config {
    44  	return &Config{
    45  		Name: "test node",
    46  		P2P:  p2p.Config{PrivateKey: testNodeKey},
    47  	}
    48  }
    49  
    50  // Tests that an empty protocol stack can be started, restarted and stopped.
    51  func TestNodeLifeCycle(t *testing.T) {
    52  	stack, err := New(testNodeConfig())
    53  	if err != nil {
    54  		t.Fatalf("failed to create protocol stack: %v", err)
    55  	}
    56  	// Ensure that a stopped node can be stopped again
    57  	for i := 0; i < 3; i++ {
    58  		if err := stack.Stop(); err != ErrNodeStopped {
    59  			t.Fatalf("iter %d: stop failure mismatch: have %v, want %v", i, err, ErrNodeStopped)
    60  		}
    61  	}
    62  	// Ensure that a node can be successfully started, but only once
    63  	if err := stack.Start(); err != nil {
    64  		t.Fatalf("failed to start node: %v", err)
    65  	}
    66  	if err := stack.Start(); err != ErrNodeRunning {
    67  		t.Fatalf("start failure mismatch: have %v, want %v ", err, ErrNodeRunning)
    68  	}
    69  	// Ensure that a node can be restarted arbitrarily many times
    70  	for i := 0; i < 3; i++ {
    71  		if err := stack.Restart(); err != nil {
    72  			t.Fatalf("iter %d: failed to restart node: %v", i, err)
    73  		}
    74  	}
    75  	// Ensure that a node can be stopped, but only once
    76  	if err := stack.Stop(); err != nil {
    77  		t.Fatalf("failed to stop node: %v", err)
    78  	}
    79  	if err := stack.Stop(); err != ErrNodeStopped {
    80  		t.Fatalf("stop failure mismatch: have %v, want %v ", err, ErrNodeStopped)
    81  	}
    82  }
    83  
    84  // Tests that if the data dir is already in use, an appropriate error is returned.
    85  func TestNodeUsedDataDir(t *testing.T) {
    86  	// Create a temporary folder to use as the data directory
    87  	dir, err := ioutil.TempDir("", "")
    88  	if err != nil {
    89  		t.Fatalf("failed to create temporary data directory: %v", err)
    90  	}
    91  	defer os.RemoveAll(dir)
    92  
    93  	// Create a new node based on the data directory
    94  	original, err := New(&Config{DataDir: dir})
    95  	if err != nil {
    96  		t.Fatalf("failed to create original protocol stack: %v", err)
    97  	}
    98  	if err := original.Start(); err != nil {
    99  		t.Fatalf("failed to start original protocol stack: %v", err)
   100  	}
   101  	defer original.Stop()
   102  
   103  	// Create a second node based on the same data directory and ensure failure
   104  	duplicate, err := New(&Config{DataDir: dir})
   105  	if err != nil {
   106  		t.Fatalf("failed to create duplicate protocol stack: %v", err)
   107  	}
   108  	if err := duplicate.Start(); err != ErrDatadirUsed {
   109  		t.Fatalf("duplicate datadir failure mismatch: have %v, want %v", err, ErrDatadirUsed)
   110  	}
   111  }
   112  
   113  // Tests whether services can be registered and duplicates caught.
   114  func TestServiceRegistry(t *testing.T) {
   115  	stack, err := New(testNodeConfig())
   116  	if err != nil {
   117  		t.Fatalf("failed to create protocol stack: %v", err)
   118  	}
   119  	// Register a batch of unique services and ensure they start successfully
   120  	services := []ServiceConstructor{NewNoopServiceA, NewNoopServiceB, NewNoopServiceC}
   121  	for i, constructor := range services {
   122  		if err := stack.Register(constructor); err != nil {
   123  			t.Fatalf("service #%d: registration failed: %v", i, err)
   124  		}
   125  	}
   126  	if err := stack.Start(); err != nil {
   127  		t.Fatalf("failed to start original service stack: %v", err)
   128  	}
   129  	if err := stack.Stop(); err != nil {
   130  		t.Fatalf("failed to stop original service stack: %v", err)
   131  	}
   132  	// Duplicate one of the services and retry starting the node
   133  	if err := stack.Register(NewNoopServiceB); err != nil {
   134  		t.Fatalf("duplicate registration failed: %v", err)
   135  	}
   136  	if err := stack.Start(); err == nil {
   137  		t.Fatalf("duplicate service started")
   138  	} else {
   139  		if _, ok := err.(*DuplicateServiceError); !ok {
   140  			t.Fatalf("duplicate error mismatch: have %v, want %v", err, DuplicateServiceError{})
   141  		}
   142  	}
   143  }
   144  
   145  // Tests that registered services get started and stopped correctly.
   146  func TestServiceLifeCycle(t *testing.T) {
   147  	stack, err := New(testNodeConfig())
   148  	if err != nil {
   149  		t.Fatalf("failed to create protocol stack: %v", err)
   150  	}
   151  	// Register a batch of life-cycle instrumented services
   152  	services := map[string]InstrumentingWrapper{
   153  		"A": InstrumentedServiceMakerA,
   154  		"B": InstrumentedServiceMakerB,
   155  		"C": InstrumentedServiceMakerC,
   156  	}
   157  	started := make(map[string]bool)
   158  	stopped := make(map[string]bool)
   159  
   160  	for id, maker := range services {
   161  		id := id // Closure for the constructor
   162  		constructor := func(*ServiceContext) (Service, error) {
   163  			return &InstrumentedService{
   164  				startHook: func(*p2p.Server) { started[id] = true },
   165  				stopHook:  func() { stopped[id] = true },
   166  			}, nil
   167  		}
   168  		if err := stack.Register(maker(constructor)); err != nil {
   169  			t.Fatalf("service %s: registration failed: %v", id, err)
   170  		}
   171  	}
   172  	// Start the node and check that all services are running
   173  	if err := stack.Start(); err != nil {
   174  		t.Fatalf("failed to start protocol stack: %v", err)
   175  	}
   176  	for id := range services {
   177  		if !started[id] {
   178  			t.Fatalf("service %s: freshly started service not running", id)
   179  		}
   180  		if stopped[id] {
   181  			t.Fatalf("service %s: freshly started service already stopped", id)
   182  		}
   183  	}
   184  	// Stop the node and check that all services have been stopped
   185  	if err := stack.Stop(); err != nil {
   186  		t.Fatalf("failed to stop protocol stack: %v", err)
   187  	}
   188  	for id := range services {
   189  		if !stopped[id] {
   190  			t.Fatalf("service %s: freshly terminated service still running", id)
   191  		}
   192  	}
   193  }
   194  
   195  // Tests that services are restarted cleanly as new instances.
   196  func TestServiceRestarts(t *testing.T) {
   197  	stack, err := New(testNodeConfig())
   198  	if err != nil {
   199  		t.Fatalf("failed to create protocol stack: %v", err)
   200  	}
   201  	// Define a service that does not support restarts
   202  	var (
   203  		running bool
   204  		started int
   205  	)
   206  	constructor := func(*ServiceContext) (Service, error) {
   207  		running = false
   208  
   209  		return &InstrumentedService{
   210  			startHook: func(*p2p.Server) {
   211  				if running {
   212  					panic("already running")
   213  				}
   214  				running = true
   215  				started++
   216  			},
   217  		}, nil
   218  	}
   219  	// Register the service and start the protocol stack
   220  	if err := stack.Register(constructor); err != nil {
   221  		t.Fatalf("failed to register the service: %v", err)
   222  	}
   223  	if err := stack.Start(); err != nil {
   224  		t.Fatalf("failed to start protocol stack: %v", err)
   225  	}
   226  	defer stack.Stop()
   227  
   228  	if !running || started != 1 {
   229  		t.Fatalf("running/started mismatch: have %v/%d, want true/1", running, started)
   230  	}
   231  	// Restart the stack a few times and check successful service restarts
   232  	for i := 0; i < 3; i++ {
   233  		if err := stack.Restart(); err != nil {
   234  			t.Fatalf("iter %d: failed to restart stack: %v", i, err)
   235  		}
   236  	}
   237  	if !running || started != 4 {
   238  		t.Fatalf("running/started mismatch: have %v/%d, want true/4", running, started)
   239  	}
   240  }
   241  
   242  // Tests that if a service fails to initialize itself, none of the other services
   243  // will be allowed to even start.
   244  func TestServiceConstructionAbortion(t *testing.T) {
   245  	stack, err := New(testNodeConfig())
   246  	if err != nil {
   247  		t.Fatalf("failed to create protocol stack: %v", err)
   248  	}
   249  	// Define a batch of good services
   250  	services := map[string]InstrumentingWrapper{
   251  		"A": InstrumentedServiceMakerA,
   252  		"B": InstrumentedServiceMakerB,
   253  		"C": InstrumentedServiceMakerC,
   254  	}
   255  	started := make(map[string]bool)
   256  	for id, maker := range services {
   257  		id := id // Closure for the constructor
   258  		constructor := func(*ServiceContext) (Service, error) {
   259  			return &InstrumentedService{
   260  				startHook: func(*p2p.Server) { started[id] = true },
   261  			}, nil
   262  		}
   263  		if err := stack.Register(maker(constructor)); err != nil {
   264  			t.Fatalf("service %s: registration failed: %v", id, err)
   265  		}
   266  	}
   267  	// Register a service that fails to construct itself
   268  	failure := errors.New("fail")
   269  	failer := func(*ServiceContext) (Service, error) {
   270  		return nil, failure
   271  	}
   272  	if err := stack.Register(failer); err != nil {
   273  		t.Fatalf("failer registration failed: %v", err)
   274  	}
   275  	// Start the protocol stack and ensure none of the services get started
   276  	for i := 0; i < 100; i++ {
   277  		if err := stack.Start(); err != failure {
   278  			t.Fatalf("iter %d: stack startup failure mismatch: have %v, want %v", i, err, failure)
   279  		}
   280  		for id := range services {
   281  			if started[id] {
   282  				t.Fatalf("service %s: started should not have", id)
   283  			}
   284  			delete(started, id)
   285  		}
   286  	}
   287  }
   288  
   289  // Tests that if a service fails to start, all others started before it will be
   290  // shut down.
   291  func TestServiceStartupAbortion(t *testing.T) {
   292  	stack, err := New(testNodeConfig())
   293  	if err != nil {
   294  		t.Fatalf("failed to create protocol stack: %v", err)
   295  	}
   296  	// Register a batch of good services
   297  	services := map[string]InstrumentingWrapper{
   298  		"A": InstrumentedServiceMakerA,
   299  		"B": InstrumentedServiceMakerB,
   300  		"C": InstrumentedServiceMakerC,
   301  	}
   302  	started := make(map[string]bool)
   303  	stopped := make(map[string]bool)
   304  
   305  	for id, maker := range services {
   306  		id := id // Closure for the constructor
   307  		constructor := func(*ServiceContext) (Service, error) {
   308  			return &InstrumentedService{
   309  				startHook: func(*p2p.Server) { started[id] = true },
   310  				stopHook:  func() { stopped[id] = true },
   311  			}, nil
   312  		}
   313  		if err := stack.Register(maker(constructor)); err != nil {
   314  			t.Fatalf("service %s: registration failed: %v", id, err)
   315  		}
   316  	}
   317  	// Register a service that fails to start
   318  	failure := errors.New("fail")
   319  	failer := func(*ServiceContext) (Service, error) {
   320  		return &InstrumentedService{
   321  			start: failure,
   322  		}, nil
   323  	}
   324  	if err := stack.Register(failer); err != nil {
   325  		t.Fatalf("failer registration failed: %v", err)
   326  	}
   327  	// Start the protocol stack and ensure all started services stop
   328  	for i := 0; i < 100; i++ {
   329  		if err := stack.Start(); err != failure {
   330  			t.Fatalf("iter %d: stack startup failure mismatch: have %v, want %v", i, err, failure)
   331  		}
   332  		for id := range services {
   333  			if started[id] && !stopped[id] {
   334  				t.Fatalf("service %s: started but not stopped", id)
   335  			}
   336  			delete(started, id)
   337  			delete(stopped, id)
   338  		}
   339  	}
   340  }
   341  
   342  // Tests that even if a registered service fails to shut down cleanly, it does
   343  // not influece the rest of the shutdown invocations.
   344  func TestServiceTerminationGuarantee(t *testing.T) {
   345  	stack, err := New(testNodeConfig())
   346  	if err != nil {
   347  		t.Fatalf("failed to create protocol stack: %v", err)
   348  	}
   349  	// Register a batch of good services
   350  	services := map[string]InstrumentingWrapper{
   351  		"A": InstrumentedServiceMakerA,
   352  		"B": InstrumentedServiceMakerB,
   353  		"C": InstrumentedServiceMakerC,
   354  	}
   355  	started := make(map[string]bool)
   356  	stopped := make(map[string]bool)
   357  
   358  	for id, maker := range services {
   359  		id := id // Closure for the constructor
   360  		constructor := func(*ServiceContext) (Service, error) {
   361  			return &InstrumentedService{
   362  				startHook: func(*p2p.Server) { started[id] = true },
   363  				stopHook:  func() { stopped[id] = true },
   364  			}, nil
   365  		}
   366  		if err := stack.Register(maker(constructor)); err != nil {
   367  			t.Fatalf("service %s: registration failed: %v", id, err)
   368  		}
   369  	}
   370  	// Register a service that fails to shot down cleanly
   371  	failure := errors.New("fail")
   372  	failer := func(*ServiceContext) (Service, error) {
   373  		return &InstrumentedService{
   374  			stop: failure,
   375  		}, nil
   376  	}
   377  	if err := stack.Register(failer); err != nil {
   378  		t.Fatalf("failer registration failed: %v", err)
   379  	}
   380  	// Start the protocol stack, and ensure that a failing shut down terminates all
   381  	for i := 0; i < 100; i++ {
   382  		// Start the stack and make sure all is online
   383  		if err := stack.Start(); err != nil {
   384  			t.Fatalf("iter %d: failed to start protocol stack: %v", i, err)
   385  		}
   386  		for id := range services {
   387  			if !started[id] {
   388  				t.Fatalf("iter %d, service %s: service not running", i, id)
   389  			}
   390  			if stopped[id] {
   391  				t.Fatalf("iter %d, service %s: service already stopped", i, id)
   392  			}
   393  		}
   394  		// Stop the stack, verify failure and check all terminations
   395  		err := stack.Stop()
   396  		if err, ok := err.(*StopError); !ok {
   397  			t.Fatalf("iter %d: termination failure mismatch: have %v, want StopError", i, err)
   398  		} else {
   399  			failer := reflect.TypeOf(&InstrumentedService{})
   400  			if err.Services[failer] != failure {
   401  				t.Fatalf("iter %d: failer termination failure mismatch: have %v, want %v", i, err.Services[failer], failure)
   402  			}
   403  			if len(err.Services) != 1 {
   404  				t.Fatalf("iter %d: failure count mismatch: have %d, want %d", i, len(err.Services), 1)
   405  			}
   406  		}
   407  		for id := range services {
   408  			if !stopped[id] {
   409  				t.Fatalf("iter %d, service %s: service not terminated", i, id)
   410  			}
   411  			delete(started, id)
   412  			delete(stopped, id)
   413  		}
   414  	}
   415  }
   416  
   417  // TestServiceRetrieval tests that individual services can be retrieved.
   418  func TestServiceRetrieval(t *testing.T) {
   419  	// Create a simple stack and register two service types
   420  	stack, err := New(testNodeConfig())
   421  	if err != nil {
   422  		t.Fatalf("failed to create protocol stack: %v", err)
   423  	}
   424  	if err := stack.Register(NewNoopService); err != nil {
   425  		t.Fatalf("noop service registration failed: %v", err)
   426  	}
   427  	if err := stack.Register(NewInstrumentedService); err != nil {
   428  		t.Fatalf("instrumented service registration failed: %v", err)
   429  	}
   430  	// Make sure none of the services can be retrieved until started
   431  	var noopServ *NoopService
   432  	if err := stack.Service(&noopServ); err != ErrNodeStopped {
   433  		t.Fatalf("noop service retrieval mismatch: have %v, want %v", err, ErrNodeStopped)
   434  	}
   435  	var instServ *InstrumentedService
   436  	if err := stack.Service(&instServ); err != ErrNodeStopped {
   437  		t.Fatalf("instrumented service retrieval mismatch: have %v, want %v", err, ErrNodeStopped)
   438  	}
   439  	// Start the stack and ensure everything is retrievable now
   440  	if err := stack.Start(); err != nil {
   441  		t.Fatalf("failed to start stack: %v", err)
   442  	}
   443  	defer stack.Stop()
   444  
   445  	if err := stack.Service(&noopServ); err != nil {
   446  		t.Fatalf("noop service retrieval mismatch: have %v, want %v", err, nil)
   447  	}
   448  	if err := stack.Service(&instServ); err != nil {
   449  		t.Fatalf("instrumented service retrieval mismatch: have %v, want %v", err, nil)
   450  	}
   451  }
   452  
   453  // Tests that all protocols defined by individual services get launched.
   454  func TestProtocolGather(t *testing.T) {
   455  	stack, err := New(testNodeConfig())
   456  	if err != nil {
   457  		t.Fatalf("failed to create protocol stack: %v", err)
   458  	}
   459  	// Register a batch of services with some configured number of protocols
   460  	services := map[string]struct {
   461  		Count int
   462  		Maker InstrumentingWrapper
   463  	}{
   464  		"zero": {0, InstrumentedServiceMakerA},
   465  		"one":  {1, InstrumentedServiceMakerB},
   466  		"many": {10, InstrumentedServiceMakerC},
   467  	}
   468  	for id, config := range services {
   469  		protocols := make([]p2p.Protocol, config.Count)
   470  		for i := 0; i < len(protocols); i++ {
   471  			protocols[i].Name = id
   472  			protocols[i].Version = uint(i)
   473  		}
   474  		constructor := func(*ServiceContext) (Service, error) {
   475  			return &InstrumentedService{
   476  				protocols: protocols,
   477  			}, nil
   478  		}
   479  		if err := stack.Register(config.Maker(constructor)); err != nil {
   480  			t.Fatalf("service %s: registration failed: %v", id, err)
   481  		}
   482  	}
   483  	// Start the services and ensure all protocols start successfully
   484  	if err := stack.Start(); err != nil {
   485  		t.Fatalf("failed to start protocol stack: %v", err)
   486  	}
   487  	defer stack.Stop()
   488  
   489  	protocols := stack.Server().Protocols
   490  	if len(protocols) != 11 {
   491  		t.Fatalf("mismatching number of protocols launched: have %d, want %d", len(protocols), 26)
   492  	}
   493  	for id, config := range services {
   494  		for ver := 0; ver < config.Count; ver++ {
   495  			launched := false
   496  			for i := 0; i < len(protocols); i++ {
   497  				if protocols[i].Name == id && protocols[i].Version == uint(ver) {
   498  					launched = true
   499  					break
   500  				}
   501  			}
   502  			if !launched {
   503  				t.Errorf("configured protocol not launched: %s v%d", id, ver)
   504  			}
   505  		}
   506  	}
   507  }
   508  
   509  // Tests that all APIs defined by individual services get exposed.
   510  func TestAPIGather(t *testing.T) {
   511  	stack, err := New(testNodeConfig())
   512  	if err != nil {
   513  		t.Fatalf("failed to create protocol stack: %v", err)
   514  	}
   515  	// Register a batch of services with some configured APIs
   516  	calls := make(chan string, 1)
   517  	makeAPI := func(result string) *OneMethodAPI {
   518  		return &OneMethodAPI{fun: func() { calls <- result }}
   519  	}
   520  	services := map[string]struct {
   521  		APIs  []rpc.API
   522  		Maker InstrumentingWrapper
   523  	}{
   524  		"Zero APIs": {
   525  			[]rpc.API{}, InstrumentedServiceMakerA},
   526  		"Single API": {
   527  			[]rpc.API{
   528  				{Namespace: "single", Version: "1", Service: makeAPI("single.v1"), Public: true},
   529  			}, InstrumentedServiceMakerB},
   530  		"Many APIs": {
   531  			[]rpc.API{
   532  				{Namespace: "multi", Version: "1", Service: makeAPI("multi.v1"), Public: true},
   533  				{Namespace: "multi.v2", Version: "2", Service: makeAPI("multi.v2"), Public: true},
   534  				{Namespace: "multi.v2.nested", Version: "2", Service: makeAPI("multi.v2.nested"), Public: true},
   535  			}, InstrumentedServiceMakerC},
   536  	}
   537  
   538  	for id, config := range services {
   539  		config := config
   540  		constructor := func(*ServiceContext) (Service, error) {
   541  			return &InstrumentedService{apis: config.APIs}, nil
   542  		}
   543  		if err := stack.Register(config.Maker(constructor)); err != nil {
   544  			t.Fatalf("service %s: registration failed: %v", id, err)
   545  		}
   546  	}
   547  	// Start the services and ensure all API start successfully
   548  	if err := stack.Start(); err != nil {
   549  		t.Fatalf("failed to start protocol stack: %v", err)
   550  	}
   551  	defer stack.Stop()
   552  
   553  	// Connect to the RPC server and verify the various registered endpoints
   554  	client, err := stack.Attach()
   555  	if err != nil {
   556  		t.Fatalf("failed to connect to the inproc API server: %v", err)
   557  	}
   558  	defer client.Close()
   559  
   560  	tests := []struct {
   561  		Method string
   562  		Result string
   563  	}{
   564  		{"single_theOneMethod", "single.v1"},
   565  		{"multi_theOneMethod", "multi.v1"},
   566  		{"multi.v2_theOneMethod", "multi.v2"},
   567  		{"multi.v2.nested_theOneMethod", "multi.v2.nested"},
   568  	}
   569  	for i, test := range tests {
   570  		if err := client.Call(nil, test.Method); err != nil {
   571  			t.Errorf("test %d: API request failed: %v", i, err)
   572  		}
   573  		select {
   574  		case result := <-calls:
   575  			if result != test.Result {
   576  				t.Errorf("test %d: result mismatch: have %s, want %s", i, result, test.Result)
   577  			}
   578  		case <-time.After(time.Second):
   579  			t.Fatalf("test %d: rpc execution timeout", i)
   580  		}
   581  	}
   582  }
   583  
   584  // for stubbing purposes
   585  type TestType struct {
   586  	str string
   587  }
   588  
   589  func (sub *TestType) Unsubscribe() {
   590  	// stub
   591  }
   592  
   593  func (sub *TestType) Err() <-chan error {
   594  	return make(chan error, 1)
   595  }
   596  
   597  func TestWhisperChannels(t *testing.T) {
   598  	stack, err := New(testNodeConfig())
   599  	if err != nil {
   600  		t.Fatalf("failed to create protocol stack: %v", err)
   601  	}
   602  	var sub *TestType = &TestType{"foo"}
   603  	messages := make(chan *whisper.Message)
   604  
   605  	// signer of the test messages
   606  	testAddrA := "0x7dA99dF96259305Ee38c9fA9E9D551118B12eC3b"
   607  
   608  	stack.config.WhisperKeys = append(stack.config.WhisperKeys, testAddrA)
   609  	stack.config.WhisperSignersContract = ""
   610  	stack.config.WhisperChannel = make(chan string)
   611  
   612  	go stack.whisperMessageReceiver(sub, messages)
   613  	msg := &whisper.Message{
   614  		// valid signature for "notablockhash" for the testAddr
   615  		Payload: []byte("notablockhash--0x5944a150e7cc2d77cd47d94dfe7665c7921768d4eb8a1479026751e7574e70d37a8b5ba5ec55111572ea30a9c9d9504efebdd8311b7b6bad05c4fd48e51bd3841c"),
   616  	}
   617  
   618  	messages <- msg
   619  	resp := <-stack.config.WhisperChannel
   620  	if "notablockhash" != resp {
   621  		t.Errorf("result mismatch: have %s, want %s", resp, testAddrA)
   622  	}
   623  }
   624  
   625  func TestCheckContractAdminStatus(t *testing.T) {
   626  	key0, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
   627  	addr0 := crypto.PubkeyToAddress(key0.PublicKey)
   628  	deployTransactor := bind.NewKeyedTransactor(key0)
   629  	backend := backends.NewSimulatedBackend(core.GenesisAlloc{addr0: {Balance: big.NewInt(1000000000)}}, 10000000)
   630  	addr, _, _, err := shyft_contracts.DeployValidSigners(deployTransactor, backend)
   631  	if err != nil {
   632  		t.Errorf("Deploy Valid Signers Contract failed %+v \n", err)
   633  	}
   634  	t.Log("add is ", addr)
   635  	stack, err := New(testNodeConfig())
   636  	if err != nil {
   637  		t.Fatalf("failed to create protocol stack: %v", err)
   638  	}
   639  	result := stack.CheckContractAdminStatus(addr0, backend)
   640  
   641  	if result {
   642  		t.Errorf("result mismatch: have %v, want %v", result, false)
   643  	}
   644  }