config: add TimePerBlock to replace SecondsPerBlock

It's more generic and convenient than MillisecondsPerBlock. This setting is
made in backwards-compatible fashion, but it'll override SecondsPerBlock if
both are used. Configurations are specifically not changed here, it's
important to check compatibility.

Fixes #2675.
This commit is contained in:
Roman Khimov 2022-12-02 19:10:45 +03:00
parent f6a9969fa8
commit c2adbf768b
13 changed files with 70 additions and 28 deletions

View file

@ -92,3 +92,13 @@ used instead (that also have a counter).
It's not a frequently used thing and it's easy to replace it, so removal of It's not a frequently used thing and it's easy to replace it, so removal of
old counters is scheduled for January-February 2023 (~0.100.X release). old counters is scheduled for January-February 2023 (~0.100.X release).
## SecondsPerBlock protocol configuration
With 0.100.0 version SecondsPerBlock protocol configuration setting was
deprecated and replaced by a bit more generic and precise TimePerBlock
(allowing for subsecond time). An informational message is printed on node
startup to inform about this, it's very easy to deal with this configuration
change, just replace one line.
Removal of SecondsPerBlock is scheduled for May-June 2023 (~0.103.0 release).

View file

@ -197,7 +197,7 @@ where:
enable `SessionBackedByMPT`, see `SessionBackedByMPT` documentation for more enable `SessionBackedByMPT`, see `SessionBackedByMPT` documentation for more
details. details.
- `SessionExpirationTime` is a lifetime of iterator session in seconds. It is set - `SessionExpirationTime` is a lifetime of iterator session in seconds. It is set
to `SecondsPerBlock` seconds by default and is relevant only if `SessionEnabled` to `TimePerBlock` seconds by default and is relevant only if `SessionEnabled`
is set to `true`. is set to `true`.
- `SessionBackedByMPT` is a flag forcing JSON-RPC server into using MPT-backed - `SessionBackedByMPT` is a flag forcing JSON-RPC server into using MPT-backed
storage for delayed iterator traversal. If `true`, then iterator resources got storage for delayed iterator traversal. If `true`, then iterator resources got
@ -275,11 +275,12 @@ protocol-related settings described in the table below.
| RemoveUntraceableBlocks | `bool`| `false` | Denotes whether old blocks should be removed from cache and database. If enabled, then only the last `MaxTraceableBlocks` are stored and accessible to smart contracts. Old MPT data is also deleted in accordance with `GarbageCollectionPeriod` setting. If enabled along with `P2PStateExchangeExtensions`, then old blocks and MPT states will be removed up to the second latest state synchronisation point (see `StateSyncInterval`). | | RemoveUntraceableBlocks | `bool`| `false` | Denotes whether old blocks should be removed from cache and database. If enabled, then only the last `MaxTraceableBlocks` are stored and accessible to smart contracts. Old MPT data is also deleted in accordance with `GarbageCollectionPeriod` setting. If enabled along with `P2PStateExchangeExtensions`, then old blocks and MPT states will be removed up to the second latest state synchronisation point (see `StateSyncInterval`). |
| ReservedAttributes | `bool` | `false` | Allows to have reserved attributes range for experimental or private purposes. | | ReservedAttributes | `bool` | `false` | Allows to have reserved attributes range for experimental or private purposes. |
| SaveStorageBatch | `bool` | `false` | Enables storage batch saving before every persist. It is similar to StorageDump plugin for C# node. | | SaveStorageBatch | `bool` | `false` | Enables storage batch saving before every persist. It is similar to StorageDump plugin for C# node. |
| SecondsPerBlock | `int` | `15` | Minimal time that should pass before next block is accepted. | | SecondsPerBlock | `int` | `15` | Minimal time that should pass before next block is accepted. Deprecated: please use TimePerBlock setting (which overrides anything set here), SecondsPerBlock will be removed in future versions. |
| SeedList | `[]string` | [] | List of initial nodes addresses used to establish connectivity. | | SeedList | `[]string` | [] | List of initial nodes addresses used to establish connectivity. |
| StandbyCommittee | `[]string` | [] | List of public keys of standby committee validators are chosen from. | | StandbyCommittee | `[]string` | [] | List of public keys of standby committee validators are chosen from. |
| StateRootInHeader | `bool` | `false` | Enables storing state root in block header. | Experimental protocol extension! | | StateRootInHeader | `bool` | `false` | Enables storing state root in block header. | Experimental protocol extension! |
| StateSyncInterval | `int` | `40000` | The number of blocks between state heights available for MPT state data synchronization. | `P2PStateExchangeExtensions` should be enabled to use this setting. | | StateSyncInterval | `int` | `40000` | The number of blocks between state heights available for MPT state data synchronization. | `P2PStateExchangeExtensions` should be enabled to use this setting. |
| TimePerBlock | `Duration` | `15s` | Minimal (and targeted for) time interval between blocks. Must be an integer number of milliseconds. |
| ValidatorsCount | `int` | `0` | Number of validators set for the whole network lifetime, can't be set if `ValidatorsHistory` setting is used. | | ValidatorsCount | `int` | `0` | Number of validators set for the whole network lifetime, can't be set if `ValidatorsHistory` setting is used. |
| ValidatorsHistory | map[uint32]int | none | Number of consensus nodes to use after given height (see `CommitteeHistory` also). Heights where the change occurs must be divisible by the number of committee members at that height. Can't be used with `ValidatorsCount` not equal to zero. | | ValidatorsHistory | map[uint32]int | none | Number of consensus nodes to use after given height (see `CommitteeHistory` also). Heights where the change occurs must be divisible by the number of committee members at that height. Can't be used with `ValidatorsCount` not equal to zero. |
| VerifyBlocks | `bool` | `false` | Denotes whether to verify the received blocks. | | VerifyBlocks | `bool` | `false` | Denotes whether to verify the received blocks. |

