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 }