From ddb23ccf785bd20311b7f8f37e9944b0fd1420ff Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Fri, 14 Jan 2022 02:09:16 +0300 Subject: [PATCH] core: shrink blockchainer.StateRoot further, leave simple RO methods --- cli/server/server.go | 4 ++- pkg/core/blockchainer/state_root.go | 4 --- pkg/core/stateroot_test.go | 42 ++++++++++++++--------------- pkg/services/stateroot/service.go | 9 +++---- 4 files changed, 27 insertions(+), 32 deletions(-) diff --git a/cli/server/server.go b/cli/server/server.go index e515cbf09..21156cec8 100644 --- a/cli/server/server.go +++ b/cli/server/server.go @@ -14,6 +14,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/core" "github.com/nspcc-dev/neo-go/pkg/core/block" "github.com/nspcc-dev/neo-go/pkg/core/chaindump" + corestate "github.com/nspcc-dev/neo-go/pkg/core/stateroot" "github.com/nspcc-dev/neo-go/pkg/core/storage" "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/io" @@ -413,7 +414,8 @@ func startServer(ctx *cli.Context) error { if err != nil { return cli.NewExitError(fmt.Errorf("failed to create network server: %w", err), 1) } - sr, err := stateroot.New(serverConfig.StateRootCfg, log, chain, serv.BroadcastExtensible) + srMod := chain.GetStateModule().(*corestate.Module) // Take full responsibility here. + sr, err := stateroot.New(serverConfig.StateRootCfg, srMod, log, chain, serv.BroadcastExtensible) if err != nil { return cli.NewExitError(fmt.Errorf("can't initialize StateRoot service: %w", err), 1) } diff --git a/pkg/core/blockchainer/state_root.go b/pkg/core/blockchainer/state_root.go index 69bff1817..0328c3a63 100644 --- a/pkg/core/blockchainer/state_root.go +++ b/pkg/core/blockchainer/state_root.go @@ -3,13 +3,11 @@ package blockchainer import ( "github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/core/storage" - "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/util" ) // StateRoot represents local state root module. type StateRoot interface { - AddStateRoot(root *state.MPTRoot) error CurrentLocalHeight() uint32 CurrentLocalStateRoot() util.Uint256 CurrentValidatedHeight() uint32 @@ -17,6 +15,4 @@ type StateRoot interface { GetState(root util.Uint256, key []byte) ([]byte, error) GetStateProof(root util.Uint256, key []byte) ([][]byte, error) GetStateRoot(height uint32) (*state.MPTRoot, error) - GetStateValidators(height uint32) keys.PublicKeys - SetUpdateValidatorsCallback(func(uint32, keys.PublicKeys)) } diff --git a/pkg/core/stateroot_test.go b/pkg/core/stateroot_test.go index 014d250b6..29777f457 100644 --- a/pkg/core/stateroot_test.go +++ b/pkg/core/stateroot_test.go @@ -80,32 +80,32 @@ func TestStateRoot(t *testing.T) { tmpDir := t.TempDir() w := createAndWriteWallet(t, accs[0], filepath.Join(tmpDir, "w"), "pass") cfg := createStateRootConfig(w.Path(), "pass") - srv, err := stateroot.New(cfg, zaptest.NewLogger(t), bc, nil) + srv, err := stateroot.New(cfg, bc.stateRoot, zaptest.NewLogger(t), bc, nil) require.NoError(t, err) - require.EqualValues(t, 0, srv.CurrentValidatedHeight()) - r, err := srv.GetStateRoot(bc.BlockHeight()) + require.EqualValues(t, 0, bc.stateRoot.CurrentValidatedHeight()) + r, err := bc.stateRoot.GetStateRoot(bc.BlockHeight()) require.NoError(t, err) - require.Equal(t, r.Root, srv.CurrentLocalStateRoot()) + require.Equal(t, r.Root, bc.stateRoot.CurrentLocalStateRoot()) t.Run("invalid message", func(t *testing.T) { require.Error(t, srv.OnPayload(&payload.Extensible{Data: []byte{42}})) - require.EqualValues(t, 0, srv.CurrentValidatedHeight()) + require.EqualValues(t, 0, bc.stateRoot.CurrentValidatedHeight()) }) t.Run("drop zero index", func(t *testing.T) { - r, err := srv.GetStateRoot(0) + r, err := bc.stateRoot.GetStateRoot(0) require.NoError(t, err) data, err := testserdes.EncodeBinary(stateroot.NewMessage(stateroot.RootT, r)) require.NoError(t, err) require.NoError(t, srv.OnPayload(&payload.Extensible{Data: data})) - require.EqualValues(t, 0, srv.CurrentValidatedHeight()) + require.EqualValues(t, 0, bc.stateRoot.CurrentValidatedHeight()) }) t.Run("invalid height", func(t *testing.T) { - r, err := srv.GetStateRoot(1) + r, err := bc.stateRoot.GetStateRoot(1) require.NoError(t, err) r.Index = 10 data := testSignStateRoot(t, r, pubs, accs...) require.Error(t, srv.OnPayload(&payload.Extensible{Data: data})) - require.EqualValues(t, 0, srv.CurrentValidatedHeight()) + require.EqualValues(t, 0, bc.stateRoot.CurrentValidatedHeight()) }) t.Run("invalid signer", func(t *testing.T) { accInv, err := wallet.NewAccount() @@ -113,21 +113,21 @@ func TestStateRoot(t *testing.T) { pubs := keys.PublicKeys{accInv.PrivateKey().PublicKey()} require.NoError(t, accInv.ConvertMultisig(1, pubs)) transferTokenFromMultisigAccount(t, bc, accInv.Contract.ScriptHash(), bc.contracts.GAS.Hash, 1_0000_0000) - r, err := srv.GetStateRoot(1) + r, err := bc.stateRoot.GetStateRoot(1) require.NoError(t, err) data := testSignStateRoot(t, r, pubs, accInv) err = srv.OnPayload(&payload.Extensible{Data: data}) require.True(t, errors.Is(err, ErrWitnessHashMismatch), "got: %v", err) - require.EqualValues(t, 0, srv.CurrentValidatedHeight()) + require.EqualValues(t, 0, bc.stateRoot.CurrentValidatedHeight()) }) - r, err = srv.GetStateRoot(updateIndex + 1) + r, err = bc.stateRoot.GetStateRoot(updateIndex + 1) require.NoError(t, err) data := testSignStateRoot(t, r, pubs, accs...) require.NoError(t, srv.OnPayload(&payload.Extensible{Data: data})) - require.EqualValues(t, 2, srv.CurrentValidatedHeight()) + require.EqualValues(t, 2, bc.stateRoot.CurrentValidatedHeight()) - r, err = srv.GetStateRoot(updateIndex + 1) + r, err = bc.stateRoot.GetStateRoot(updateIndex + 1) require.NoError(t, err) require.NotEqual(t, 0, len(r.Witness)) require.Equal(t, h, r.Witness[0].ScriptHash()) @@ -148,14 +148,14 @@ func TestStateRootInitNonZeroHeight(t *testing.T) { tmpDir := t.TempDir() w := createAndWriteWallet(t, accs[0], filepath.Join(tmpDir, "w"), "pass") cfg := createStateRootConfig(w.Path(), "pass") - srv, err := stateroot.New(cfg, zaptest.NewLogger(t), bc, nil) + srv, err := stateroot.New(cfg, bc.stateRoot, zaptest.NewLogger(t), bc, nil) require.NoError(t, err) - r, err := srv.GetStateRoot(2) + r, err := bc.stateRoot.GetStateRoot(2) require.NoError(t, err) data := testSignStateRoot(t, r, pubs, accs...) require.NoError(t, srv.OnPayload(&payload.Extensible{Data: data})) - require.EqualValues(t, 2, srv.CurrentValidatedHeight()) - root = srv.CurrentLocalStateRoot() + require.EqualValues(t, 2, bc.stateRoot.CurrentValidatedHeight()) + root = bc.stateRoot.CurrentLocalStateRoot() }) bc2 := newTestChainWithCustomCfgAndStore(t, st, nil) @@ -194,7 +194,7 @@ func TestStateRootFull(t *testing.T) { var lastValidated atomic.Value var lastHeight atomic.Uint32 - srv, err := stateroot.New(cfg, zaptest.NewLogger(t), bc, func(ep *payload.Extensible) { + srv, err := stateroot.New(cfg, bc.stateRoot, zaptest.NewLogger(t), bc, func(ep *payload.Extensible) { lastHeight.Store(ep.ValidBlockStart) lastValidated.Store(ep) }) @@ -211,7 +211,7 @@ func TestStateRootFull(t *testing.T) { require.Eventually(t, func() bool { return lastHeight.Load() == 3 }, time.Second, time.Millisecond) checkVoteBroadcasted(t, bc, lastValidated.Load().(*payload.Extensible), 3, 1) - r, err := srv.GetStateRoot(2) + r, err := bc.stateRoot.GetStateRoot(2) require.NoError(t, err) require.NoError(t, srv.AddSignature(2, 0, accs[0].PrivateKey().SignHashable(uint32(netmode.UnitTestNet), r))) require.NotNil(t, lastValidated.Load().(*payload.Extensible)) @@ -220,7 +220,7 @@ func TestStateRootFull(t *testing.T) { require.NoError(t, testserdes.DecodeBinary(lastValidated.Load().(*payload.Extensible).Data, msg)) require.NotEqual(t, stateroot.RootT, msg.Type) // not a sender for this root - r, err = srv.GetStateRoot(3) + r, err = bc.stateRoot.GetStateRoot(3) require.NoError(t, err) require.Error(t, srv.AddSignature(2, 0, accs[0].PrivateKey().SignHashable(uint32(netmode.UnitTestNet), r))) require.NoError(t, srv.AddSignature(3, 0, accs[0].PrivateKey().SignHashable(uint32(netmode.UnitTestNet), r))) diff --git a/pkg/services/stateroot/service.go b/pkg/services/stateroot/service.go index b26e4d417..8da2ae13d 100644 --- a/pkg/services/stateroot/service.go +++ b/pkg/services/stateroot/service.go @@ -8,7 +8,6 @@ import ( "github.com/nspcc-dev/neo-go/pkg/config" "github.com/nspcc-dev/neo-go/pkg/config/netmode" "github.com/nspcc-dev/neo-go/pkg/core/block" - "github.com/nspcc-dev/neo-go/pkg/core/blockchainer" "github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/core/stateroot" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" @@ -22,7 +21,6 @@ type ( // Ledger is the interface to Blockchain sufficient for Service. Ledger interface { GetConfig() config.ProtocolConfiguration - GetStateModule() blockchainer.StateRoot HeaderHeight() uint32 SubscribeForBlocks(ch chan<- *block.Block) UnsubscribeFromBlocks(ch chan<- *block.Block) @@ -30,7 +28,6 @@ type ( // Service represents state root service. Service interface { - blockchainer.StateRoot OnPayload(p *payload.Extensible) error AddSignature(height uint32, validatorIndex int32, sig []byte) error GetConfig() config.StateRoot @@ -39,7 +36,7 @@ type ( } service struct { - blockchainer.StateRoot + *stateroot.Module chain Ledger MainCfg config.StateRoot @@ -69,10 +66,10 @@ const ( ) // New returns new state root service instance using underlying module. -func New(cfg config.StateRoot, log *zap.Logger, bc Ledger, cb RelayCallback) (Service, error) { +func New(cfg config.StateRoot, sm *stateroot.Module, log *zap.Logger, bc Ledger, cb RelayCallback) (Service, error) { bcConf := bc.GetConfig() s := &service{ - StateRoot: bc.GetStateModule(), + Module: sm, Network: bcConf.Magic, chain: bc, log: log,