rpc/server: add notification subscription

Note that the protocol differs a bit from #895 in its notifications format,
to avoid additional server-side processing we're omitting some metadata like:
 * block size and confirmations
 * transaction fees, confirmations, block hash and timestamp
 * application execution doesn't have ScriptHash populated

Some block fields may also differ in encoding compared to `getblock` results
(like nonce field).

I think these differences are unnoticieable for most use cases, so we can
leave them as is, but it can be changed in the future.
This commit is contained in:
Roman Khimov 2020-05-11 01:00:19 +03:00
parent 03ecab5eec
commit fc22a46a4c
7 changed files with 688 additions and 24 deletions

View file

@ -14,12 +14,11 @@ import (
"github.com/nspcc-dev/neo-go/pkg/network"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
"go.uber.org/zap/zaptest"
)
func initServerWithInMemoryChain(t *testing.T) (*core.Blockchain, *Server, *httptest.Server) {
var nBlocks uint32
func getUnitTestChain(t *testing.T) (*core.Blockchain, config.Config, *zap.Logger) {
net := config.ModeUnitTestNet
configPath := "../../../config"
cfg, err := config.Load(configPath, net)
@ -32,6 +31,10 @@ func initServerWithInMemoryChain(t *testing.T) (*core.Blockchain, *Server, *http
go chain.Run()
return chain, cfg, logger
}
func getTestBlocks(t *testing.T) []*block.Block {
// File "./testdata/testblocks.acc" was generated by function core._
// ("neo-go/pkg/core/helper_test.go").
// To generate new "./testdata/testblocks.acc", follow the steps:
@ -41,15 +44,21 @@ func initServerWithInMemoryChain(t *testing.T) (*core.Blockchain, *Server, *http
f, err := os.Open("testdata/testblocks.acc")
require.Nil(t, err)
br := io.NewBinReaderFromIO(f)
nBlocks = br.ReadU32LE()
nBlocks := br.ReadU32LE()
require.Nil(t, br.Err)
blocks := make([]*block.Block, 0, int(nBlocks))
for i := 0; i < int(nBlocks); i++ {
_ = br.ReadU32LE()
b := &block.Block{}
b.DecodeBinary(br)
require.Nil(t, br.Err)
require.NoError(t, chain.AddBlock(b))
blocks = append(blocks, b)
}
return blocks
}
func initClearServerWithInMemoryChain(t *testing.T) (*core.Blockchain, *Server, *httptest.Server) {
chain, cfg, logger := getUnitTestChain(t)
serverConfig := network.NewServerConfig(cfg)
server, err := network.NewServer(serverConfig, chain, logger)
@ -64,6 +73,15 @@ func initServerWithInMemoryChain(t *testing.T) (*core.Blockchain, *Server, *http
return chain, &rpcServer, srv
}
func initServerWithInMemoryChain(t *testing.T) (*core.Blockchain, *Server, *httptest.Server) {
chain, rpcServer, srv := initClearServerWithInMemoryChain(t)
for _, b := range getTestBlocks(t) {
require.NoError(t, chain.AddBlock(b))
}
return chain, rpcServer, srv
}
type FeerStub struct{}
func (fs *FeerStub) IsLowPriority(util.Fixed8) bool {