github.com/Synthesix/Sia@v1.3.3-0.20180413141344-f863baeed3ca/node/api/miner_test.go (about)

     1  package api
     2  
     3  import (
     4  	"io/ioutil"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/Synthesix/Sia/crypto"
     9  	"github.com/Synthesix/Sia/types"
    10  )
    11  
    12  // TestMinerGET checks the GET call to the /miner endpoint.
    13  func TestMinerGET(t *testing.T) {
    14  	if testing.Short() {
    15  		t.SkipNow()
    16  	}
    17  	t.Parallel()
    18  	st, err := createServerTester(t.Name())
    19  	if err != nil {
    20  		t.Fatal(err)
    21  	}
    22  	defer st.server.panicClose()
    23  
    24  	// Get the api returned fields of the miner.
    25  	var mg MinerGET
    26  	err = st.getAPI("/miner", &mg)
    27  	if err != nil {
    28  		t.Fatal(err)
    29  	}
    30  
    31  	// Verify the correctness of the results.
    32  	blocksMined, staleBlocksMined := st.server.api.miner.BlocksMined()
    33  	if mg.BlocksMined != blocksMined {
    34  		t.Error("blocks mined did not succeed")
    35  	}
    36  	if mg.StaleBlocksMined != staleBlocksMined {
    37  		t.Error("stale blocks mined is incorrect")
    38  	}
    39  	if mg.CPUHashrate != st.server.api.miner.CPUHashrate() {
    40  		t.Error("mismatched cpu hashrate")
    41  	}
    42  	if mg.CPUMining != st.server.api.miner.CPUMining() {
    43  		t.Error("mismatched cpu miner status")
    44  	}
    45  }
    46  
    47  // TestMinerStartStop checks that the miner start and miner stop api endpoints
    48  // toggle the cpu miner.
    49  func TestMinerStartStop(t *testing.T) {
    50  	if testing.Short() {
    51  		t.SkipNow()
    52  	}
    53  	t.Parallel()
    54  	st, err := createServerTester(t.Name())
    55  	if err != nil {
    56  		t.Fatal(err)
    57  	}
    58  	defer st.server.panicClose()
    59  
    60  	// Start the cpu miner, give time for the first hashrate readings to
    61  	// appear.
    62  	err = st.stdGetAPI("/miner/start")
    63  	if err != nil {
    64  		t.Fatal(err)
    65  	}
    66  	time.Sleep(100 * time.Millisecond)
    67  	if !st.server.api.miner.CPUMining() {
    68  		t.Error("cpu miner is reporting that it is not on")
    69  	}
    70  
    71  	// Check the numbers through the status api call.
    72  	var mg MinerGET
    73  	err = st.getAPI("/miner", &mg)
    74  	if err != nil {
    75  		t.Fatal(err)
    76  	}
    77  	if !mg.CPUMining {
    78  		t.Error("cpu is not reporting through the api that it is mining")
    79  	}
    80  
    81  	// Stop the cpu miner and wait for the stop call to go through.
    82  	err = st.stdGetAPI("/miner/stop")
    83  	if err != nil {
    84  		t.Fatal(err)
    85  	}
    86  	time.Sleep(100 * time.Millisecond)
    87  	if st.server.api.miner.CPUMining() {
    88  		t.Error("cpu miner is reporting that it is on after being stopped")
    89  	}
    90  
    91  	// Check the numbers through the status api call.
    92  	err = st.getAPI("/miner", &mg)
    93  	if err != nil {
    94  		t.Fatal(err)
    95  	}
    96  	if mg.CPUMining {
    97  		t.Error("cpu is not reporting through the api that it is mining")
    98  	}
    99  }
   100  
   101  // TestMinerHeader checks that the header GET and POST calls are
   102  // useful tools for mining blocks.
   103  func TestMinerHeader(t *testing.T) {
   104  	if testing.Short() {
   105  		t.SkipNow()
   106  	}
   107  	t.Parallel()
   108  	st, err := createServerTester(t.Name())
   109  	if err != nil {
   110  		t.Fatal(err)
   111  	}
   112  	defer st.server.panicClose()
   113  	startingHeight := st.cs.Height()
   114  
   115  	// Get a header that can be used for mining.
   116  	resp, err := HttpGET("http://" + st.server.listener.Addr().String() + "/miner/header")
   117  	if err != nil {
   118  		t.Fatal(err)
   119  	}
   120  	defer resp.Body.Close()
   121  	targetAndHeader, err := ioutil.ReadAll(resp.Body)
   122  	if err != nil {
   123  		t.Fatal(err)
   124  	}
   125  
   126  	// Twiddle the header bits until a block has been found.
   127  	//
   128  	// Note: this test treats the target as hardcoded, if the testing target is
   129  	// changed, this test will also need to be changed.
   130  	if types.RootTarget[0] != 128 {
   131  		t.Fatal("test will fail because the testing constants have been unexpectedly changed")
   132  	}
   133  	var header [80]byte
   134  	copy(header[:], targetAndHeader[32:])
   135  	headerHash := crypto.HashObject(header)
   136  	for headerHash[0] >= types.RootTarget[0] {
   137  		header[35]++
   138  		headerHash = crypto.HashObject(header)
   139  	}
   140  
   141  	// Submit the solved header through the api and check that the height of
   142  	// the blockchain increases.
   143  	resp, err = HttpPOST("http://"+st.server.listener.Addr().String()+"/miner/header", string(header[:]))
   144  	if err != nil {
   145  		t.Fatal(err)
   146  	}
   147  	defer resp.Body.Close()
   148  	time.Sleep(500 * time.Millisecond)
   149  	if st.cs.Height() != startingHeight+1 {
   150  		t.Errorf("block height did not increase after trying to mine a block through the api, started at %v and ended at %v", startingHeight, st.cs.Height())
   151  	}
   152  }