View file

@ -4,6 +4,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"sort" "sort"
"time"
"github.com/nspcc-dev/neo-go/pkg/config/netmode" "github.com/nspcc-dev/neo-go/pkg/config/netmode"
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames" "github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
@ -58,7 +59,10 @@ type (
// ReservedAttributes allows to have reserved attributes range for experimental or private purposes. // ReservedAttributes allows to have reserved attributes range for experimental or private purposes.
ReservedAttributes bool `yaml:"ReservedAttributes"` ReservedAttributes bool `yaml:"ReservedAttributes"`
// SaveStorageBatch enables storage batch saving before every persist. // SaveStorageBatch enables storage batch saving before every persist.
SaveStorageBatch bool `yaml:"SaveStorageBatch"` SaveStorageBatch bool `yaml:"SaveStorageBatch"`
// SecondsPerBlock is the time interval (in seconds) between blocks that consensus nodes work with.
//
// Deprecated: replaced by TimePerBlock, to be removed in future versions.
SecondsPerBlock int `yaml:"SecondsPerBlock"` SecondsPerBlock int `yaml:"SecondsPerBlock"`
SeedList []string `yaml:"SeedList"` SeedList []string `yaml:"SeedList"`
StandbyCommittee []string `yaml:"StandbyCommittee"` StandbyCommittee []string `yaml:"StandbyCommittee"`
@ -67,7 +71,10 @@ type (
// StateSyncInterval is the number of blocks between state heights available for MPT state data synchronization. // StateSyncInterval is the number of blocks between state heights available for MPT state data synchronization.
// It is valid only if P2PStateExchangeExtensions are enabled. // It is valid only if P2PStateExchangeExtensions are enabled.
StateSyncInterval int `yaml:"StateSyncInterval"` StateSyncInterval int `yaml:"StateSyncInterval"`
ValidatorsCount int `yaml:"ValidatorsCount"` // TimePerBlock is the time interval between blocks that consensus nodes work with.
// It must be an integer number of milliseconds.
TimePerBlock time.Duration `yaml:"TimePerBlock"`
ValidatorsCount int `yaml:"ValidatorsCount"`
// Validators stores history of changes to consensus node number (height: number). // Validators stores history of changes to consensus node number (height: number).
ValidatorsHistory map[uint32]int `yaml:"ValidatorsHistory"` ValidatorsHistory map[uint32]int `yaml:"ValidatorsHistory"`
// Whether to verify received blocks. // Whether to verify received blocks.
@ -92,6 +99,9 @@ func (p *ProtocolConfiguration) Validate() error {
if p.P2PStateExchangeExtensions && p.KeepOnlyLatestState && !p.RemoveUntraceableBlocks { if p.P2PStateExchangeExtensions && p.KeepOnlyLatestState && !p.RemoveUntraceableBlocks {
return fmt.Errorf("P2PStateExchangeExtensions can be enabled either on MPT-complete node (KeepOnlyLatestState=false) or on light GC-enabled node (RemoveUntraceableBlocks=true)") return fmt.Errorf("P2PStateExchangeExtensions can be enabled either on MPT-complete node (KeepOnlyLatestState=false) or on light GC-enabled node (RemoveUntraceableBlocks=true)")
} }
if p.TimePerBlock%time.Millisecond != 0 {
return errors.New("TimePerBlock must be an integer number of milliseconds")
}
for name := range p.NativeUpdateHistories { for name := range p.NativeUpdateHistories {
if !nativenames.IsValid(name) { if !nativenames.IsValid(name) {
return fmt.Errorf("NativeActivations configuration section contains unexpected native contract name: %s", name) return fmt.Errorf("NativeActivations configuration section contains unexpected native contract name: %s", name)
@ -219,6 +229,7 @@ func (p *ProtocolConfiguration) Equals(o *ProtocolConfiguration) bool {
p.SecondsPerBlock != o.SecondsPerBlock || p.SecondsPerBlock != o.SecondsPerBlock ||
p.StateRootInHeader != o.StateRootInHeader || p.StateRootInHeader != o.StateRootInHeader ||
p.StateSyncInterval != o.StateSyncInterval || p.StateSyncInterval != o.StateSyncInterval ||
p.TimePerBlock != o.TimePerBlock ||
p.ValidatorsCount != o.ValidatorsCount || p.ValidatorsCount != o.ValidatorsCount ||
p.VerifyBlocks != o.VerifyBlocks || p.VerifyBlocks != o.VerifyBlocks ||
p.VerifyTransactions != o.VerifyTransactions || p.VerifyTransactions != o.VerifyTransactions ||

View file

@ -3,6 +3,7 @@ package config
import ( import (
"path/filepath" "path/filepath"
"testing" "testing"
"time"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -17,6 +18,14 @@ func TestProtocolConfigurationValidation(t *testing.T) {
P2PStateExchangeExtensions: true, P2PStateExchangeExtensions: true,
} }
require.Error(t, p.Validate()) require.Error(t, p.Validate())
p = &ProtocolConfiguration{
StandbyCommittee: []string{
"02b3622bf4017bdfe317c58aed5f4c753f206b7db896046fa7d774bbc4bf7f8dc2",
},
ValidatorsCount: 1,
TimePerBlock: time.Microsecond,
}
require.Error(t, p.Validate())
p = &ProtocolConfiguration{ p = &ProtocolConfiguration{
ValidatorsCount: 1, ValidatorsCount: 1,
} }

View file

@ -480,7 +480,7 @@ func newTestServiceWithChain(t *testing.T, bc *core.Blockchain) *service {
ProtocolConfiguration: bc.GetConfig(), ProtocolConfiguration: bc.GetConfig(),
RequestTx: func(...util.Uint256) {}, RequestTx: func(...util.Uint256) {},
StopTxFlow: func() {}, StopTxFlow: func() {},
TimePerBlock: time.Duration(bc.GetConfig().SecondsPerBlock) * time.Second, TimePerBlock: bc.GetConfig().TimePerBlock,
Wallet: &config.Wallet{ Wallet: &config.Wallet{
Path: "./testdata/wallet1.json", Path: "./testdata/wallet1.json",
Password: "one", Password: "one",

View file

@ -55,7 +55,7 @@ const (
defaultMaxBlockSystemFee = 900000000000 defaultMaxBlockSystemFee = 900000000000
defaultMaxTraceableBlocks = 2102400 // 1 year of 15s blocks defaultMaxTraceableBlocks = 2102400 // 1 year of 15s blocks
defaultMaxTransactionsPerBlock = 512 defaultMaxTransactionsPerBlock = 512
defaultSecondsPerBlock = 15 defaultTimePerBlock = 15 * time.Second
// HeaderVerificationGasLimit is the maximum amount of GAS for block header verification. // HeaderVerificationGasLimit is the maximum amount of GAS for block header verification.
HeaderVerificationGasLimit = 3_00000000 // 3 GAS HeaderVerificationGasLimit = 3_00000000 // 3 GAS
defaultStateSyncInterval = 40000 defaultStateSyncInterval = 40000
@ -252,15 +252,21 @@ func NewBlockchain(s storage.Store, cfg config.ProtocolConfiguration, log *zap.L
log.Info("MaxTransactionsPerBlock is not set or wrong, using default value", log.Info("MaxTransactionsPerBlock is not set or wrong, using default value",
zap.Uint16("MaxTransactionsPerBlock", cfg.MaxTransactionsPerBlock)) zap.Uint16("MaxTransactionsPerBlock", cfg.MaxTransactionsPerBlock))
} }
if cfg.SecondsPerBlock == 0 { if cfg.TimePerBlock <= 0 {
cfg.SecondsPerBlock = defaultSecondsPerBlock if cfg.SecondsPerBlock > 0 { //nolint:staticcheck // SA1019: cfg.SecondsPerBlock is deprecated
log.Info("SecondsPerBlock is not set or wrong, using default value", cfg.TimePerBlock = time.Duration(cfg.SecondsPerBlock) * time.Second //nolint:staticcheck // SA1019: cfg.SecondsPerBlock is deprecated
zap.Int("SecondsPerBlock", cfg.SecondsPerBlock)) log.Info("TimePerBlock is not set, using deprecated SecondsPerBlock setting, consider updating your config",
zap.Duration("TimePerBlock", cfg.TimePerBlock))
} else {
cfg.TimePerBlock = defaultTimePerBlock
log.Info("TimePerBlock is not set or wrong, using default value",
zap.Duration("TimePerBlock", cfg.TimePerBlock))
}
} }
if cfg.MaxValidUntilBlockIncrement == 0 { if cfg.MaxValidUntilBlockIncrement == 0 {
const secondsPerDay = int(24 * time.Hour / time.Second) const timePerDay = 24 * time.Hour
cfg.MaxValidUntilBlockIncrement = uint32(secondsPerDay / cfg.SecondsPerBlock) cfg.MaxValidUntilBlockIncrement = uint32(timePerDay / cfg.TimePerBlock)
log.Info("MaxValidUntilBlockIncrement is not set or wrong, using default value", log.Info("MaxValidUntilBlockIncrement is not set or wrong, using default value",
zap.Uint32("MaxValidUntilBlockIncrement", cfg.MaxValidUntilBlockIncrement)) zap.Uint32("MaxValidUntilBlockIncrement", cfg.MaxValidUntilBlockIncrement))
} }
@ -2650,7 +2656,7 @@ func (bc *Blockchain) getFakeNextBlock(nextBlockHeight uint32) (*block.Block, er
if err != nil { if err != nil {
return nil, err return nil, err
} }
b.Timestamp = hdr.Timestamp + uint64(bc.config.SecondsPerBlock*int(time.Second/time.Millisecond)) b.Timestamp = hdr.Timestamp + uint64(bc.config.TimePerBlock/time.Millisecond)
return b, nil return b, nil
} }

View file

@ -4,6 +4,7 @@ import (
"encoding/hex" "encoding/hex"
"sort" "sort"
"testing" "testing"
"time"
"github.com/nspcc-dev/neo-go/pkg/config" "github.com/nspcc-dev/neo-go/pkg/config"
"github.com/nspcc-dev/neo-go/pkg/config/netmode" "github.com/nspcc-dev/neo-go/pkg/config/netmode"
@ -22,9 +23,9 @@ const (
// We don't need a lot of traceable blocks for tests. // We don't need a lot of traceable blocks for tests.
MaxTraceableBlocks = 1000 MaxTraceableBlocks = 1000
// SecondsPerBlock is the default SecondsPerBlock setting used for test chains. // TimePerBlock is the default TimePerBlock setting used for test chains (1s).
// Usually blocks are created by tests bypassing this setting. // Usually blocks are created by tests bypassing this setting.
SecondsPerBlock = 1 TimePerBlock = time.Second
) )
const singleValidatorWIF = "KxyjQ8eUa4FHt3Gvioyt1Wz29cTUrE4eTqX3yFSk1YFCsPL8uNsY" const singleValidatorWIF = "KxyjQ8eUa4FHt3Gvioyt1Wz29cTUrE4eTqX3yFSk1YFCsPL8uNsY"
@ -117,7 +118,7 @@ func init() {
// NewSingle creates a new blockchain instance with a single validator and // NewSingle creates a new blockchain instance with a single validator and
// setups cleanup functions. The configuration used is with netmode.UnitTestNet // setups cleanup functions. The configuration used is with netmode.UnitTestNet
// magic and SecondsPerBlock/MaxTraceableBlocks options defined by constants in // magic and TimePerBlock/MaxTraceableBlocks options defined by constants in
// this package. MemoryStore is used as the backend storage, so all of the chain // this package. MemoryStore is used as the backend storage, so all of the chain
// contents is always in RAM. The Signer returned is the validator (and the committee at // contents is always in RAM. The Signer returned is the validator (and the committee at
// the same time). // the same time).
@ -140,7 +141,7 @@ func NewSingleWithCustomConfigAndStore(t testing.TB, f func(cfg *config.Protocol
protoCfg := config.ProtocolConfiguration{ protoCfg := config.ProtocolConfiguration{
Magic: netmode.UnitTestNet, Magic: netmode.UnitTestNet,
MaxTraceableBlocks: MaxTraceableBlocks, MaxTraceableBlocks: MaxTraceableBlocks,
SecondsPerBlock: SecondsPerBlock, TimePerBlock: TimePerBlock,
StandbyCommittee: []string{hex.EncodeToString(committeeAcc.PublicKey().Bytes())}, StandbyCommittee: []string{hex.EncodeToString(committeeAcc.PublicKey().Bytes())},
ValidatorsCount: 1, ValidatorsCount: 1,
VerifyBlocks: true, VerifyBlocks: true,
@ -196,7 +197,7 @@ func NewMultiWithCustomConfigAndStoreNoCheck(t testing.TB, f func(*config.Protoc
protoCfg := config.ProtocolConfiguration{ protoCfg := config.ProtocolConfiguration{
Magic: netmode.UnitTestNet, Magic: netmode.UnitTestNet,
MaxTraceableBlocks: MaxTraceableBlocks, MaxTraceableBlocks: MaxTraceableBlocks,
SecondsPerBlock: SecondsPerBlock, TimePerBlock: TimePerBlock,
StandbyCommittee: standByCommittee, StandbyCommittee: standByCommittee,
ValidatorsCount: 4, ValidatorsCount: 4,
VerifyBlocks: true, VerifyBlocks: true,

View file

@ -89,6 +89,10 @@ type (
func NewServerConfig(cfg config.Config) ServerConfig { func NewServerConfig(cfg config.Config) ServerConfig {
appConfig := cfg.ApplicationConfiguration appConfig := cfg.ApplicationConfiguration
protoConfig := cfg.ProtocolConfiguration protoConfig := cfg.ProtocolConfiguration
timePerBlock := protoConfig.TimePerBlock
if timePerBlock == 0 && protoConfig.SecondsPerBlock > 0 { //nolint:staticcheck // SA1019: protoConfig.SecondsPerBlock is deprecated
timePerBlock = time.Duration(protoConfig.SecondsPerBlock) * time.Second //nolint:staticcheck // SA1019: protoConfig.SecondsPerBlock is deprecated
}
return ServerConfig{ return ServerConfig{
UserAgent: cfg.GenerateUserAgent(), UserAgent: cfg.GenerateUserAgent(),
@ -105,7 +109,7 @@ func NewServerConfig(cfg config.Config) ServerConfig {
MaxPeers: appConfig.MaxPeers, MaxPeers: appConfig.MaxPeers,
AttemptConnPeers: appConfig.AttemptConnPeers, AttemptConnPeers: appConfig.AttemptConnPeers,
MinPeers: appConfig.MinPeers, MinPeers: appConfig.MinPeers,
TimePerBlock: time.Duration(protoConfig.SecondsPerBlock) * time.Second, TimePerBlock: timePerBlock,
OracleCfg: appConfig.Oracle, OracleCfg: appConfig.Oracle,
P2PNotaryCfg: appConfig.P2PNotary, P2PNotaryCfg: appConfig.P2PNotary,
StateRootCfg: appConfig.StateRoot, StateRootCfg: appConfig.StateRoot,

View file

@ -205,7 +205,7 @@ func (p *TCPPeer) handleQueues() {
var p2pSkipCounter uint32 var p2pSkipCounter uint32
const p2pSkipDivisor = 4 const p2pSkipDivisor = 4
var writeTimeout = time.Duration(p.server.config.SecondsPerBlock) * time.Second var writeTimeout = p.server.TimePerBlock
for { for {
var msg []byte var msg []byte

View file

@ -1994,7 +1994,7 @@ func TestClient_Wait(t *testing.T) {
select { select {
case <-rcvr: case <-rcvr:
break waitloop break waitloop
case <-time.NewTimer(time.Duration(chain.GetConfig().SecondsPerBlock) * time.Second).C: case <-time.NewTimer(chain.GetConfig().TimePerBlock).C:
t.Fatal("transaction failed to be awaited") t.Fatal("transaction failed to be awaited")
} }
} }
@ -2070,7 +2070,7 @@ func TestWSClient_Wait(t *testing.T) {
require.Equal(t, vmstate.Halt, aer.VMState) require.Equal(t, vmstate.Halt, aer.VMState)
} }
break waitloop break waitloop
case <-time.NewTimer(time.Duration(chain.GetConfig().SecondsPerBlock) * time.Second).C: case <-time.NewTimer(chain.GetConfig().TimePerBlock).C:
t.Fatalf("transaction from block %d failed to be awaited: deadline exceeded", b.Index) t.Fatalf("transaction from block %d failed to be awaited: deadline exceeded", b.Index)
} }
} }
@ -2232,7 +2232,7 @@ waitloop:
require.Equal(t, trigger.Application, aer.Trigger) require.Equal(t, trigger.Application, aer.Trigger)
require.Equal(t, vmstate.Halt, aer.VMState) require.Equal(t, vmstate.Halt, aer.VMState)
break waitloop break waitloop
case <-time.NewTimer(time.Duration(chain.GetConfig().SecondsPerBlock) * time.Second).C: case <-time.NewTimer(chain.GetConfig().TimePerBlock).C:
t.Fatal("transaction failed to be awaited") t.Fatal("transaction failed to be awaited")
} }
} }

View file

@ -268,8 +268,8 @@ func New(chain Ledger, conf config.RPC, coreServer *network.Server,
protoCfg := chain.GetConfig() protoCfg := chain.GetConfig()
if conf.SessionEnabled { if conf.SessionEnabled {
if conf.SessionExpirationTime <= 0 { if conf.SessionExpirationTime <= 0 {
conf.SessionExpirationTime = protoCfg.SecondsPerBlock conf.SessionExpirationTime = int(protoCfg.TimePerBlock / time.Second)
log.Info("SessionExpirationTime is not set or wrong, setting default value", zap.Int("SessionExpirationTime", protoCfg.SecondsPerBlock)) log.Info("SessionExpirationTime is not set or wrong, setting default value", zap.Int("SessionExpirationTime", conf.SessionExpirationTime))
} }
if conf.SessionPoolSize <= 0 { if conf.SessionPoolSize <= 0 {
conf.SessionPoolSize = defaultSessionPoolSize conf.SessionPoolSize = defaultSessionPoolSize
@ -706,7 +706,7 @@ func (s *Server) getVersion(_ params.Params) (interface{}, *neorpc.Error) {
Protocol: result.Protocol{ Protocol: result.Protocol{
AddressVersion: address.NEO3Prefix, AddressVersion: address.NEO3Prefix,
Network: cfg.Magic, Network: cfg.Magic,
MillisecondsPerBlock: cfg.SecondsPerBlock * 1000, MillisecondsPerBlock: int(cfg.TimePerBlock / time.Millisecond),
MaxTraceableBlocks: cfg.MaxTraceableBlocks, MaxTraceableBlocks: cfg.MaxTraceableBlocks,
MaxValidUntilBlockIncrement: cfg.MaxValidUntilBlockIncrement, MaxValidUntilBlockIncrement: cfg.MaxValidUntilBlockIncrement,
MaxTransactionsPerBlock: cfg.MaxTransactionsPerBlock, MaxTransactionsPerBlock: cfg.MaxTransactionsPerBlock,

View file

@ -872,7 +872,7 @@ var rpcTestCases = map[string][]rpcTestCase{
cfg := e.chain.GetConfig() cfg := e.chain.GetConfig()
require.EqualValues(t, address.NEO3Prefix, resp.Protocol.AddressVersion) require.EqualValues(t, address.NEO3Prefix, resp.Protocol.AddressVersion)
require.EqualValues(t, cfg.Magic, resp.Protocol.Network) require.EqualValues(t, cfg.Magic, resp.Protocol.Network)
require.EqualValues(t, cfg.SecondsPerBlock*1000, resp.Protocol.MillisecondsPerBlock) require.EqualValues(t, cfg.TimePerBlock/time.Millisecond, resp.Protocol.MillisecondsPerBlock)
require.EqualValues(t, cfg.MaxTraceableBlocks, resp.Protocol.MaxTraceableBlocks) require.EqualValues(t, cfg.MaxTraceableBlocks, resp.Protocol.MaxTraceableBlocks)
require.EqualValues(t, cfg.MaxValidUntilBlockIncrement, resp.Protocol.MaxValidUntilBlockIncrement) require.EqualValues(t, cfg.MaxValidUntilBlockIncrement, resp.Protocol.MaxValidUntilBlockIncrement)
require.EqualValues(t, cfg.MaxTransactionsPerBlock, resp.Protocol.MaxTransactionsPerBlock) require.EqualValues(t, cfg.MaxTransactionsPerBlock, resp.Protocol.MaxTransactionsPerBlock)

View file

@ -87,7 +87,7 @@ func New(cfg config.StateRoot, sm *stateroot.Module, log *zap.Logger, bc Ledger,
blockCh: make(chan *block.Block), blockCh: make(chan *block.Block),
stopCh: make(chan struct{}), stopCh: make(chan struct{}),
done: make(chan struct{}), done: make(chan struct{}),
timePerBlock: time.Duration(bcConf.SecondsPerBlock) * time.Second, timePerBlock: bcConf.TimePerBlock,
maxRetries: voteValidEndInc, maxRetries: voteValidEndInc,
relayExtensible: cb, relayExtensible: cb,
} }