github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/services/rpcsrv/server_helper_test.go (about) 1 package rpcsrv 2 3 import ( 4 "fmt" 5 "math/big" 6 "net/http" 7 "net/http/httptest" 8 "os" 9 "testing" 10 11 "github.com/nspcc-dev/neo-go/pkg/config" 12 "github.com/nspcc-dev/neo-go/pkg/config/netmode" 13 "github.com/nspcc-dev/neo-go/pkg/core" 14 "github.com/nspcc-dev/neo-go/pkg/core/block" 15 "github.com/nspcc-dev/neo-go/pkg/core/interop" 16 "github.com/nspcc-dev/neo-go/pkg/core/native" 17 "github.com/nspcc-dev/neo-go/pkg/core/storage" 18 "github.com/nspcc-dev/neo-go/pkg/io" 19 "github.com/nspcc-dev/neo-go/pkg/network" 20 "github.com/nspcc-dev/neo-go/pkg/services/oracle" 21 "github.com/nspcc-dev/neo-go/pkg/util" 22 "github.com/stretchr/testify/require" 23 "go.uber.org/zap" 24 "go.uber.org/zap/zaptest" 25 ) 26 27 const ( 28 notaryPath = "../notary/testdata/notary1.json" 29 notaryPass = "one" 30 ) 31 32 func getUnitTestChain(t testing.TB, enableOracle bool, enableNotary bool, disableIteratorSessions bool) (*core.Blockchain, OracleHandler, config.Config, *zap.Logger) { 33 return getUnitTestChainWithCustomConfig(t, enableOracle, enableNotary, func(cfg *config.Config) { 34 if disableIteratorSessions { 35 cfg.ApplicationConfiguration.RPC.SessionEnabled = false 36 } 37 if enableNotary { 38 cfg.ProtocolConfiguration.P2PSigExtensions = true 39 cfg.ProtocolConfiguration.P2PNotaryRequestPayloadPoolSize = 1000 40 cfg.ApplicationConfiguration.P2PNotary = config.P2PNotary{ 41 Enabled: true, 42 UnlockWallet: config.Wallet{ 43 Path: notaryPath, 44 Password: notaryPass, 45 }, 46 } 47 } else { 48 cfg.ApplicationConfiguration.P2PNotary.Enabled = false 49 } 50 if enableOracle { 51 cfg.ApplicationConfiguration.Oracle.Enabled = true 52 cfg.ApplicationConfiguration.Oracle.UnlockWallet = config.Wallet{ 53 Path: "../oracle/testdata/oracle1.json", 54 Password: "one", 55 } 56 } 57 }) 58 } 59 func getUnitTestChainWithCustomConfig(t testing.TB, enableOracle bool, enableNotary bool, customCfg func(configuration *config.Config)) (*core.Blockchain, OracleHandler, config.Config, *zap.Logger) { 60 net := netmode.UnitTestNet 61 configPath := "../../../config" 62 cfg, err := config.Load(configPath, net) 63 require.NoError(t, err, "could not load config") 64 if customCfg != nil { 65 customCfg(&cfg) 66 } 67 68 memoryStore := storage.NewMemoryStore() 69 logger := zaptest.NewLogger(t) 70 chain, err := core.NewBlockchain(memoryStore, cfg.Blockchain(), logger) 71 require.NoError(t, err, "could not create chain") 72 73 var orc OracleHandler 74 if enableOracle { 75 orc, err = oracle.NewOracle(oracle.Config{ 76 Log: logger, 77 Network: netmode.UnitTestNet, 78 MainCfg: cfg.ApplicationConfiguration.Oracle, 79 Chain: chain, 80 }) 81 require.NoError(t, err) 82 chain.SetOracle(orc.(*oracle.Oracle)) 83 } 84 85 go chain.Run() 86 t.Cleanup(chain.Close) 87 88 return chain, orc, cfg, logger 89 } 90 91 func getTestBlocks(t *testing.T) []*block.Block { 92 // File "./testdata/testblocks.acc" was generated by function core.TestCreateBasicChain 93 // ("neo-go/pkg/core/helper_test.go"). 94 // To generate new "./testdata/testblocks.acc", follow the steps: 95 // 1. Rename the function 96 // 2. Add specific test-case into "neo-go/pkg/core/blockchain_test.go" 97 // 3. Run tests with `$ make test` 98 f, err := os.Open("testdata/testblocks.acc") 99 require.Nil(t, err) 100 br := io.NewBinReaderFromIO(f) 101 nBlocks := br.ReadU32LE() 102 require.Nil(t, br.Err) 103 blocks := make([]*block.Block, 0, int(nBlocks)) 104 for i := 0; i < int(nBlocks); i++ { 105 _ = br.ReadU32LE() 106 b := block.New(false) 107 b.DecodeBinary(br) 108 require.Nil(t, br.Err) 109 blocks = append(blocks, b) 110 } 111 return blocks 112 } 113 114 func initClearServerWithServices(t testing.TB, needOracle bool, needNotary bool, disableIteratorsSessions bool) (*core.Blockchain, *Server, *httptest.Server) { 115 chain, orc, cfg, logger := getUnitTestChain(t, needOracle, needNotary, disableIteratorsSessions) 116 return wrapUnitTestChain(t, chain, orc, cfg, logger) 117 } 118 119 func wrapUnitTestChain(t testing.TB, chain *core.Blockchain, orc OracleHandler, cfg config.Config, logger *zap.Logger) (*core.Blockchain, *Server, *httptest.Server) { 120 serverConfig, err := network.NewServerConfig(cfg) 121 require.NoError(t, err) 122 serverConfig.UserAgent = fmt.Sprintf(config.UserAgentFormat, "0.98.6-test") 123 serverConfig.Addresses = []config.AnnounceableAddress{{Address: ":0"}} 124 server, err := network.NewServer(serverConfig, chain, chain.GetStateSyncModule(), logger) 125 require.NoError(t, err) 126 errCh := make(chan error, 2) 127 rpcServer := New(chain, cfg.ApplicationConfiguration.RPC, server, orc, logger, errCh) 128 rpcServer.Start() 129 t.Cleanup(rpcServer.Shutdown) 130 131 handler := http.HandlerFunc(rpcServer.handleHTTPRequest) 132 srv := httptest.NewServer(handler) 133 t.Cleanup(srv.Close) 134 return chain, &rpcServer, srv 135 } 136 137 func initClearServerWithCustomConfig(t testing.TB, ccfg func(configuration *config.Config)) (*core.Blockchain, *Server, *httptest.Server) { 138 chain, orc, cfg, logger := getUnitTestChainWithCustomConfig(t, false, false, ccfg) 139 return wrapUnitTestChain(t, chain, orc, cfg, logger) 140 } 141 142 func initClearServerWithInMemoryChain(t testing.TB) (*core.Blockchain, *Server, *httptest.Server) { 143 return initClearServerWithServices(t, false, true, false) 144 } 145 146 func initServerWithInMemoryChain(t *testing.T) (*core.Blockchain, *Server, *httptest.Server) { 147 chain, rpcServer, srv := initClearServerWithInMemoryChain(t) 148 149 for _, b := range getTestBlocks(t) { 150 require.NoError(t, chain.AddBlock(b)) 151 } 152 return chain, rpcServer, srv 153 } 154 155 func initServerWithInMemoryChainAndServices(t *testing.T, needOracle bool, needNotary bool, disableIteratorSessions bool) (*core.Blockchain, *Server, *httptest.Server) { 156 chain, rpcServer, srv := initClearServerWithServices(t, needOracle, needNotary, disableIteratorSessions) 157 158 for _, b := range getTestBlocks(t) { 159 require.NoError(t, chain.AddBlock(b)) 160 } 161 return chain, rpcServer, srv 162 } 163 164 type FeerStub struct{} 165 166 func (fs *FeerStub) FeePerByte() int64 { 167 return 0 168 } 169 170 func (fs *FeerStub) BlockHeight() uint32 { 171 return 0 172 } 173 174 func (fs *FeerStub) GetUtilityTokenBalance(acc util.Uint160) *big.Int { 175 return big.NewInt(1000000 * native.GASFactor) 176 } 177 178 func (fs FeerStub) GetBaseExecFee() int64 { 179 return interop.DefaultBaseExecFee 180 }