2020-12-19 10:01:29 +00:00
// Copyright 2017-2021 DERO Project. All rights reserved.
// Use of this source code in any form is governed by RESEARCH license.
// license can be found in the LICENSE file.
// GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8
//
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package p2p
//import "fmt"
//import "net"
//import "container/list"
//import log "github.com/sirupsen/logrus"
import "github.com/romana/rlog"
//import "github.com/deroproject/derosuite/crypto"
import "github.com/deroproject/derohe/globals"
//import "github.com/deroproject/derosuite/blockchain"
// peer has requested chain
2021-02-22 17:48:14 +00:00
func ( c * Connection ) Chain ( request Chain_Request_Struct , response * Chain_Response_Struct ) error {
2020-12-19 10:01:29 +00:00
2021-02-22 17:48:14 +00:00
if len ( request . Block_list ) < 1 { // malformed request ban peer
rlog . Warnf ( "malformed chain request received, banning peer %+v %s" , request , globals . CTXString ( c . logger ) )
c . exit ( )
return nil
2020-12-19 10:01:29 +00:00
}
if len ( request . Block_list ) != len ( request . TopoHeights ) || len ( request . Block_list ) > 1024 {
rlog . Warnf ( "Peer chain request has %d block %d topos, therefore invalid" , len ( request . Block_list ) , len ( request . TopoHeights ) )
2021-02-22 17:48:14 +00:00
c . exit ( )
return nil
2020-12-19 10:01:29 +00:00
}
if request . Block_list [ len ( request . Block_list ) - 1 ] != globals . Config . Genesis_Block_Hash {
rlog . Warnf ( "Peer's genesis block is different from our, so disconnect Actual %s Expected %s" , request . Block_list [ len ( request . Block_list ) - 1 ] , globals . Config . Genesis_Block_Hash )
2021-02-22 17:48:14 +00:00
c . exit ( )
return nil
2020-12-19 10:01:29 +00:00
}
// we must give user our version of the chain
start_height := int64 ( 0 )
start_topoheight := int64 ( 0 )
for i := 0 ; i < len ( request . Block_list ) ; i ++ { // find the common point in our chain ( the block is NOT orphan)
2021-02-22 17:48:14 +00:00
//c.logger.Infof("Checking block for chain detection %d %s", i, request.Block_list[i])
2020-12-19 10:01:29 +00:00
if chain . Block_Exists ( request . Block_list [ i ] ) && chain . Is_Block_Topological_order ( request . Block_list [ i ] ) &&
request . TopoHeights [ i ] == chain . Load_Block_Topological_order ( request . Block_list [ i ] ) {
start_height = chain . Load_Height_for_BL_ID ( request . Block_list [ i ] )
start_topoheight = chain . Load_Block_Topological_order ( request . Block_list [ i ] )
rlog . Tracef ( 2 , "Found common point in chain at hash %x height %d topoheight %d\n" , request . Block_list [ i ] , start_height , start_topoheight )
break
}
}
// we can serve maximum of 512 BLID = 16K KB
const MAX_BLOCKS = 512
for i := start_topoheight ; i <= chain . Load_TOPO_HEIGHT ( ) && len ( response . Block_list ) <= MAX_BLOCKS ; i ++ {
hash , _ := chain . Load_Block_Topological_order_at_index ( i )
response . Block_list = append ( response . Block_list , [ 32 ] byte ( hash ) )
}
// we must also fill blocks for the last top 10 heights, so client can sync faster to alt tips
top_height := chain . Get_Height ( )
counter := 0
for ; top_height > 0 && counter <= 10 ; top_height -- {
blocks := chain . Get_Blocks_At_Height ( top_height )
for i := range blocks {
response . TopBlocks = append ( [ ] [ 32 ] byte { blocks [ i ] } , response . TopBlocks ... ) // blocks are ordered height wise
}
counter ++
}
response . Start_height = start_height
response . Start_topoheight = start_topoheight
fill_common ( & response . Common ) // fill common info
2021-02-22 17:48:14 +00:00
c . update ( & request . Common ) // update common information
2020-12-19 10:01:29 +00:00
2021-02-22 17:48:14 +00:00
return nil
2020-12-19 10:01:29 +00:00
}