git.gammaspectra.live/P2Pool/consensus/v3@v3.8.0/p2pool/stratum/template_test.go (about)

     1  package stratum
     2  
     3  import (
     4  	"bytes"
     5  	"git.gammaspectra.live/P2Pool/consensus/v3/monero/crypto"
     6  	"git.gammaspectra.live/P2Pool/consensus/v3/p2pool/sidechain"
     7  	"git.gammaspectra.live/P2Pool/consensus/v3/types"
     8  	fasthex "github.com/tmthrgd/go-hex"
     9  	unsafeRandom "math/rand/v2"
    10  	"testing"
    11  )
    12  
    13  func TestTemplate(t *testing.T) {
    14  	b := preLoadedPoolBlock
    15  	buf, _ := b.MarshalBinary()
    16  	tpl, err := TemplateFromPoolBlock(b)
    17  	if err != nil {
    18  		t.Fatal(err)
    19  	}
    20  
    21  	preAllocatedBuffer := make([]byte, 0, len(tpl.Buffer))
    22  
    23  	blockTemplateId := b.FastSideTemplateId(sidechain.ConsensusDefault)
    24  
    25  	if tplBuf := tpl.Blob(preAllocatedBuffer, b.Main.Nonce, b.ExtraNonce(), b.Side.ExtraBuffer.RandomNumber, b.Side.ExtraBuffer.SideChainExtraNonce, blockTemplateId); bytes.Compare(tplBuf, buf) != 0 {
    26  		if len(tplBuf) == len(buf) {
    27  			for i := range buf {
    28  				if buf[i] != tplBuf[i] {
    29  					t.Logf("%s %s *** @ %d", fasthex.EncodeToString(buf[i:i+1]), fasthex.EncodeToString(tplBuf[i:i+1]), i)
    30  				} else {
    31  					t.Logf("%s %s @ %d", fasthex.EncodeToString(buf[i:i+1]), fasthex.EncodeToString(tplBuf[i:i+1]), i)
    32  				}
    33  			}
    34  		}
    35  		t.Fatal("not matching blob buffers")
    36  	}
    37  
    38  	writer := bytes.NewBuffer(nil)
    39  
    40  	if err := tpl.Write(writer, b.Main.Nonce, b.ExtraNonce(), b.Side.ExtraBuffer.RandomNumber, b.Side.ExtraBuffer.SideChainExtraNonce, blockTemplateId); err != nil {
    41  		t.Fatal(err)
    42  	} else if bytes.Compare(writer.Bytes(), buf) != 0 {
    43  		t.Fatal("not matching writer buffers")
    44  	}
    45  
    46  	hasher := crypto.GetKeccak256Hasher()
    47  	defer crypto.PutKeccak256Hasher(hasher)
    48  
    49  	bHashingBlob := b.Main.HashingBlob(nil)
    50  	if tplHashingBlob := tpl.HashingBlob(hasher, preAllocatedBuffer, b.Main.Nonce, b.ExtraNonce(), blockTemplateId); bytes.Compare(tplHashingBlob, bHashingBlob) != 0 {
    51  		if len(tplHashingBlob) == len(bHashingBlob) {
    52  			for i := range buf {
    53  				if bHashingBlob[i] != tplHashingBlob[i] {
    54  					t.Logf("%s %s *** @ %d", fasthex.EncodeToString(bHashingBlob[i:i+1]), fasthex.EncodeToString(tplHashingBlob[i:i+1]), i)
    55  				} else {
    56  					t.Logf("%s %s @ %d", fasthex.EncodeToString(bHashingBlob[i:i+1]), fasthex.EncodeToString(tplHashingBlob[i:i+1]), i)
    57  				}
    58  			}
    59  		}
    60  		t.Fatal("not matching hashing blob buffers")
    61  	}
    62  
    63  	bCoinbaseBlob, _ := b.Main.Coinbase.MarshalBinary()
    64  	if tplCoinbaseBlob := tpl.CoinbaseBlob(preAllocatedBuffer, b.ExtraNonce(), blockTemplateId); bytes.Compare(tplCoinbaseBlob, bCoinbaseBlob) != 0 {
    65  		if len(tplCoinbaseBlob) == len(bCoinbaseBlob) {
    66  			for i := range buf {
    67  				if bCoinbaseBlob[i] != tplCoinbaseBlob[i] {
    68  					t.Logf("%s %s *** @ %d", fasthex.EncodeToString(bCoinbaseBlob[i:i+1]), fasthex.EncodeToString(tplCoinbaseBlob[i:i+1]), i)
    69  				} else {
    70  					t.Logf("%s %s @ %d", fasthex.EncodeToString(bCoinbaseBlob[i:i+1]), fasthex.EncodeToString(tplCoinbaseBlob[i:i+1]), i)
    71  				}
    72  			}
    73  		}
    74  		t.Fatal("not matching coinbase blob buffers")
    75  	}
    76  
    77  	var coinbaseId types.Hash
    78  
    79  	if tpl.CoinbaseId(hasher, b.ExtraNonce(), blockTemplateId, &coinbaseId); coinbaseId != b.Main.Coinbase.CalculateId() {
    80  		t.Fatal("different coinbase ids")
    81  	}
    82  
    83  	if tpl.CoinbaseBlobId(hasher, preAllocatedBuffer, b.ExtraNonce(), blockTemplateId, &coinbaseId); coinbaseId != b.Main.Coinbase.CalculateId() {
    84  		t.Fatal("different coinbase blob ids")
    85  	}
    86  
    87  	var templateId types.Hash
    88  	if tpl.TemplateId(hasher, preAllocatedBuffer, sidechain.ConsensusDefault, b.Side.ExtraBuffer.RandomNumber, b.Side.ExtraBuffer.SideChainExtraNonce, &templateId); templateId != blockTemplateId {
    89  		t.Fatal("different template ids")
    90  	}
    91  
    92  	if tpl.Timestamp() != b.Main.Timestamp {
    93  		t.Fatal("different timestamps")
    94  	}
    95  
    96  	if tpl.HashingBlobBufferLength() != b.Main.HashingBlobBufferLength() {
    97  		t.Fatal("different hashing blob buffer length")
    98  	}
    99  
   100  	if tpl.HashingBlobBufferLength() != len(tpl.HashingBlob(hasher, preAllocatedBuffer, 0, 0, types.ZeroHash)) {
   101  		t.Fatal("different hashing blob buffer length from blob")
   102  	}
   103  
   104  }
   105  
   106  func BenchmarkTemplate_CoinbaseId(b *testing.B) {
   107  	tpl, err := TemplateFromPoolBlock(preLoadedPoolBlock)
   108  	if err != nil {
   109  		b.Fatal(err)
   110  	}
   111  
   112  	b.ResetTimer()
   113  	b.RunParallel(func(pb *testing.PB) {
   114  		hasher := crypto.GetKeccak256Hasher()
   115  		defer crypto.PutKeccak256Hasher(hasher)
   116  		var counter = unsafeRandom.Uint32()
   117  		var coinbaseId types.Hash
   118  		for pb.Next() {
   119  			tpl.CoinbaseId(hasher, counter, types.ZeroHash, &coinbaseId)
   120  			counter++
   121  		}
   122  	})
   123  	b.ReportAllocs()
   124  }
   125  
   126  func BenchmarkTemplate_CoinbaseBlobId(b *testing.B) {
   127  	tpl, err := TemplateFromPoolBlock(preLoadedPoolBlock)
   128  	if err != nil {
   129  		b.Fatal(err)
   130  	}
   131  
   132  	b.ResetTimer()
   133  	b.RunParallel(func(pb *testing.PB) {
   134  		preAllocatedBuffer := make([]byte, 0, tpl.CoinbaseBufferLength())
   135  		hasher := crypto.GetKeccak256Hasher()
   136  		defer crypto.PutKeccak256Hasher(hasher)
   137  		var counter = unsafeRandom.Uint32()
   138  		var coinbaseId types.Hash
   139  		for pb.Next() {
   140  			tpl.CoinbaseBlobId(hasher, preAllocatedBuffer, counter, types.ZeroHash, &coinbaseId)
   141  			counter++
   142  		}
   143  	})
   144  	b.ReportAllocs()
   145  }
   146  
   147  func BenchmarkTemplate_HashingBlob(b *testing.B) {
   148  	tpl, err := TemplateFromPoolBlock(preLoadedPoolBlock)
   149  	if err != nil {
   150  		b.Fatal(err)
   151  	}
   152  
   153  	b.ResetTimer()
   154  
   155  	b.RunParallel(func(pb *testing.PB) {
   156  		preAllocatedBuffer := make([]byte, 0, tpl.HashingBlobBufferLength())
   157  		hasher := crypto.GetKeccak256Hasher()
   158  		defer crypto.PutKeccak256Hasher(hasher)
   159  		var counter = unsafeRandom.Uint32()
   160  		for pb.Next() {
   161  			tpl.HashingBlob(hasher, preAllocatedBuffer, counter, counter, types.ZeroHash)
   162  			counter++
   163  		}
   164  	})
   165  	b.ReportAllocs()
   166  }
   167  
   168  func BenchmarkTemplate_TemplateId(b *testing.B) {
   169  	tpl, err := TemplateFromPoolBlock(preLoadedPoolBlock)
   170  	if err != nil {
   171  		b.Fatal(err)
   172  	}
   173  
   174  	b.ResetTimer()
   175  
   176  	b.RunParallel(func(pb *testing.PB) {
   177  		preAllocatedBuffer := make([]byte, 0, len(tpl.Buffer))
   178  		hasher := crypto.GetKeccak256Hasher()
   179  		defer crypto.PutKeccak256Hasher(hasher)
   180  		var counter = unsafeRandom.Uint32()
   181  		var templateId types.Hash
   182  		for pb.Next() {
   183  			tpl.TemplateId(hasher, preAllocatedBuffer, sidechain.ConsensusDefault, counter, counter+1, &templateId)
   184  			counter++
   185  		}
   186  	})
   187  	b.ReportAllocs()
   188  }