github.com/deroproject/derosuite@v2.1.6-1.0.20200307070847-0f2e589c7a2b+incompatible/p2p/object_pool.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"
    22  import "time"
    23  
    24  //import "container/list"
    25  
    26  //import log "github.com/sirupsen/logrus"
    27  //import "github.com/vmihailenco/msgpack"
    28  
    29  import "github.com/deroproject/derosuite/crypto"
    30  
    31  //import "github.com/deroproject/derosuite/globals"
    32  
    33  import "github.com/deroproject/derosuite/block"
    34  
    35  // if block request pool is empty, we are syncronised otherwise we are syncronising
    36  var block_request_pool = map[crypto.Hash]uint64{} // these are received, we must attach a connection to blacklist peers
    37  
    38  var block_received = map[crypto.Hash]*block.Complete_Block{} // once blocks are received, they are placed here
    39  var block_request_pool_mutex sync.Mutex
    40  
    41  func queue_block(blid crypto.Hash) {
    42  	block_request_pool_mutex.Lock()
    43  	defer block_request_pool_mutex.Unlock()
    44  
    45  	// if object has already been received, it no longer should be request
    46  	if _, ok := block_received[blid]; ok { // object is already in pool
    47  		return
    48  	}
    49  
    50  	// if object has already been requested, skip it , else add it to queue
    51  	if _, ok := block_request_pool[blid]; !ok {
    52  		block_request_pool[blid] = 0
    53  	}
    54  }
    55  
    56  // a block hash been received, make it ready for consumption
    57  func queue_block_received(blid crypto.Hash, cbl *block.Complete_Block) {
    58  	block_request_pool_mutex.Lock()
    59  	defer block_request_pool_mutex.Unlock()
    60  
    61  	if _, ok := block_request_pool[blid]; !ok {
    62  		// unknown object received discard it
    63  		return
    64  	}
    65  	delete(block_request_pool, blid)
    66  
    67  	block_received[blid] = cbl
    68  }
    69  
    70  // continusly retrieve_objects
    71  func retrieve_objects() {
    72  
    73  	for {
    74  		select {
    75  		case <-Exit_Event:
    76  			return
    77  		case <-time.After(5 * time.Second):
    78  		}
    79  
    80  		block_request_pool_mutex.Lock()
    81  
    82  		for k, _ := range block_request_pool {
    83  
    84  			connection := Random_Connection(0)
    85  			if connection != nil {
    86  				connection.Send_ObjectRequest([]crypto.Hash{k}, []crypto.Hash{})
    87  			}
    88  		}
    89  		block_request_pool_mutex.Unlock()
    90  
    91  	}
    92  
    93  }
    94  
    95  // this goroutine will keep searching the queue for any blocks and see if they are can be attached somewhere, if yes they will be attached and cleaned up
    96  func sync_retrieved_blocks() {
    97  	// success := make(chan bool)
    98  	for {
    99  
   100  		select {
   101  		case <-Exit_Event:
   102  			return
   103  		//case <- success:
   104  		case <-time.After(1 * time.Second):
   105  		}
   106  
   107  		block_request_pool_mutex.Lock()
   108  
   109  		for blid, cbl := range block_received {
   110  			if chain.Block_Exists(nil, blid) { /// block is already in chain, discard it
   111  				delete(block_received, blid)
   112  				continue
   113  			}
   114  			_ = cbl
   115  			/*if cbl == nil {
   116  			    delete(block_received,blid)
   117  			     block_request_pool[blid]=0 // need to request object again
   118  			    continue
   119  			}*/
   120  
   121  			/*
   122  				// attach it to parent, else skip for now
   123  				if chain.Block_Exists(cbl.Bl.Prev_Hash) {
   124  					if chain.Add_Complete_Block(cbl) {
   125  						// if block successfully added , delete it now
   126  						delete(block_received, blid)
   127  
   128  						continue
   129  					} else { // checksum of something failed, request it randomly from another peer
   130  						block_request_pool[blid] = 0
   131  					}
   132  				}*/
   133  		}
   134  		block_request_pool_mutex.Unlock()
   135  	}
   136  }