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  }