mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-05-28 09:46:50 +00:00

* Don't error out if antiPastHashesBetween have 2 blocks with the same blue score * Prepend lowHash to RPC GetBlocks request * Add a test for GetHashesBetween * Add a test for GetBlocks RPC call * Update antipast.go Co-authored-by: stasatdaglabs <39559713+stasatdaglabs@users.noreply.github.com>
96 lines
3.3 KiB
Go
96 lines
3.3 KiB
Go
package rpchandlers
|
|
|
|
import (
|
|
"github.com/kaspanet/kaspad/app/appmessage"
|
|
"github.com/kaspanet/kaspad/app/rpc/rpccontext"
|
|
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
|
"github.com/kaspanet/kaspad/domain/consensus/utils/hashes"
|
|
"github.com/kaspanet/kaspad/infrastructure/network/netadapter/router"
|
|
)
|
|
|
|
const (
|
|
// maxBlocksInGetBlocksResponse is the max amount of blocks that are
|
|
// allowed in a GetBlocksResult.
|
|
maxBlocksInGetBlocksResponse = 100
|
|
)
|
|
|
|
// HandleGetBlocks handles the respectively named RPC command
|
|
func HandleGetBlocks(context *rpccontext.Context, _ *router.Router, request appmessage.Message) (appmessage.Message, error) {
|
|
getBlocksRequest := request.(*appmessage.GetBlocksRequestMessage)
|
|
|
|
// Validate that user didn't set IncludeTransactionVerboseData without setting IncludeBlockVerboseData
|
|
if !getBlocksRequest.IncludeBlockVerboseData && getBlocksRequest.IncludeTransactionVerboseData {
|
|
return &appmessage.GetBlocksResponseMessage{
|
|
Error: appmessage.RPCErrorf(
|
|
"If includeTransactionVerboseData is set, then includeBlockVerboseData must be set as well"),
|
|
}, nil
|
|
}
|
|
|
|
// Decode lowHash
|
|
// If lowHash is empty - use genesis instead.
|
|
lowHash := context.Config.ActiveNetParams.GenesisHash
|
|
if getBlocksRequest.LowHash != "" {
|
|
var err error
|
|
lowHash, err = externalapi.NewDomainHashFromString(getBlocksRequest.LowHash)
|
|
if err != nil {
|
|
return &appmessage.GetBlocksResponseMessage{
|
|
Error: appmessage.RPCErrorf("Could not decode lowHash %s: %s", getBlocksRequest.LowHash, err),
|
|
}, nil
|
|
}
|
|
}
|
|
|
|
// Get hashes between lowHash and virtualSelectedParent
|
|
virtualSelectedParent, err := context.Domain.Consensus().GetVirtualSelectedParent()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
blockHashes, err := context.Domain.Consensus().GetHashesBetween(
|
|
lowHash, virtualSelectedParent, maxBlocksInGetBlocksResponse)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// prepend low hash to make it inclusive
|
|
blockHashes = append([]*externalapi.DomainHash{lowHash}, blockHashes...)
|
|
|
|
// If there are no maxBlocksInGetBlocksResponse between lowHash and virtualSelectedParent -
|
|
// add virtualSelectedParent's anticone
|
|
if len(blockHashes) < maxBlocksInGetBlocksResponse {
|
|
virtualSelectedParentAnticone, err := context.Domain.Consensus().Anticone(virtualSelectedParent)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
blockHashes = append(blockHashes, virtualSelectedParentAnticone...)
|
|
}
|
|
|
|
// Both GetHashesBetween and Anticone might return more then the allowed number of blocks, so
|
|
// trim any extra blocks.
|
|
if len(blockHashes) > maxBlocksInGetBlocksResponse {
|
|
blockHashes = blockHashes[:maxBlocksInGetBlocksResponse]
|
|
}
|
|
|
|
// Prepare the response
|
|
response := &appmessage.GetBlocksResponseMessage{
|
|
BlockHashes: hashes.ToStrings(blockHashes),
|
|
}
|
|
|
|
// Retrieve all block data in case BlockVerboseData was requested
|
|
if getBlocksRequest.IncludeBlockVerboseData {
|
|
response.BlockVerboseData = make([]*appmessage.BlockVerboseData, len(blockHashes))
|
|
for i, blockHash := range blockHashes {
|
|
blockHeader, err := context.Domain.Consensus().GetBlockHeader(blockHash)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
blockVerboseData, err := context.BuildBlockVerboseData(blockHeader, nil,
|
|
getBlocksRequest.IncludeTransactionVerboseData)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
response.BlockVerboseData[i] = blockVerboseData
|
|
}
|
|
}
|
|
return response, nil
|
|
}
|