Skip to content

Commit 16fcfc8

Browse files
committed
services: adjust StateRoot service initialisation
Perform initialisation of StateRoot service with designated StateValidator's node list in the service constructor. There's no need to wait until the next role update event, and it may lead to inaccuraces in service work on SIGHUP/server restart. A part of #3228. Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
1 parent 4d1e96e commit 16fcfc8

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

pkg/services/stateroot/service.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ package stateroot
22

33
import (
44
"errors"
5+
"fmt"
56
"sync"
67
"sync/atomic"
78
"time"
89

910
"github.com/nspcc-dev/neo-go/pkg/config"
1011
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
1112
"github.com/nspcc-dev/neo-go/pkg/core/block"
13+
"github.com/nspcc-dev/neo-go/pkg/core/native/noderoles"
1214
"github.com/nspcc-dev/neo-go/pkg/core/state"
1315
"github.com/nspcc-dev/neo-go/pkg/core/stateroot"
1416
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
@@ -22,6 +24,7 @@ type (
2224
// Ledger is an interface to Blockchain sufficient for Service.
2325
Ledger interface {
2426
GetConfig() config.Blockchain
27+
GetDesignatedByRole(role noderoles.Role) (keys.PublicKeys, uint32, error)
2528
HeaderHeight() uint32
2629
SubscribeForBlocks(ch chan *block.Block)
2730
UnsubscribeFromBlocks(ch chan *block.Block)
@@ -40,6 +43,10 @@ type (
4043
// to Shutdown on the same instance are no-op. The instance that was stopped can
4144
// not be started again by calling Start (use a new instance if needed).
4245
Shutdown()
46+
// IsAuthorized returns whether state root service currently is authorized to sign
47+
// state roots. It returns true iff designated StateValidator node's account
48+
// provided to the state root service in decrypted state.
49+
IsAuthorized() bool
4350
}
4451

4552
service struct {
@@ -116,6 +123,12 @@ func New(cfg config.StateRoot, sm *stateroot.Module, log *zap.Logger, bc Ledger,
116123
return nil, errors.New("no wallet account could be unlocked")
117124
}
118125

126+
keys, h, err := bc.GetDesignatedByRole(noderoles.StateValidator)
127+
if err != nil {
128+
return nil, fmt.Errorf("failed to get designated StateValidators: %w", err)
129+
}
130+
s.updateValidators(h, keys)
131+
119132
s.SetUpdateValidatorsCallback(s.updateValidators)
120133
}
121134
return s, nil
@@ -173,3 +186,9 @@ func (s *service) updateValidators(height uint32, pubs keys.PublicKeys) {
173186
}
174187
}
175188
}
189+
190+
// IsAuthorized implements Service interface.
191+
func (s *service) IsAuthorized() bool {
192+
_, acc := s.getAccount()
193+
return acc != nil
194+
}

pkg/services/stateroot/service_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,25 @@ func TestStateRoot(t *testing.T) {
148148
require.Equal(t, h, r.Witness[0].ScriptHash())
149149
}
150150

151+
func TestStateRoot_GenesisRole(t *testing.T) {
152+
_, _, accs := newMajorityMultisigWithGAS(t, 2)
153+
154+
bc, _, _ := chain.NewMultiWithCustomConfig(t, func(c *config.Blockchain) {
155+
c.Genesis.Roles = map[noderoles.Role]keys.PublicKeys{
156+
noderoles.StateValidator: {accs[0].PublicKey(), accs[1].PublicKey()},
157+
}
158+
})
159+
160+
tmpDir := t.TempDir()
161+
w := createAndWriteWallet(t, accs[0], filepath.Join(tmpDir, "w"), "pass")
162+
cfg := createStateRootConfig(w.Path(), "pass")
163+
srMod := bc.GetStateModule().(*corestate.Module) // Take full responsibility here.
164+
srv, err := stateroot.New(cfg, srMod, zaptest.NewLogger(t), bc, nil)
165+
require.NoError(t, err)
166+
167+
require.True(t, srv.IsAuthorized())
168+
}
169+
151170
type memoryStore struct {
152171
*storage.MemoryStore
153172
}

0 commit comments

Comments
 (0)