github.com/ylsGit/go-ethereum@v1.6.5/node/utils_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 // Contains a batch of utility type declarations used by the tests. As the node 18 // operates on unique types, a lot of them are needed to check various features. 19 20 package node 21 22 import ( 23 "reflect" 24 25 "github.com/ethereum/go-ethereum/p2p" 26 "github.com/ethereum/go-ethereum/rpc" 27 ) 28 29 // NoopService is a trivial implementation of the Service interface. 30 type NoopService struct{} 31 32 func (s *NoopService) Protocols() []p2p.Protocol { return nil } 33 func (s *NoopService) APIs() []rpc.API { return nil } 34 func (s *NoopService) Start(*p2p.Server) error { return nil } 35 func (s *NoopService) Stop() error { return nil } 36 37 func NewNoopService(*ServiceContext) (Service, error) { return new(NoopService), nil } 38 39 // Set of services all wrapping the base NoopService resulting in the same method 40 // signatures but different outer types. 41 type NoopServiceA struct{ NoopService } 42 type NoopServiceB struct{ NoopService } 43 type NoopServiceC struct{ NoopService } 44 type NoopServiceD struct{ NoopService } 45 46 func NewNoopServiceA(*ServiceContext) (Service, error) { return new(NoopServiceA), nil } 47 func NewNoopServiceB(*ServiceContext) (Service, error) { return new(NoopServiceB), nil } 48 func NewNoopServiceC(*ServiceContext) (Service, error) { return new(NoopServiceC), nil } 49 func NewNoopServiceD(*ServiceContext) (Service, error) { return new(NoopServiceD), nil } 50 51 // InstrumentedService is an implementation of Service for which all interface 52 // methods can be instrumented both return value as well as event hook wise. 53 type InstrumentedService struct { 54 protocols []p2p.Protocol 55 apis []rpc.API 56 start error 57 stop error 58 59 protocolsHook func() 60 startHook func(*p2p.Server) 61 stopHook func() 62 } 63 64 func NewInstrumentedService(*ServiceContext) (Service, error) { return new(InstrumentedService), nil } 65 66 func (s *InstrumentedService) Protocols() []p2p.Protocol { 67 if s.protocolsHook != nil { 68 s.protocolsHook() 69 } 70 return s.protocols 71 } 72 73 func (s *InstrumentedService) APIs() []rpc.API { 74 return s.apis 75 } 76 77 func (s *InstrumentedService) Start(server *p2p.Server) error { 78 if s.startHook != nil { 79 s.startHook(server) 80 } 81 return s.start 82 } 83 84 func (s *InstrumentedService) Stop() error { 85 if s.stopHook != nil { 86 s.stopHook() 87 } 88 return s.stop 89 } 90 91 // InstrumentingWrapper is a method to specialize a service constructor returning 92 // a generic InstrumentedService into one returning a wrapping specific one. 93 type InstrumentingWrapper func(base ServiceConstructor) ServiceConstructor 94 95 func InstrumentingWrapperMaker(base ServiceConstructor, kind reflect.Type) ServiceConstructor { 96 return func(ctx *ServiceContext) (Service, error) { 97 obj, err := base(ctx) 98 if err != nil { 99 return nil, err 100 } 101 wrapper := reflect.New(kind) 102 wrapper.Elem().Field(0).Set(reflect.ValueOf(obj).Elem()) 103 104 return wrapper.Interface().(Service), nil 105 } 106 } 107 108 // Set of services all wrapping the base InstrumentedService resulting in the 109 // same method signatures but different outer types. 110 type InstrumentedServiceA struct{ InstrumentedService } 111 type InstrumentedServiceB struct{ InstrumentedService } 112 type InstrumentedServiceC struct{ InstrumentedService } 113 114 func InstrumentedServiceMakerA(base ServiceConstructor) ServiceConstructor { 115 return InstrumentingWrapperMaker(base, reflect.TypeOf(InstrumentedServiceA{})) 116 } 117 118 func InstrumentedServiceMakerB(base ServiceConstructor) ServiceConstructor { 119 return InstrumentingWrapperMaker(base, reflect.TypeOf(InstrumentedServiceB{})) 120 } 121 122 func InstrumentedServiceMakerC(base ServiceConstructor) ServiceConstructor { 123 return InstrumentingWrapperMaker(base, reflect.TypeOf(InstrumentedServiceC{})) 124 } 125 126 // OneMethodApi is a single-method API handler to be returned by test services. 127 type OneMethodApi struct { 128 fun func() 129 } 130 131 func (api *OneMethodApi) TheOneMethod() { 132 if api.fun != nil { 133 api.fun() 134 } 135 }