stasatdaglabs 7f899b0d09
[NOD-1579] Improve the IBD mechanism (#1174)
* [NOD-1579] Remove selected tip hash messages.

* [NOD-1579] Start moving IBD stuff into blockrelay.

* [NOD-1579] Rename relaytransactions to transactionrelay.

* [NOD-1579] Move IBD files into blockrelay.

* [NOD-1579] Remove flow stuff from ibd.go.

* [NOD-1579] Bring back IsInIBD().

* [NOD-1579] Simplify block relay flow.

* [NOD-1579] Check orphan pool for missing parents to avoid unnecessary processing.

* [NOD-1579] Implement processOrphan.

* [NOD-1579] Implement addToOrphanSetAndRequestMissingParents.

* [NOD-1579] Fix TestIBD.

* [NOD-1579] Implement isBlockInOrphanResolutionRange.

* [NOD-1579] Implement limited block locators.

* [NOD-1579] Add some comments.

* [NOD-1579] Specifically check for StatusHeaderOnly in blockrelay.

* [NOD-1579] Simplify runIBDIfNotRunning.

* [NOD-1579] Don't run IBD if it is already running.

* [NOD-1579] Fix a comment.

* [NOD-1579] Rename mode to syncInfo.

* [NOD-1579] Simplify validateAndInsertBlock.

* [NOD-1579] Fix bad SyncStateSynced condition.

* [NOD-1579] Implement validateAgainstSyncStateAndResolveInsertMode.

* [NOD-1579] Use insertModeHeader.

* [NOD-1579] Add logs to TrySetIBDRunning and UnsetIBDRunning.

* [NOD-1579] Implement and use dequeueIncomingMessageAndSkipInvs.

* [NOD-1579] Fix a log.

* [NOD-1579] Fix a bug in createBlockLocator.

* [NOD-1579] Rename a variable.

* [NOD-1579] Fix a slew of bugs in missingBlockBodyHashes and selectedChildIterator.

* [NOD-1579] Fix bad chunk size in syncMissingBlockBodies.

* [NOD-1579] Remove maxOrphanBlueScoreDiff.

* [NOD-1579] Fix merge errors.

* [NOD-1579] Remove a debug log.

* [NOD-1579] Add logs.

* [NOD-1579] Make various go quality tools happy.

* [NOD-1579] Fix a typo in a variable name.

* [NOD-1579] Fix full blocks over header-only blocks not failing the missing-parents validation.

* [NOD-1579] Add an error log about a condition that should never happen.

* [NOD-1579] Check all antiPast hashes instead of just the lowHash's anticone to filter for header-only blocks.

* [NOD-1579] Remove the nil stuff from GetBlockLocator.

* [NOD-1579] Remove superfluous condition in handleRelayInvsFlow.start().

* [NOD-1579] Return a boolean from requestBlock instead of comparing to nil.

* [NOD-1579] Fix a bad log.Debugf.

* [NOD-1579] Remove a redundant check.

* [NOD-1579] Change an info log to a warning log.

* [NOD-1579] Move OnNewBlock out of relayBlock.

* [NOD-1579] Remove redundant exists check from runIBDIfNotRunning.

* [NOD-1579] Fix bad call to OnNewBlock.

* [NOD-1579] Remove an impossible check.

* [NOD-1579] Added a log.

* [NOD-1579] Rename insertModeBlockWithoutUpdatingVirtual to insertModeBlockBody.

* [NOD-1579] Add a check for duplicate headers.

* [NOD-1579] Added a comment.

* [NOD-1579] Tighten a stop condition.

* [NOD-1579] Simplify a log.

* [NOD-1579] Clarify a log.

* [NOD-1579] Move a log.
2020-12-06 16:23:56 +02:00

582 lines
16 KiB
Go

package protowire
import (
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/pkg/errors"
)
type converter interface {
toAppMessage() (appmessage.Message, error)
}
// ToAppMessage converts a KaspadMessage to its appmessage.Message representation
func (x *KaspadMessage) ToAppMessage() (appmessage.Message, error) {
appMessage, err := x.Payload.(converter).toAppMessage()
if err != nil {
return nil, err
}
return appMessage, nil
}
// FromAppMessage creates a KaspadMessage from a appmessage.Message
func FromAppMessage(message appmessage.Message) (*KaspadMessage, error) {
payload, err := toPayload(message)
if err != nil {
return nil, err
}
return &KaspadMessage{
Payload: payload,
}, nil
}
func toPayload(message appmessage.Message) (isKaspadMessage_Payload, error) {
p2pPayload, err := toP2PPayload(message)
if err != nil {
return nil, err
}
if p2pPayload != nil {
return p2pPayload, nil
}
rpcPayload, err := toRPCPayload(message)
if err != nil {
return nil, err
}
if rpcPayload != nil {
return rpcPayload, nil
}
return nil, errors.Errorf("unknown message type %T", message)
}
func toP2PPayload(message appmessage.Message) (isKaspadMessage_Payload, error) {
switch message := message.(type) {
case *appmessage.MsgAddresses:
payload := new(KaspadMessage_Addresses)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.MsgBlock:
payload := new(KaspadMessage_Block)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.MsgRequestBlockLocator:
payload := new(KaspadMessage_RequestBlockLocator)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.MsgBlockLocator:
payload := new(KaspadMessage_BlockLocator)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.MsgRequestAddresses:
payload := new(KaspadMessage_RequestAddresses)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.MsgRequestIBDBlocks:
payload := new(KaspadMessage_RequestIBDBlocks)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.MsgRequestNextHeaders:
payload := new(KaspadMessage_RequestNextHeaders)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.MsgDoneHeaders:
payload := new(KaspadMessage_DoneHeaders)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.MsgRequestRelayBlocks:
payload := new(KaspadMessage_RequestRelayBlocks)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.MsgRequestTransactions:
payload := new(KaspadMessage_RequestTransactions)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.MsgTransactionNotFound:
payload := new(KaspadMessage_TransactionNotFound)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.MsgIBDBlock:
payload := new(KaspadMessage_IbdBlock)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.MsgInvRelayBlock:
payload := new(KaspadMessage_InvRelayBlock)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.MsgInvTransaction:
payload := new(KaspadMessage_InvTransactions)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.MsgPing:
payload := new(KaspadMessage_Ping)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.MsgPong:
payload := new(KaspadMessage_Pong)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.MsgTx:
payload := new(KaspadMessage_Transaction)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.MsgVerAck:
payload := new(KaspadMessage_Verack)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.MsgVersion:
payload := new(KaspadMessage_Version)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.MsgReject:
payload := new(KaspadMessage_Reject)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.MsgBlockHeader:
payload := new(KaspadMessage_BlockHeader)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.MsgRequestIBDRootUTXOSetAndBlock:
payload := new(KaspadMessage_RequestIBDRootUTXOSetAndBlock)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.MsgIBDRootUTXOSetAndBlock:
payload := new(KaspadMessage_IbdRootUTXOSetAndBlock)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.MsgRequestHeaders:
payload := new(KaspadMessage_RequestHeaders)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.MsgIBDRootNotFound:
payload := new(KaspadMessage_IbdRootNotFound)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
default:
return nil, nil
}
}
func toRPCPayload(message appmessage.Message) (isKaspadMessage_Payload, error) {
switch message := message.(type) {
case *appmessage.GetCurrentNetworkRequestMessage:
payload := new(KaspadMessage_GetCurrentNetworkRequest)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.GetCurrentNetworkResponseMessage:
payload := new(KaspadMessage_GetCurrentNetworkResponse)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.SubmitBlockRequestMessage:
payload := new(KaspadMessage_SubmitBlockRequest)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.SubmitBlockResponseMessage:
payload := new(KaspadMessage_SubmitBlockResponse)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.GetBlockTemplateRequestMessage:
payload := new(KaspadMessage_GetBlockTemplateRequest)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.GetBlockTemplateResponseMessage:
payload := new(KaspadMessage_GetBlockTemplateResponse)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.NotifyBlockAddedRequestMessage:
payload := new(KaspadMessage_NotifyBlockAddedRequest)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.NotifyBlockAddedResponseMessage:
payload := new(KaspadMessage_NotifyBlockAddedResponse)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.BlockAddedNotificationMessage:
payload := new(KaspadMessage_BlockAddedNotification)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.GetPeerAddressesRequestMessage:
payload := new(KaspadMessage_GetPeerAddressesRequest)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.GetPeerAddressesResponseMessage:
payload := new(KaspadMessage_GetPeerAddressesResponse)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.GetSelectedTipHashRequestMessage:
payload := new(KaspadMessage_GetSelectedTipHashRequest)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.GetSelectedTipHashResponseMessage:
payload := new(KaspadMessage_GetSelectedTipHashResponse)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.GetMempoolEntryRequestMessage:
payload := new(KaspadMessage_GetMempoolEntryRequest)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.GetMempoolEntryResponseMessage:
payload := new(KaspadMessage_GetMempoolEntryResponse)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.GetConnectedPeerInfoRequestMessage:
payload := new(KaspadMessage_GetConnectedPeerInfoRequest)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.GetConnectedPeerInfoResponseMessage:
payload := new(KaspadMessage_GetConnectedPeerInfoResponse)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.AddPeerRequestMessage:
payload := new(KaspadMessage_AddPeerRequest)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.AddPeerResponseMessage:
payload := new(KaspadMessage_AddPeerResponse)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.SubmitTransactionRequestMessage:
payload := new(KaspadMessage_SubmitTransactionRequest)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.SubmitTransactionResponseMessage:
payload := new(KaspadMessage_SubmitTransactionResponse)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.NotifyChainChangedRequestMessage:
payload := new(KaspadMessage_NotifyChainChangedRequest)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.NotifyChainChangedResponseMessage:
payload := new(KaspadMessage_NotifyChainChangedResponse)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.ChainChangedNotificationMessage:
payload := new(KaspadMessage_ChainChangedNotification)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.GetBlockRequestMessage:
payload := new(KaspadMessage_GetBlockRequest)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.GetBlockResponseMessage:
payload := new(KaspadMessage_GetBlockResponse)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.GetSubnetworkRequestMessage:
payload := new(KaspadMessage_GetSubnetworkRequest)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.GetSubnetworkResponseMessage:
payload := new(KaspadMessage_GetSubnetworkResponse)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.GetChainFromBlockRequestMessage:
payload := new(KaspadMessage_GetChainFromBlockRequest)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.GetChainFromBlockResponseMessage:
payload := new(KaspadMessage_GetChainFromBlockResponse)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.GetBlocksRequestMessage:
payload := new(KaspadMessage_GetBlocksRequest)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.GetBlocksResponseMessage:
payload := new(KaspadMessage_GetBlocksResponse)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.GetBlockCountRequestMessage:
payload := new(KaspadMessage_GetBlockCountRequest)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.GetBlockCountResponseMessage:
payload := new(KaspadMessage_GetBlockCountResponse)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.GetBlockDAGInfoRequestMessage:
payload := new(KaspadMessage_GetBlockDagInfoRequest)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.GetBlockDAGInfoResponseMessage:
payload := new(KaspadMessage_GetBlockDagInfoResponse)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.ResolveFinalityConflictRequestMessage:
payload := new(KaspadMessage_ResolveFinalityConflictRequest)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.ResolveFinalityConflictResponseMessage:
payload := new(KaspadMessage_ResolveFinalityConflictResponse)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.NotifyFinalityConflictsRequestMessage:
payload := new(KaspadMessage_NotifyFinalityConflictsRequest)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.NotifyFinalityConflictsResponseMessage:
payload := new(KaspadMessage_NotifyFinalityConflictsResponse)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.FinalityConflictNotificationMessage:
payload := new(KaspadMessage_FinalityConflictNotification)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.FinalityConflictResolvedNotificationMessage:
payload := new(KaspadMessage_FinalityConflictResolvedNotification)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.GetMempoolEntriesRequestMessage:
payload := new(KaspadMessage_GetMempoolEntriesRequest)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.GetMempoolEntriesResponseMessage:
payload := new(KaspadMessage_GetMempoolEntriesResponse)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.ShutDownRequestMessage:
payload := new(KaspadMessage_ShutDownRequest)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.ShutDownResponseMessage:
payload := new(KaspadMessage_ShutDownResponse)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.GetHeadersRequestMessage:
payload := new(KaspadMessage_GetHeadersRequest)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
case *appmessage.GetHeadersResponseMessage:
payload := new(KaspadMessage_GetHeadersResponse)
err := payload.fromAppMessage(message)
if err != nil {
return nil, err
}
return payload, nil
default:
return nil, nil
}
}