From 63646c8c92a901822c40bbfd80f59e1c43c7f3aa Mon Sep 17 00:00:00 2001 From: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com> Date: Wed, 22 Jul 2020 13:47:38 +0300 Subject: [PATCH] [NOD-1175] Implement AddBlock (#809) * [NOD-1175] Get rid of something weird. * [NOD-1175] Implement AddBlock. * [NOD-1175] Implement BFDisallowOrphans. * [NOD-1175] Pass flags into AddBlock. * [NOD-1175] Remove isOrphan and isDelayed handling from AddBlock. * [NOD-1175] Use default return values in error. * [NOD-1175] Bring back a comment. * [NOD-1175] Add ErrOrphanBlockIsNotAllowed to errorCodeStrings. --- blockdag/error.go | 5 +++++ blockdag/error_test.go | 1 + blockdag/process.go | 9 +++++++++ protocol/flowcontext/blocks.go | 7 ++++--- protocol/manager.go | 4 ++-- rpc/handle_submit_block.go | 8 ++------ 6 files changed, 23 insertions(+), 11 deletions(-) diff --git a/blockdag/error.go b/blockdag/error.go index 662e11cb6..00da2feb7 100644 --- a/blockdag/error.go +++ b/blockdag/error.go @@ -206,6 +206,10 @@ const ( // ErrDelayedBlockIsNotAllowed indicates that a block with a delayed timestamp was // submitted with BFDisallowDelay flag raised. ErrDelayedBlockIsNotAllowed + + // ErrOrphanBlockIsNotAllowed indicates that an orphan block was submitted with + // BFDisallowOrphans flag raised. + ErrOrphanBlockIsNotAllowed ) // Map of ErrorCode values back to their constant names for pretty printing. @@ -254,6 +258,7 @@ var errorCodeStrings = map[ErrorCode]string{ ErrInvalidPayloadHash: "ErrInvalidPayloadHash", ErrInvalidParentsRelation: "ErrInvalidParentsRelation", ErrDelayedBlockIsNotAllowed: "ErrDelayedBlockIsNotAllowed", + ErrOrphanBlockIsNotAllowed: "ErrOrphanBlockIsNotAllowed", } // String returns the ErrorCode as a human-readable name. diff --git a/blockdag/error_test.go b/blockdag/error_test.go index 471da3b96..5be0eda65 100644 --- a/blockdag/error_test.go +++ b/blockdag/error_test.go @@ -57,6 +57,7 @@ func TestErrorCodeStringer(t *testing.T) { {ErrInvalidPayloadHash, "ErrInvalidPayloadHash"}, {ErrInvalidParentsRelation, "ErrInvalidParentsRelation"}, {ErrDelayedBlockIsNotAllowed, "ErrDelayedBlockIsNotAllowed"}, + {ErrOrphanBlockIsNotAllowed, "ErrOrphanBlockIsNotAllowed"}, {0xffff, "Unknown ErrorCode (65535)"}, } diff --git a/blockdag/process.go b/blockdag/process.go index 094bd604b..704fde44e 100644 --- a/blockdag/process.go +++ b/blockdag/process.go @@ -49,6 +49,10 @@ const ( // This is used for the case where a block is submitted through RPC. BFDisallowDelay + // BFDisallowOrphans is set to indicate that an orphan block should be rejected. + // This is used for the case where a block is submitted through RPC. + BFDisallowOrphans + // BFNone is a convenience value to specifically indicate no flags. BFNone BehaviorFlags = 0 ) @@ -151,6 +155,7 @@ func (dag *BlockDAG) processBlockNoLock(block *util.Block, flags BehaviorFlags) isAfterDelay := flags&BFAfterDelay == BFAfterDelay wasBlockStored := flags&BFWasStored == BFWasStored disallowDelay := flags&BFDisallowDelay == BFDisallowDelay + disallowOrphans := flags&BFDisallowOrphans == BFDisallowOrphans blockHash := block.Hash() log.Tracef("Processing block %s", blockHash) @@ -199,6 +204,10 @@ func (dag *BlockDAG) processBlockNoLock(block *util.Block, flags BehaviorFlags) missingParents = append(missingParents, parentHash) } } + if len(missingParents) > 0 && disallowOrphans { + str := fmt.Sprintf("Cannot process orphan blocks while the BFDisallowOrphans flag is raised %s", blockHash) + return false, false, ruleError(ErrOrphanBlockIsNotAllowed, str) + } // Handle the case of a block with a valid timestamp(non-delayed) which points to a delayed block. delay, isParentDelayed := dag.maxDelayOfParents(missingParents) diff --git a/protocol/flowcontext/blocks.go b/protocol/flowcontext/blocks.go index 4b1e68fcd..2d9c0ae99 100644 --- a/protocol/flowcontext/blocks.go +++ b/protocol/flowcontext/blocks.go @@ -1,6 +1,7 @@ package flowcontext import ( + "github.com/kaspanet/kaspad/blockdag" "github.com/kaspanet/kaspad/protocol/flows/blockrelay" "github.com/kaspanet/kaspad/util" "github.com/kaspanet/kaspad/util/daghash" @@ -48,7 +49,7 @@ func (f *FlowContext) SharedRequestedBlocks() *blockrelay.SharedRequestedBlocks } // AddBlock adds the given block to the DAG and propagates it. -func (f *FlowContext) AddBlock(block *util.Block) error { - // TODO(libp2p): unimplemented - panic("unimplemented") +func (f *FlowContext) AddBlock(block *util.Block, flags blockdag.BehaviorFlags) error { + _, _, err := f.DAG().ProcessBlock(block, flags) + return err } diff --git a/protocol/manager.go b/protocol/manager.go index 4a5b5fbbe..534b03186 100644 --- a/protocol/manager.go +++ b/protocol/manager.go @@ -59,6 +59,6 @@ func (m *Manager) AddTransaction(tx *util.Tx) error { } // AddBlock adds the given block to the DAG and propagates it. -func (m *Manager) AddBlock(block *util.Block) error { - return m.context.AddBlock(block) +func (m *Manager) AddBlock(block *util.Block, flags blockdag.BehaviorFlags) error { + return m.context.AddBlock(block, flags) } diff --git a/rpc/handle_submit_block.go b/rpc/handle_submit_block.go index 3ed36393e..1a61c6adb 100644 --- a/rpc/handle_submit_block.go +++ b/rpc/handle_submit_block.go @@ -3,6 +3,7 @@ package rpc import ( "encoding/hex" "fmt" + "github.com/kaspanet/kaspad/blockdag" "github.com/kaspanet/kaspad/rpc/model" "github.com/kaspanet/kaspad/util" ) @@ -13,9 +14,6 @@ func handleSubmitBlock(s *Server, cmd interface{}, closeChan <-chan struct{}) (i // Deserialize the submitted block. hexStr := c.HexBlock - if len(hexStr)%2 != 0 { - hexStr = "0" + c.HexBlock - } serializedBlock, err := hex.DecodeString(hexStr) if err != nil { return nil, rpcDecodeHexError(hexStr) @@ -29,9 +27,7 @@ func handleSubmitBlock(s *Server, cmd interface{}, closeChan <-chan struct{}) (i } } - // Process this block using the same rules as blocks coming from other - // nodes. This will in turn relay it to the network like normal. - err = s.protocolManager.AddBlock(block) + err = s.protocolManager.AddBlock(block, blockdag.BFDisallowDelay|blockdag.BFDisallowOrphans) if err != nil { return nil, &model.RPCError{ Code: model.ErrRPCVerify,