github.com/deroproject/derosuite@v2.1.6-1.0.20200307070847-0f2e589c7a2b+incompatible/blockchain/rpcserver/getoutputs.bin.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 rpcserver
    18  
    19  import "strconv"
    20  import "net/http"
    21  
    22  import "compress/gzip"
    23  
    24  //import "github.com/pierrec/lz4"
    25  
    26  // serve the outputs in streaming mode
    27  
    28  // feeds any outputs requested by the server
    29  func getoutputs(rw http.ResponseWriter, req *http.Request) {
    30  	var err error
    31  	start := int64(0)
    32  	stop := int64(0)
    33  	start_height := int64(0)
    34  
    35  	{ // parse start query parameter
    36  		keys, ok := req.URL.Query()["startheight"]
    37  		if !ok || len(keys) < 1 {
    38  			//log.Println("Url Param 'key' is missing")
    39  			//return
    40  		} else {
    41  			start_string := keys[0]
    42  			start_height, err = strconv.ParseInt(start_string, 10, 64)
    43  			if err != nil {
    44  				start_height = 0
    45  			}
    46  
    47  			//logger.Warnf("sending data from height %d chain height %d\n", start_height, chain.Get_Height())
    48  
    49  			// set the start pointer based on vout index
    50  			if start_height <= int64(chain.Load_TOPO_HEIGHT(nil)) {
    51  				// convert height to block
    52  				blid, err := chain.Load_Block_Topological_order_at_index(nil, int64(start_height))
    53  				//logger.Warnf("sending data from height %d err %s\n", start_height, err)
    54  				if err == nil {
    55  					start, _ = chain.Get_Block_Output_Index(nil, blid)
    56  				}
    57  
    58  			}
    59  		}
    60  	}
    61  
    62  	{ // parse start query parameter
    63  		keys, ok := req.URL.Query()["start"]
    64  		if !ok || len(keys) < 1 {
    65  			//log.Println("Url Param 'key' is missing")
    66  			//return
    67  		} else {
    68  			start_string := keys[0]
    69  			start, err = strconv.ParseInt(start_string, 10, 64)
    70  			if err != nil {
    71  				start = 0
    72  			}
    73  		}
    74  	}
    75  
    76  	{ // parse stop query parameter
    77  		keys, ok := req.URL.Query()["stop"]
    78  		if !ok || len(keys) < 1 {
    79  
    80  		} else {
    81  			stop_string := keys[0]
    82  			stop, err = strconv.ParseInt(stop_string, 10, 64)
    83  			if err != nil {
    84  				stop = 0
    85  			}
    86  		}
    87  	}
    88  
    89  	// TODO BUG FIXME
    90  	// do sanity check of stop  first
    91  	//top_id := chain.Get_Top_ID()
    92  	//biggest_output_index := chain.Block_Count_Vout(nil,top_id) + chain.Get_Block_Output_Index(nil,top_id)
    93  
    94  	biggest_output_index := int64(0)
    95  
    96  	// convert height to block
    97  	top_block, err := chain.Load_Block_Topological_order_at_index(nil, chain.Load_TOPO_HEIGHT(nil))
    98  	//logger.Warnf("sending data from height %d err %s\n", start_height, err)
    99  	if err == nil {
   100  		_, biggest_output_index = chain.Get_Block_Output_Index(nil, top_block)
   101  
   102  	}
   103  
   104  	if stop == 0 || stop > biggest_output_index {
   105  		stop = biggest_output_index
   106  	}
   107  
   108  	// feed in atleast 1 index
   109  	if start >= stop {
   110  		start = stop - 1
   111  	}
   112  
   113  	//   lz4writer := lz4.NewWriter(rw)
   114  	//lz4writer.HighCompression = true // enable extreme but slow compression
   115  	//lz4writer.BlockMaxSize = 256*1024 // small block size to decrease memory consumption
   116  
   117  	gzipwriter := gzip.NewWriter(rw)
   118  	defer gzipwriter.Close()
   119  	for i := start; i < stop; i++ {
   120  		// load the bytes and send them
   121  		data, err := chain.Read_output_index(nil, uint64(i))
   122  		if err != nil {
   123  			logger.Warnf("err while reading output err: %s\n", err)
   124  			break
   125  		}
   126  
   127  		//
   128  		//rw.Write(data)
   129  		// lz4writer.Write(data)
   130  		gzipwriter.Write(data)
   131  
   132  	}
   133  	//lz4writer.Flush() // flush any pending data
   134  
   135  }