@@ -22,6 +22,7 @@ import (
2222 "math/big"
2323 "net/http"
2424 "net/http/httptest"
25+ "strconv"
2526 "testing"
2627 "time"
2728
@@ -74,6 +75,50 @@ func TestRemoteNotify(t *testing.T) {
7475 }
7576}
7677
78+ // Tests whether remote HTTP servers are correctly notified of new work. (Full pending block body / --miner.notify.full)
79+ func TestRemoteNotifyFull (t * testing.T ) {
80+ // Start a simple web server to capture notifications.
81+ sink := make (chan map [string ]interface {})
82+ server := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , req * http.Request ) {
83+ blob , err := ioutil .ReadAll (req .Body )
84+ if err != nil {
85+ t .Errorf ("failed to read miner notification: %v" , err )
86+ }
87+ var work map [string ]interface {}
88+ if err := json .Unmarshal (blob , & work ); err != nil {
89+ t .Errorf ("failed to unmarshal miner notification: %v" , err )
90+ }
91+ sink <- work
92+ }))
93+ defer server .Close ()
94+
95+ // Create the custom ethash engine.
96+ config := Config {
97+ PowMode : ModeTest ,
98+ NotifyFull : true ,
99+ Log : testlog .Logger (t , log .LvlWarn ),
100+ }
101+ ethash := New (config , []string {server .URL }, false )
102+ defer ethash .Close ()
103+
104+ // Stream a work task and ensure the notification bubbles out.
105+ header := & types.Header {Number : big .NewInt (1 ), Difficulty : big .NewInt (100 )}
106+ block := types .NewBlockWithHeader (header )
107+
108+ ethash .Seal (nil , block , nil , nil )
109+ select {
110+ case work := <- sink :
111+ if want := "0x" + strconv .FormatUint (header .Number .Uint64 (), 16 ); work ["number" ] != want {
112+ t .Errorf ("pending block number mismatch: have %v, want %v" , work ["number" ], want )
113+ }
114+ if want := "0x" + header .Difficulty .Text (16 ); work ["difficulty" ] != want {
115+ t .Errorf ("pending block difficulty mismatch: have %s, want %s" , work ["difficulty" ], want )
116+ }
117+ case <- time .After (3 * time .Second ):
118+ t .Fatalf ("notification timed out" )
119+ }
120+ }
121+
77122// Tests that pushing work packages fast to the miner doesn't cause any data race
78123// issues in the notifications.
79124func TestRemoteMultiNotify (t * testing.T ) {
@@ -119,6 +164,55 @@ func TestRemoteMultiNotify(t *testing.T) {
119164 }
120165}
121166
167+ // Tests that pushing work packages fast to the miner doesn't cause any data race
168+ // issues in the notifications. Full pending block body / --miner.notify.full)
169+ func TestRemoteMultiNotifyFull (t * testing.T ) {
170+ // Start a simple web server to capture notifications.
171+ sink := make (chan map [string ]interface {}, 64 )
172+ server := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , req * http.Request ) {
173+ blob , err := ioutil .ReadAll (req .Body )
174+ if err != nil {
175+ t .Errorf ("failed to read miner notification: %v" , err )
176+ }
177+ var work map [string ]interface {}
178+ if err := json .Unmarshal (blob , & work ); err != nil {
179+ t .Errorf ("failed to unmarshal miner notification: %v" , err )
180+ }
181+ sink <- work
182+ }))
183+ defer server .Close ()
184+
185+ // Create the custom ethash engine.
186+ config := Config {
187+ PowMode : ModeTest ,
188+ NotifyFull : true ,
189+ Log : testlog .Logger (t , log .LvlWarn ),
190+ }
191+ ethash := New (config , []string {server .URL }, false )
192+ defer ethash .Close ()
193+
194+ // Provide a results reader.
195+ // Otherwise the unread results will be logged asynchronously
196+ // and this can happen after the test is finished, causing a panic.
197+ results := make (chan * types.Block , cap (sink ))
198+
199+ // Stream a lot of work task and ensure all the notifications bubble out.
200+ for i := 0 ; i < cap (sink ); i ++ {
201+ header := & types.Header {Number : big .NewInt (int64 (i )), Difficulty : big .NewInt (100 )}
202+ block := types .NewBlockWithHeader (header )
203+ ethash .Seal (nil , block , results , nil )
204+ }
205+
206+ for i := 0 ; i < cap (sink ); i ++ {
207+ select {
208+ case <- sink :
209+ <- results
210+ case <- time .After (10 * time .Second ):
211+ t .Fatalf ("notification %d timed out" , i )
212+ }
213+ }
214+ }
215+
122216// Tests whether stale solutions are correctly processed.
123217func TestStaleSubmission (t * testing.T ) {
124218 ethash := NewTester (nil , true )
0 commit comments