github.com/deroproject/derosuite@v2.1.6-1.0.20200307070847-0f2e589c7a2b+incompatible/p2p/object_request.go (about)

     1  // Copyright 2017-2018 DERO Project. All rights reserved.
     2  // Use of this source code in any form is governed by RESEARCH license.
     3  // license can be found in the LICENSE file.
     4  // GPG: 0F39 E425 8C65 3947 702A  8234 08B2 0360 A03A 9DE8
     5  //
     6  //
     7  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
     8  // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     9  // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
    10  // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    11  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    12  // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    13  // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    14  // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
    15  // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    16  
    17  package p2p
    18  
    19  //import "fmt"
    20  //import "net"
    21  import "sync/atomic"
    22  import "time"
    23  
    24  //import "container/list"
    25  
    26  import "github.com/romana/rlog"
    27  import "github.com/vmihailenco/msgpack"
    28  
    29  //import "github.com/deroproject/derosuite/crypto"
    30  //import "github.com/deroproject/derosuite/globals"
    31  
    32  import "github.com/deroproject/derosuite/crypto"
    33  
    34  //import "github.com/deroproject/derosuite/globals"
    35  
    36  //import "github.com/deroproject/derosuite/blockchain"
    37  
    38  //  we are sending object request
    39  // right now we only send block ids
    40  func (connection *Connection) Send_ObjectRequest(blids []crypto.Hash, txids []crypto.Hash) {
    41  
    42  	var request Object_Request_Struct
    43  	fill_common(&request.Common) // fill common info
    44  	request.Command = V2_COMMAND_OBJECTS_REQUEST
    45  
    46  	for i := range blids {
    47  		request.Block_list = append(request.Block_list, blids[i])
    48  	}
    49  
    50  	for i := range txids {
    51  		request.Tx_list = append(request.Tx_list, txids[i])
    52  	}
    53  
    54  	if len(blids) > 0 || len(txids) > 0 {
    55  		serialized, err := msgpack.Marshal(&request) // serialize and send
    56  		if err != nil {
    57  			panic(err)
    58  		}
    59  
    60  		// use first object
    61  
    62  		command := Queued_Command{Command: V2_COMMAND_OBJECTS_RESPONSE, BLID: blids, TXID: txids}
    63  
    64  		connection.Objects <- command
    65  		atomic.StoreInt64(&connection.LastObjectRequestTime, time.Now().Unix())
    66  
    67  		// we should add to queue that we are waiting for object response
    68  		//command := Queued_Command{Command: V2_COMMAND_OBJECTS_RESPONSE, BLID: blids, TXID: txids, Started: time.Now()}
    69  
    70  		connection.Lock()
    71  		//connection.Command_queue.PushBack(command) // queue command
    72  		connection.Send_Message_prelocked(serialized)
    73  		connection.Unlock()
    74  		rlog.Tracef(3, "object request sent contains %d blids %d txids %s ", len(blids), connection.logid)
    75  	}
    76  }
    77  
    78  // peer has requested some objects, we must respond
    79  // if certain object is not in our list we respond with empty buffer for that slot
    80  func (connection *Connection) Handle_ObjectRequest(buf []byte) {
    81  	var request Object_Request_Struct
    82  	var response Object_Response_struct
    83  
    84  	err := msgpack.Unmarshal(buf, &request)
    85  	if err != nil {
    86  		rlog.Warnf("Error while decoding incoming object request err %s %s", err, connection.logid)
    87  		connection.Exit()
    88  	}
    89  
    90  	if len(request.Block_list) < 1 { // we are expecting 1 block
    91  		rlog.Warnf("malformed object request  received, banning peer %+v %s", request, connection.logid)
    92  		connection.Exit()
    93  	}
    94  
    95  	for i := 0; i < len(request.Block_list); i++ { // find the common point in our chain
    96  		var cbl Complete_Block
    97  		if chain.Block_Exists(nil, request.Block_list[i]) {
    98  			bl, _ := chain.Load_BL_FROM_ID(nil, request.Block_list[i])
    99  			cbl.Block = bl.Serialize()
   100  			for j := range bl.Tx_hashes {
   101  				tx, err := chain.Load_TX_FROM_ID(nil, bl.Tx_hashes[j])
   102  
   103  				if err != nil {
   104  					//rlog.Tracef(1, "ERR Cannot load tx from DB\n")
   105  					return
   106  				}
   107  				cbl.Txs = append(cbl.Txs, tx.Serialize()) // append all the txs
   108  			}
   109  		}
   110  
   111  		response.CBlocks = append(response.CBlocks, cbl)
   112  	}
   113  
   114  	// we can serve maximum of 1024 BLID = 32 KB
   115  
   116  	// if everything is OK, we must respond with object response
   117  	fill_common(&response.Common) // fill common info
   118  	response.Command = V2_COMMAND_OBJECTS_RESPONSE
   119  
   120  	serialized, err := msgpack.Marshal(&response) // serialize and send
   121  	if err != nil {
   122  		panic(err)
   123  	}
   124  
   125  	rlog.Tracef(3, "OBJECT RESPONSE SENT  sent size %d %s", len(serialized), connection.logid)
   126  	connection.Send_Message(serialized)
   127  }