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 }