github.com/deroproject/derosuite@v2.1.6-1.0.20200307070847-0f2e589c7a2b+incompatible/p2p/object_response.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 log "github.com/sirupsen/logrus" 27 import "github.com/romana/rlog" 28 import "github.com/vmihailenco/msgpack" 29 30 //import "github.com/deroproject/derosuite/crypto" 31 //import "github.com/deroproject/derosuite/globals" 32 33 import "github.com/deroproject/derosuite/block" 34 import "github.com/deroproject/derosuite/errormsg" 35 import "github.com/deroproject/derosuite/transaction" 36 37 // peer has responded with some objects, we must respond 38 func (connection *Connection) Handle_ObjectResponse(buf []byte) { 39 var response Object_Response_struct 40 41 err := msgpack.Unmarshal(buf, &response) 42 if err != nil { 43 rlog.Warnf("Error while decoding incoming object response err %s %s", err, connection.logid) 44 connection.Exit() 45 } 46 47 var expected Queued_Command 48 49 select { 50 case expected = <-connection.Objects: 51 52 default: // if nothing is on queue the peer sent us bogus request, 53 rlog.Warnf("Peer sent us a chain response, when we didnot request chain, Exiting, may be block the peer %s", connection.logid) 54 connection.Exit() 55 } 56 57 if expected.Command != V2_COMMAND_OBJECTS_RESPONSE { 58 rlog.Warnf("We were waiting for a different object, but peer sent something else, Exiting, may be block the peer %s", connection.logid) 59 connection.Exit() 60 } 61 62 // we need to verify common and update common 63 64 if len(response.CBlocks) != len(expected.BLID) { // we requested x block , peer sent us y blocks, time to ban peer 65 rlog.Warnf("we got %d response for %d requests %s %s", len(response.CBlocks), len(expected.BLID), connection.logid) 66 } 67 68 for i := 0; i < len(response.CBlocks); i++ { // process incoming full blocks 69 var cbl block.Complete_Block // parse incoming block and deserialize it 70 var bl block.Block 71 // lets deserialize block first and see whether it is the requested object 72 cbl.Bl = &bl 73 err := bl.Deserialize(response.CBlocks[i].Block) 74 if err != nil { // we have a block which could not be deserialized ban peer 75 rlog.Warnf("Error Incoming block could not be deserilised err %s %s", err, connection.logid) 76 connection.Exit() 77 return 78 } 79 80 // check if deserialized hash is same as what we requested 81 if bl.GetHash() != expected.BLID[i] { // user is trying to spoof block, ban hime 82 connection.logger.Warnf("requested and response block mismatch") 83 rlog.Warnf("Error block hash mismatch Actual %s Expected %s err %s %s", bl.GetHash(), expected.BLID[i], connection.logid) 84 connection.Exit() 85 } 86 87 // give the chain some more time to respond 88 atomic.StoreInt64(&connection.LastObjectRequestTime, time.Now().Unix()) 89 90 // check whether the object was requested one 91 92 // complete the txs 93 for j := range response.CBlocks[i].Txs { 94 var tx transaction.Transaction 95 err = tx.DeserializeHeader(response.CBlocks[i].Txs[j]) 96 if err != nil { // we have a tx which could not be deserialized ban peer 97 rlog.Warnf("Error Incoming TX could not be deserialized err %s %s", err, connection.logid) 98 connection.Exit() 99 100 return 101 } 102 cbl.Txs = append(cbl.Txs, &tx) 103 } 104 105 // check if we can add ourselves to chain 106 err, ok := chain.Add_Complete_Block(&cbl) 107 if !ok && err == errormsg.ErrInvalidPoW { 108 connection.logger.Warnf("This peer should be banned") 109 connection.Exit() 110 } 111 112 // add the object to object pool from where it will be consume 113 // queue_block_received(bl.GetHash(),&cbl) 114 115 } 116 117 }