diff --git a/pkg/consensus/consensus.go b/pkg/consensus/consensus.go index 01178ae5f..1edcb8a45 100644 --- a/pkg/consensus/consensus.go +++ b/pkg/consensus/consensus.go @@ -14,6 +14,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/config/netmode" coreb "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/interop" "github.com/nspcc-dev/neo-go/pkg/core/mempool" "github.com/nspcc-dev/neo-go/pkg/core/native" "github.com/nspcc-dev/neo-go/pkg/core/transaction" @@ -43,6 +44,22 @@ const nsInMs = 1000000 // Category is message category for extensible payloads. const Category = "dBFT" +// Ledger is the interface to Blockchain sufficient for Service. +type Ledger interface { + AddBlock(block *coreb.Block) error + ApplyPolicyToTxSet([]*transaction.Transaction) []*transaction.Transaction + GetMemPool() *mempool.Pool + GetNextBlockValidators() ([]*keys.PublicKey, error) + GetStateModule() blockchainer.StateRoot + GetTransaction(util.Uint256) (*transaction.Transaction, uint32, error) + GetValidators() ([]*keys.PublicKey, error) + PoolTx(t *transaction.Transaction, pools ...*mempool.Pool) error + SubscribeForBlocks(ch chan<- *coreb.Block) + UnsubscribeFromBlocks(ch chan<- *coreb.Block) + interop.Ledger + mempool.Feer +} + // Service represents consensus instance. type Service interface { // Start initializes dBFT and starts event loop for consensus service. @@ -92,8 +109,8 @@ type Config struct { // Broadcast is a callback which is called to notify server // about new consensus payload to sent. Broadcast func(p *npayload.Extensible) - // Chain is a core.Blockchainer instance. - Chain blockchainer.Blockchainer + // Chain is a Ledger instance. + Chain Ledger // ProtocolConfiguration contains protocol settings. ProtocolConfiguration config.ProtocolConfiguration // RequestTx is a callback to which will be called diff --git a/pkg/consensus/consensus_test.go b/pkg/consensus/consensus_test.go index 6bc2e6b45..db3601867 100644 --- a/pkg/consensus/consensus_test.go +++ b/pkg/consensus/consensus_test.go @@ -13,7 +13,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" - "github.com/nspcc-dev/neo-go/pkg/core/blockchainer" "github.com/nspcc-dev/neo-go/pkg/core/fee" "github.com/nspcc-dev/neo-go/pkg/core/native" "github.com/nspcc-dev/neo-go/pkg/core/storage" @@ -366,9 +365,10 @@ func TestService_OnPayload(t *testing.T) { func TestVerifyBlock(t *testing.T) { srv := newTestService(t) + bc := srv.Chain.(*core.Blockchain) srv.lastTimestamp = 1 t.Run("good empty", func(t *testing.T) { - b := testchain.NewBlock(t, srv.Chain, 1, 0) + b := testchain.NewBlock(t, bc, 1, 0) require.True(t, srv.verifyBlock(&neoBlock{Block: *b})) }) t.Run("good pooled tx", func(t *testing.T) { @@ -377,7 +377,7 @@ func TestVerifyBlock(t *testing.T) { addSender(t, tx) signTx(t, srv.Chain, tx) require.NoError(t, srv.Chain.PoolTx(tx)) - b := testchain.NewBlock(t, srv.Chain, 1, 0, tx) + b := testchain.NewBlock(t, bc, 1, 0, tx) require.True(t, srv.verifyBlock(&neoBlock{Block: *b})) }) t.Run("good non-pooled tx", func(t *testing.T) { @@ -385,7 +385,7 @@ func TestVerifyBlock(t *testing.T) { tx.ValidUntilBlock = 1 addSender(t, tx) signTx(t, srv.Chain, tx) - b := testchain.NewBlock(t, srv.Chain, 1, 0, tx) + b := testchain.NewBlock(t, bc, 1, 0, tx) require.True(t, srv.verifyBlock(&neoBlock{Block: *b})) }) t.Run("good conflicting tx", func(t *testing.T) { @@ -402,11 +402,11 @@ func TestVerifyBlock(t *testing.T) { signTx(t, srv.Chain, tx2) require.NoError(t, srv.Chain.PoolTx(tx1)) require.Error(t, srv.Chain.PoolTx(tx2)) - b := testchain.NewBlock(t, srv.Chain, 1, 0, tx2) + b := testchain.NewBlock(t, bc, 1, 0, tx2) require.True(t, srv.verifyBlock(&neoBlock{Block: *b})) }) t.Run("bad old", func(t *testing.T) { - b := testchain.NewBlock(t, srv.Chain, 1, 0) + b := testchain.NewBlock(t, bc, 1, 0) b.Index = srv.Chain.BlockHeight() require.False(t, srv.verifyBlock(&neoBlock{Block: *b})) }) @@ -417,11 +417,11 @@ func TestVerifyBlock(t *testing.T) { tx.ValidUntilBlock = 1 addSender(t, tx) signTx(t, srv.Chain, tx) - b := testchain.NewBlock(t, srv.Chain, 1, 0, tx) + b := testchain.NewBlock(t, bc, 1, 0, tx) require.False(t, srv.verifyBlock(&neoBlock{Block: *b})) }) t.Run("bad timestamp", func(t *testing.T) { - b := testchain.NewBlock(t, srv.Chain, 1, 0) + b := testchain.NewBlock(t, bc, 1, 0) b.Timestamp = srv.lastTimestamp - 1 require.False(t, srv.verifyBlock(&neoBlock{Block: *b})) }) @@ -431,7 +431,7 @@ func TestVerifyBlock(t *testing.T) { addSender(t, tx) signTx(t, srv.Chain, tx) tx.Scripts[0].InvocationScript[16] = ^tx.Scripts[0].InvocationScript[16] - b := testchain.NewBlock(t, srv.Chain, 1, 0, tx) + b := testchain.NewBlock(t, bc, 1, 0, tx) require.False(t, srv.verifyBlock(&neoBlock{Block: *b})) }) t.Run("bad big sys fee", func(t *testing.T) { @@ -442,7 +442,7 @@ func TestVerifyBlock(t *testing.T) { addSender(t, txes[i]) signTx(t, srv.Chain, txes[i]) } - b := testchain.NewBlock(t, srv.Chain, 1, 0, txes...) + b := testchain.NewBlock(t, bc, 1, 0, txes...) require.False(t, srv.verifyBlock(&neoBlock{Block: *b})) }) } @@ -532,7 +532,7 @@ func addSender(t *testing.T, txs ...*transaction.Transaction) { } } -func signTx(t *testing.T, bc blockchainer.Blockchainer, txs ...*transaction.Transaction) { +func signTx(t *testing.T, bc Ledger, txs ...*transaction.Transaction) { validators := make([]*keys.PublicKey, 4) privNetKeys := make([]*keys.PrivateKey, 4) for i := 0; i < 4; i++ { diff --git a/pkg/core/chaindump/dump.go b/pkg/core/chaindump/dump.go index 6f5cd7259..54ae5d514 100644 --- a/pkg/core/chaindump/dump.go +++ b/pkg/core/chaindump/dump.go @@ -3,14 +3,23 @@ package chaindump import ( "fmt" + "github.com/nspcc-dev/neo-go/pkg/config" "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/io" + "github.com/nspcc-dev/neo-go/pkg/util" ) +// DumperRestorer in the interface to get/add blocks from/to. +type DumperRestorer interface { + AddBlock(block *block.Block) error + GetBlock(hash util.Uint256) (*block.Block, error) + GetConfig() config.ProtocolConfiguration + GetHeaderHash(int) util.Uint256 +} + // Dump writes count blocks from start to the provided writer. // Note: header needs to be written separately by client. -func Dump(bc blockchainer.Blockchainer, w *io.BinWriter, start, count uint32) error { +func Dump(bc DumperRestorer, w *io.BinWriter, start, count uint32) error { for i := start; i < start+count; i++ { bh := bc.GetHeaderHash(int(i)) b, err := bc.GetBlock(bh) @@ -31,7 +40,7 @@ func Dump(bc blockchainer.Blockchainer, w *io.BinWriter, start, count uint32) er // Restore restores blocks from provided reader. // f is called after addition of every block. -func Restore(bc blockchainer.Blockchainer, r *io.BinReader, skip, count uint32, f func(b *block.Block) error) error { +func Restore(bc DumperRestorer, r *io.BinReader, skip, count uint32, f func(b *block.Block) error) error { readBlock := func(r *io.BinReader) ([]byte, error) { var size = r.ReadU32LE() buf := make([]byte, size) diff --git a/pkg/services/notary/node_test.go b/pkg/services/notary/node_test.go index 4e69eb246..979c3e848 100644 --- a/pkg/services/notary/node_test.go +++ b/pkg/services/notary/node_test.go @@ -6,7 +6,6 @@ import ( "github.com/nspcc-dev/neo-go/internal/fakechain" "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/blockchainer" "github.com/nspcc-dev/neo-go/pkg/core/mempool" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/wallet" @@ -14,7 +13,7 @@ import ( "go.uber.org/zap/zaptest" ) -func getTestNotary(t *testing.T, bc blockchainer.Blockchainer, walletPath, pass string) (*wallet.Account, *Notary, *mempool.Pool) { +func getTestNotary(t *testing.T, bc Ledger, walletPath, pass string) (*wallet.Account, *Notary, *mempool.Pool) { mainCfg := config.P2PNotary{ Enabled: true, UnlockWallet: config.Wallet{ diff --git a/pkg/services/notary/notary.go b/pkg/services/notary/notary.go index b9cc1bcdd..5f6a8e747 100644 --- a/pkg/services/notary/notary.go +++ b/pkg/services/notary/notary.go @@ -11,7 +11,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/mempool" "github.com/nspcc-dev/neo-go/pkg/core/mempoolevent" "github.com/nspcc-dev/neo-go/pkg/core/transaction" @@ -27,6 +26,16 @@ import ( ) type ( + // Ledger is the interface to Blockchain sufficient for Notary. + Ledger interface { + BlockHeight() uint32 + GetMaxVerificationGAS() int64 + GetNotaryContractScriptHash() util.Uint160 + SubscribeForBlocks(ch chan<- *block.Block) + UnsubscribeFromBlocks(ch chan<- *block.Block) + VerifyWitness(util.Uint160, hash.Hashable, *transaction.Witness, int64) (int64, error) + } + // Notary represents Notary module. Notary struct { Config Config @@ -60,7 +69,7 @@ type ( // Config represents external configuration for Notary module. Config struct { MainCfg config.P2PNotary - Chain blockchainer.Blockchainer + Chain Ledger Log *zap.Logger } ) diff --git a/pkg/services/oracle/oracle.go b/pkg/services/oracle/oracle.go index c5f570a78..b63c96ebe 100644 --- a/pkg/services/oracle/oracle.go +++ b/pkg/services/oracle/oracle.go @@ -9,10 +9,12 @@ 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/blockchainer" + "github.com/nspcc-dev/neo-go/pkg/core/block" + "github.com/nspcc-dev/neo-go/pkg/core/interop" "github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" + "github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util/slice" "github.com/nspcc-dev/neo-go/pkg/wallet" @@ -20,6 +22,17 @@ import ( ) type ( + // Ledger is the interface to Blockchain sufficient for Oracle. + Ledger interface { + BlockHeight() uint32 + FeePerByte() int64 + GetBaseExecFee() int64 + GetConfig() config.ProtocolConfiguration + GetMaxVerificationGAS() int64 + GetTestVM(t trigger.Type, tx *transaction.Transaction, b *block.Block) *interop.Context + GetTransaction(util.Uint256) (*transaction.Transaction, uint32, error) + } + // Oracle represents oracle module capable of talking // with the external world. Oracle struct { @@ -64,7 +77,7 @@ type ( Network netmode.Magic MainCfg config.OracleConfiguration Client HTTPClient - Chain blockchainer.Blockchainer + Chain Ledger ResponseHandler Broadcaster OnTransaction TxCallback URIValidator URIValidator diff --git a/pkg/services/stateroot/service.go b/pkg/services/stateroot/service.go index 07fd9554c..b26e4d417 100644 --- a/pkg/services/stateroot/service.go +++ b/pkg/services/stateroot/service.go @@ -19,6 +19,15 @@ import ( ) 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) + } + // Service represents state root service. Service interface { blockchainer.StateRoot @@ -31,7 +40,7 @@ type ( service struct { blockchainer.StateRoot - chain blockchainer.Blockchainer + chain Ledger MainCfg config.StateRoot Network netmode.Magic @@ -60,7 +69,7 @@ const ( ) // New returns new state root service instance using underlying module. -func New(cfg config.StateRoot, log *zap.Logger, bc blockchainer.Blockchainer, cb RelayCallback) (Service, error) { +func New(cfg config.StateRoot, log *zap.Logger, bc Ledger, cb RelayCallback) (Service, error) { bcConf := bc.GetConfig() s := &service{ StateRoot: bc.GetStateModule(),