multi: add SanityChecker interface.
This adds the sanity checker interface and update the function signature of CheckBlockSanity. Associated tests and mocks updated/added.
This commit is contained in:
parent
f73d738c24
commit
dcddbbabb4
@ -455,3 +455,13 @@ type LogManager interface {
|
||||
// is invalid.
|
||||
ParseAndSetDebugLevels(debugLevel string) error
|
||||
}
|
||||
|
||||
// SanityChecker represents a block sanity checker for use with the RPC server.
|
||||
//
|
||||
// The interface contract requires that all of these methods are safe for
|
||||
// concurrent access.
|
||||
type SanityChecker interface {
|
||||
// CheckBlockSanity checks the correctness of the provided block
|
||||
// per consensus.
|
||||
CheckBlockSanity(block *dcrutil.Block) error
|
||||
}
|
||||
|
||||
@ -4786,8 +4786,7 @@ func verifyChain(_ context.Context, s *Server, level, depth int64) error {
|
||||
|
||||
// Level 1 does basic chain sanity checks.
|
||||
if level > 0 {
|
||||
err := blockchain.CheckBlockSanity(block, s.cfg.TimeSource,
|
||||
s.cfg.ChainParams)
|
||||
err := s.cfg.SanityChecker.CheckBlockSanity(block)
|
||||
if err != nil {
|
||||
log.Errorf("Verify is unable to validate "+
|
||||
"block at hash %v height %d: %v",
|
||||
@ -5593,12 +5592,13 @@ type Config struct {
|
||||
|
||||
// These fields allow the RPC server to interface with the local block
|
||||
// chain data and state.
|
||||
TimeSource blockchain.MedianTimeSource
|
||||
Chain Chain
|
||||
ChainParams *chaincfg.Params
|
||||
DB database.DB
|
||||
FeeEstimator FeeEstimator
|
||||
Services wire.ServiceFlag
|
||||
TimeSource blockchain.MedianTimeSource
|
||||
Chain Chain
|
||||
SanityChecker SanityChecker
|
||||
ChainParams *chaincfg.Params
|
||||
DB database.DB
|
||||
FeeEstimator FeeEstimator
|
||||
Services wire.ServiceFlag
|
||||
|
||||
// SubsidyCache defines a cache for efficient access to consensus-critical
|
||||
// subsidy calculations.
|
||||
|
||||
@ -654,6 +654,17 @@ func (l *testLogManager) SupportedSubsystems() []string {
|
||||
return l.supportedSubsystems
|
||||
}
|
||||
|
||||
// testSanityChecker provides a mock implementation that checks the sanity
|
||||
// state of a block.
|
||||
type testSanityChecker struct {
|
||||
checkBlockSanityErr error
|
||||
}
|
||||
|
||||
// testSanityChecker returns mock sanity state of the provided block.
|
||||
func (s *testSanityChecker) CheckBlockSanity(block *dcrutil.Block) error {
|
||||
return s.checkBlockSanityErr
|
||||
}
|
||||
|
||||
// ParseAndSetDebugLevels provides a mock implementation for parsing the
|
||||
// specified debug level and setting the levels accordingly.
|
||||
func (l *testLogManager) ParseAndSetDebugLevels(debugLevel string) error {
|
||||
@ -719,20 +730,21 @@ var block432100 = func() wire.MsgBlock {
|
||||
}()
|
||||
|
||||
type rpcTest struct {
|
||||
name string
|
||||
handler commandHandler
|
||||
cmd interface{}
|
||||
mockChainParams *chaincfg.Params
|
||||
mockChain *testRPCChain
|
||||
mockAddrManager *testAddrManager
|
||||
mockFeeEstimator *testFeeEstimator
|
||||
mockSyncManager *testSyncManager
|
||||
mockConnManager *testConnManager
|
||||
mockClock *testClock
|
||||
mockLogManager *testLogManager
|
||||
result interface{}
|
||||
wantErr bool
|
||||
errCode dcrjson.RPCErrorCode
|
||||
name string
|
||||
handler commandHandler
|
||||
cmd interface{}
|
||||
mockChainParams *chaincfg.Params
|
||||
mockChain *testRPCChain
|
||||
mockSanityChecker *testSanityChecker
|
||||
mockAddrManager *testAddrManager
|
||||
mockFeeEstimator *testFeeEstimator
|
||||
mockSyncManager *testSyncManager
|
||||
mockConnManager *testConnManager
|
||||
mockClock *testClock
|
||||
mockLogManager *testLogManager
|
||||
result interface{}
|
||||
wantErr bool
|
||||
errCode dcrjson.RPCErrorCode
|
||||
}
|
||||
|
||||
// defaultChainParams provides a default chaincfg.Params to be used throughout
|
||||
@ -878,6 +890,15 @@ func defaultMockRPCChain() *testRPCChain {
|
||||
}
|
||||
}
|
||||
|
||||
// defaultMockSanityChecker provides a default mock sanity checker to be used
|
||||
// throughout the tests. Tests can override these defaults by calling
|
||||
// defaultMockSanityChecker, updating fields as necessary on the returned
|
||||
// *testSanityChecker, and then setting rpcTest.mockSanityChecker as that
|
||||
// *testSanityChecker.
|
||||
func defaultMockSanityChecker() *testSanityChecker {
|
||||
return &testSanityChecker{}
|
||||
}
|
||||
|
||||
// defaultMockAddrManager provides a default mock address manager to be used
|
||||
// throughout the tests. Tests can override these defaults by calling
|
||||
// defaultMockAddrManager, updating fields as necessary on the returned
|
||||
@ -990,17 +1011,18 @@ func defaultMockLogManager() *testLogManager {
|
||||
// the tests. Defaults can be overridden by tests through the rpcTest struct.
|
||||
func defaultMockConfig(chainParams *chaincfg.Params) *Config {
|
||||
return &Config{
|
||||
ChainParams: chainParams,
|
||||
Chain: defaultMockRPCChain(),
|
||||
AddrManager: defaultMockAddrManager(),
|
||||
FeeEstimator: defaultMockFeeEstimator(),
|
||||
SyncMgr: defaultMockSyncManager(),
|
||||
ConnMgr: defaultMockConnManager(),
|
||||
Clock: &testClock{},
|
||||
LogManager: defaultMockLogManager(),
|
||||
TimeSource: blockchain.NewMedianTime(),
|
||||
Services: wire.SFNodeNetwork | wire.SFNodeCF,
|
||||
SubsidyCache: standalone.NewSubsidyCache(chainParams),
|
||||
ChainParams: chainParams,
|
||||
Chain: defaultMockRPCChain(),
|
||||
SanityChecker: defaultMockSanityChecker(),
|
||||
AddrManager: defaultMockAddrManager(),
|
||||
FeeEstimator: defaultMockFeeEstimator(),
|
||||
SyncMgr: defaultMockSyncManager(),
|
||||
ConnMgr: defaultMockConnManager(),
|
||||
Clock: &testClock{},
|
||||
LogManager: defaultMockLogManager(),
|
||||
TimeSource: blockchain.NewMedianTime(),
|
||||
Services: wire.SFNodeNetwork | wire.SFNodeCF,
|
||||
SubsidyCache: standalone.NewSubsidyCache(chainParams),
|
||||
NetInfo: []types.NetworksResult{{
|
||||
Name: "IPV4",
|
||||
Limited: false,
|
||||
@ -3913,6 +3935,9 @@ func testRPCServerHandler(t *testing.T, tests []rpcTest) {
|
||||
if test.mockLogManager != nil {
|
||||
rpcserverConfig.LogManager = test.mockLogManager
|
||||
}
|
||||
if test.mockSanityChecker != nil {
|
||||
rpcserverConfig.SanityChecker = test.mockSanityChecker
|
||||
}
|
||||
|
||||
testServer := &Server{cfg: *rpcserverConfig}
|
||||
result, err := test.handler(nil, testServer, test.cmd)
|
||||
|
||||
@ -14,6 +14,7 @@ import (
|
||||
"github.com/decred/dcrd/blockchain/v3"
|
||||
"github.com/decred/dcrd/blockchain/v3/indexers"
|
||||
"github.com/decred/dcrd/chaincfg/chainhash"
|
||||
"github.com/decred/dcrd/chaincfg/v3"
|
||||
"github.com/decred/dcrd/dcrutil/v3"
|
||||
"github.com/decred/dcrd/internal/fees"
|
||||
"github.com/decred/dcrd/internal/mempool"
|
||||
@ -496,3 +497,22 @@ func (*rpcLogManager) SupportedSubsystems() []string {
|
||||
func (*rpcLogManager) ParseAndSetDebugLevels(debugLevel string) error {
|
||||
return parseAndSetDebugLevels(debugLevel)
|
||||
}
|
||||
|
||||
// rpcSanityChecker provides a block sanity checker for use with the RPC and
|
||||
// implements the rpcserver.SanityChecker interface.
|
||||
type rpcSanityChecker struct {
|
||||
timeSource blockchain.MedianTimeSource
|
||||
chainParams *chaincfg.Params
|
||||
}
|
||||
|
||||
// Ensure rpcSanityChecker implements the rpcserver.SanityChecker interface.
|
||||
var _ rpcserver.SanityChecker = (*rpcSanityChecker)(nil)
|
||||
|
||||
// CheckBlockSanity checks the correctness of the provided block
|
||||
// per consensus. An appropriate error is returned if anything is
|
||||
// invalid.
|
||||
//
|
||||
// This function is part of the rpcserver.SanityChecker interface implementation.
|
||||
func (s *rpcSanityChecker) CheckBlockSanity(block *dcrutil.Block) error {
|
||||
return blockchain.CheckBlockSanity(block, s.timeSource, s.chainParams)
|
||||
}
|
||||
|
||||
27
server.go
27
server.go
@ -3265,19 +3265,20 @@ func newServer(ctx context.Context, listenAddrs []string, db database.DB, chainP
|
||||
}
|
||||
|
||||
s.rpcServer, err = rpcserver.New(&rpcserver.Config{
|
||||
Listeners: rpcListeners,
|
||||
ConnMgr: &rpcConnManager{&s},
|
||||
SyncMgr: &rpcSyncMgr{&s, s.blockManager},
|
||||
FeeEstimator: &rpcFeeEstimator{s.feeEstimator},
|
||||
TimeSource: s.timeSource,
|
||||
Services: s.services,
|
||||
AddrManager: &rpcAddrManager{s.addrManager},
|
||||
Clock: &rpcClock{},
|
||||
SubsidyCache: s.subsidyCache,
|
||||
Chain: &rpcChain{s.chain},
|
||||
ChainParams: chainParams,
|
||||
DB: db,
|
||||
TxMemPool: s.txMemPool,
|
||||
Listeners: rpcListeners,
|
||||
ConnMgr: &rpcConnManager{&s},
|
||||
SyncMgr: &rpcSyncMgr{&s, s.blockManager},
|
||||
FeeEstimator: &rpcFeeEstimator{s.feeEstimator},
|
||||
TimeSource: s.timeSource,
|
||||
Services: s.services,
|
||||
AddrManager: &rpcAddrManager{s.addrManager},
|
||||
Clock: &rpcClock{},
|
||||
SubsidyCache: s.subsidyCache,
|
||||
Chain: &rpcChain{s.chain},
|
||||
ChainParams: chainParams,
|
||||
SanityChecker: &rpcSanityChecker{s.timeSource, chainParams},
|
||||
DB: db,
|
||||
TxMemPool: s.txMemPool,
|
||||
BgBlkTmplGenerator: func() *mining.BgBlkTmplGenerator {
|
||||
return s.bg
|
||||
},
|
||||
|
||||
Loading…
Reference in New Issue
Block a user