mirror of
https://github.com/PeernetOfficial/core.git
synced 2026-07-17 02:47:51 +01:00
Get Block message: BlockTransferReadBlock validate limit. Fix in startBlockTransfer. New high-level function BlockDownload to download requested blocks.
This commit is contained in:
@@ -67,7 +67,7 @@ func (peer *PeerInfo) startBlockTransfer(BlockchainPublicKey *btcec.PublicKey, L
|
||||
udtConn.Write(blockData)
|
||||
|
||||
sentBlocks++
|
||||
if sentBlocks >= MaxBlockSize {
|
||||
if sentBlocks >= LimitBlockCount {
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -115,3 +115,44 @@ func (peer *PeerInfo) BlockTransferRequest(BlockchainPublicKey *btcec.PublicKey,
|
||||
|
||||
return udtConn, virtualConn, nil
|
||||
}
|
||||
|
||||
// Downloads the requested blocks for the selected blockchain from the remote peer. The callback is called for each result.
|
||||
func (peer *PeerInfo) BlockDownload(BlockchainPublicKey *btcec.PublicKey, LimitBlockCount, MaxBlockSize uint64, TargetBlocks []protocol.BlockRange, callback func(data []byte, targetBlock protocol.BlockRange, blockSize uint64, availability uint8)) (err error) {
|
||||
conn, _, err := peer.BlockTransferRequest(BlockchainPublicKey, LimitBlockCount, MaxBlockSize, TargetBlocks)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
var limit uint64
|
||||
for _, target := range TargetBlocks {
|
||||
limit += target.Limit
|
||||
}
|
||||
|
||||
for n := uint64(0); n < limit; {
|
||||
data, targetBlock, blockSize, availability, err := protocol.BlockTransferReadBlock(conn, MaxBlockSize)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !isTargetInRange(TargetBlocks, targetBlock.Offset, targetBlock.Limit) {
|
||||
return errors.New("invalid returned block range")
|
||||
}
|
||||
|
||||
// TODO: Check if the block was already returned in case the block is available. This can be done via simple map.
|
||||
|
||||
callback(data, targetBlock, blockSize, availability)
|
||||
|
||||
n += targetBlock.Limit
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func isTargetInRange(targets []protocol.BlockRange, offset, limit uint64) (valid bool) {
|
||||
for _, target := range targets {
|
||||
if offset >= target.Offset && offset+limit <= target.Offset+target.Limit {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -29,6 +29,8 @@ Offset Size Info
|
||||
2 = Block range exceeds size limit.
|
||||
1 16 Block range
|
||||
17 8 Block size
|
||||
|
||||
The limit in block range must be 1 if a block is returned.
|
||||
*/
|
||||
|
||||
package protocol
|
||||
@@ -197,12 +199,16 @@ func BlockTransferReadBlock(reader io.Reader, maxBlockSize uint64) (data []byte,
|
||||
targetBlock.Limit = binary.LittleEndian.Uint64(header[9:17])
|
||||
blockSize = binary.LittleEndian.Uint64(header[17:25])
|
||||
|
||||
if availability != GetBlockStatusAvailable { // return if status isn't available
|
||||
if targetBlock.Limit == 0 {
|
||||
return nil, targetBlock, blockSize, availability, errors.New("empty target block limit")
|
||||
} else if availability != GetBlockStatusAvailable { // return if status indicates the block is not available
|
||||
return nil, targetBlock, blockSize, availability, nil
|
||||
}
|
||||
|
||||
if blockSize > maxBlockSize {
|
||||
return nil, targetBlock, blockSize, availability, errors.New("remote block size exceeds limit")
|
||||
} else if targetBlock.Limit != 1 {
|
||||
return nil, targetBlock, blockSize, availability, errors.New("invalid target block limit")
|
||||
}
|
||||
|
||||
// read the block
|
||||
|
||||
Reference in New Issue
Block a user