whisper: switching to v5 + minor refactoring (#14387)
This commit is contained in:
		| @@ -52,7 +52,7 @@ import ( | |||||||
| 	"github.com/ethereum/go-ethereum/p2p/nat" | 	"github.com/ethereum/go-ethereum/p2p/nat" | ||||||
| 	"github.com/ethereum/go-ethereum/p2p/netutil" | 	"github.com/ethereum/go-ethereum/p2p/netutil" | ||||||
| 	"github.com/ethereum/go-ethereum/params" | 	"github.com/ethereum/go-ethereum/params" | ||||||
| 	whisper "github.com/ethereum/go-ethereum/whisper/whisperv2" | 	whisper "github.com/ethereum/go-ethereum/whisper/whisperv5" | ||||||
| 	"gopkg.in/urfave/cli.v1" | 	"gopkg.in/urfave/cli.v1" | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -183,7 +183,7 @@ func initialize() { | |||||||
|  |  | ||||||
| 	if *testMode { | 	if *testMode { | ||||||
| 		symPass = "wwww" // ascii code: 0x77777777 | 		symPass = "wwww" // ascii code: 0x77777777 | ||||||
| 		msPassword = "mail server test password" | 		msPassword = "wwww" | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if *bootstrapMode { | 	if *bootstrapMode { | ||||||
| @@ -330,7 +330,7 @@ func configureNode() { | |||||||
|  |  | ||||||
| 	if !*asymmetricMode && !*forwarderMode { | 	if !*asymmetricMode && !*forwarderMode { | ||||||
| 		if len(symPass) == 0 { | 		if len(symPass) == 0 { | ||||||
| 			symPass, err = console.Stdin.PromptPassword("Please enter the password: ") | 			symPass, err = console.Stdin.PromptPassword("Please enter the password for symmetric encryption: ") | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				utils.Fatalf("Failed to read passphrase: %v", err) | 				utils.Fatalf("Failed to read passphrase: %v", err) | ||||||
| 			} | 			} | ||||||
| @@ -347,6 +347,8 @@ func configureNode() { | |||||||
| 		if len(*argTopic) == 0 { | 		if len(*argTopic) == 0 { | ||||||
| 			generateTopic([]byte(symPass)) | 			generateTopic([]byte(symPass)) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		fmt.Printf("Filter is configured for the topic: %x \n", topic) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if *mailServerMode { | 	if *mailServerMode { | ||||||
| @@ -365,7 +367,6 @@ func configureNode() { | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		utils.Fatalf("Failed to install filter: %s", err) | 		utils.Fatalf("Failed to install filter: %s", err) | ||||||
| 	} | 	} | ||||||
| 	fmt.Printf("Filter is configured for the topic: %x \n", topic) |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func generateTopic(password []byte) { | func generateTopic(password []byte) { | ||||||
|   | |||||||
| @@ -525,7 +525,105 @@ web3._extend({ | |||||||
| const Shh_JS = ` | const Shh_JS = ` | ||||||
| web3._extend({ | web3._extend({ | ||||||
| 	property: 'shh', | 	property: 'shh', | ||||||
| 	methods: [], | 	methods: [ | ||||||
|  | 		new web3._extend.Method({ | ||||||
|  | 			name: 'info', | ||||||
|  | 			call: 'shh_info' | ||||||
|  | 		}), | ||||||
|  | 		new web3._extend.Method({ | ||||||
|  | 			name: 'setMaxMessageLength', | ||||||
|  | 			call: 'shh_setMaxMessageLength', | ||||||
|  | 			params: 1 | ||||||
|  | 		}), | ||||||
|  | 		new web3._extend.Method({ | ||||||
|  | 			name: 'setMinimumPoW', | ||||||
|  | 			call: 'shh_setMinimumPoW', | ||||||
|  | 			params: 1 | ||||||
|  | 		}), | ||||||
|  | 		new web3._extend.Method({ | ||||||
|  | 			name: 'allowP2PMessagesFromPeer', | ||||||
|  | 			call: 'shh_allowP2PMessagesFromPeer', | ||||||
|  | 			params: 1 | ||||||
|  | 		}), | ||||||
|  | 		new web3._extend.Method({ | ||||||
|  | 			name: 'hasKeyPair', | ||||||
|  | 			call: 'shh_hasKeyPair', | ||||||
|  | 			params: 1 | ||||||
|  | 		}), | ||||||
|  | 		new web3._extend.Method({ | ||||||
|  | 			name: 'deleteKeyPair', | ||||||
|  | 			call: 'shh_deleteKeyPair', | ||||||
|  | 			params: 1 | ||||||
|  | 		}), | ||||||
|  | 		new web3._extend.Method({ | ||||||
|  | 			name: 'newKeyPair', | ||||||
|  | 			call: 'shh_newKeyPair' | ||||||
|  | 		}), | ||||||
|  | 		new web3._extend.Method({ | ||||||
|  | 			name: 'getPublicKey', | ||||||
|  | 			call: 'shh_getPublicKey', | ||||||
|  | 			params: 1 | ||||||
|  | 		}), | ||||||
|  | 		new web3._extend.Method({ | ||||||
|  | 			name: 'getPrivateKey', | ||||||
|  | 			call: 'shh_getPrivateKey', | ||||||
|  | 			params: 1 | ||||||
|  | 		}), | ||||||
|  | 		new web3._extend.Method({ | ||||||
|  | 			name: 'generateSymmetricKey', | ||||||
|  | 			call: 'shh_generateSymmetricKey', | ||||||
|  | 		}), | ||||||
|  | 		new web3._extend.Method({ | ||||||
|  | 			name: 'addSymmetricKeyDirect', | ||||||
|  | 			call: 'shh_addSymmetricKeyDirect', | ||||||
|  | 			params: 1 | ||||||
|  | 		}), | ||||||
|  | 		new web3._extend.Method({ | ||||||
|  | 			name: 'addSymmetricKeyFromPassword', | ||||||
|  | 			call: 'shh_addSymmetricKeyFromPassword', | ||||||
|  | 			params: 1 | ||||||
|  | 		}), | ||||||
|  | 		new web3._extend.Method({ | ||||||
|  | 			name: 'hasSymmetricKey', | ||||||
|  | 			call: 'shh_hasSymmetricKey', | ||||||
|  | 			params: 1 | ||||||
|  | 		}), | ||||||
|  | 		new web3._extend.Method({ | ||||||
|  | 			name: 'getSymmetricKey', | ||||||
|  | 			call: 'shh_getSymmetricKey', | ||||||
|  | 			params: 1 | ||||||
|  | 		}), | ||||||
|  | 		new web3._extend.Method({ | ||||||
|  | 			name: 'deleteSymmetricKey', | ||||||
|  | 			call: 'shh_deleteSymmetricKey', | ||||||
|  | 			params: 1 | ||||||
|  | 		}), | ||||||
|  | 		new web3._extend.Method({ | ||||||
|  | 			name: 'subscribe', | ||||||
|  | 			call: 'shh_subscribe', | ||||||
|  | 			params: 1 | ||||||
|  | 		}), | ||||||
|  | 		new web3._extend.Method({ | ||||||
|  | 			name: 'unsubscribe', | ||||||
|  | 			call: 'shh_unsubscribe', | ||||||
|  | 			params: 1 | ||||||
|  | 		}), | ||||||
|  | 		new web3._extend.Method({ | ||||||
|  | 			name: 'getNewSubscriptionMessages', | ||||||
|  | 			call: 'shh_getNewSubscriptionMessages', | ||||||
|  | 			params: 1 | ||||||
|  | 		}), | ||||||
|  | 		new web3._extend.Method({ | ||||||
|  | 			name: 'getFloatingMessages', | ||||||
|  | 			call: 'shh_getFloatingMessages', | ||||||
|  | 			params: 1 | ||||||
|  | 		}), | ||||||
|  | 		new web3._extend.Method({ | ||||||
|  | 			name: 'post', | ||||||
|  | 			call: 'shh_post', | ||||||
|  | 			params: 1 | ||||||
|  | 		}) | ||||||
|  | 	], | ||||||
| 	properties: | 	properties: | ||||||
| 	[ | 	[ | ||||||
| 		new web3._extend.Property({ | 		new web3._extend.Property({ | ||||||
| @@ -536,6 +634,7 @@ web3._extend({ | |||||||
| 	] | 	] | ||||||
| }); | }); | ||||||
| ` | ` | ||||||
|  |  | ||||||
| const SWARMFS_JS = ` | const SWARMFS_JS = ` | ||||||
| web3._extend({ | web3._extend({ | ||||||
| 	property: 'swarmfs', | 	property: 'swarmfs', | ||||||
|   | |||||||
| @@ -34,7 +34,7 @@ import ( | |||||||
| 	"github.com/ethereum/go-ethereum/p2p" | 	"github.com/ethereum/go-ethereum/p2p" | ||||||
| 	"github.com/ethereum/go-ethereum/p2p/nat" | 	"github.com/ethereum/go-ethereum/p2p/nat" | ||||||
| 	"github.com/ethereum/go-ethereum/params" | 	"github.com/ethereum/go-ethereum/params" | ||||||
| 	whisper "github.com/ethereum/go-ethereum/whisper/whisperv2" | 	whisper "github.com/ethereum/go-ethereum/whisper/whisperv5" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // NodeConfig represents the collection of configuration values to fine tune the Geth | // NodeConfig represents the collection of configuration values to fine tune the Geth | ||||||
|   | |||||||
| @@ -231,14 +231,14 @@ func (api *PublicWhisperAPI) Subscribe(args WhisperFilterArgs) (string, error) { | |||||||
| 		return "", errors.New("subscribe: " + err.Error()) | 		return "", errors.New("subscribe: " + err.Error()) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(args.SignedWith) > 0 { | 	if len(args.Sig) > 0 { | ||||||
| 		sb := common.FromHex(args.SignedWith) | 		sb := common.FromHex(args.Sig) | ||||||
| 		if sb == nil { | 		if sb == nil { | ||||||
| 			return "", errors.New("subscribe: SignedWith parameter is invalid") | 			return "", errors.New("subscribe: sig parameter is invalid") | ||||||
| 		} | 		} | ||||||
| 		filter.Src = crypto.ToECDSAPub(sb) | 		filter.Src = crypto.ToECDSAPub(sb) | ||||||
| 		if !ValidatePublicKey(filter.Src) { | 		if !ValidatePublicKey(filter.Src) { | ||||||
| 			return "", errors.New("subscribe: invalid 'SignedWith' field") | 			return "", errors.New("subscribe: invalid 'sig' field") | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -319,8 +319,8 @@ func (api *PublicWhisperAPI) Post(args PostArgs) error { | |||||||
| 		return errors.New("post: key is missing") | 		return errors.New("post: key is missing") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(args.SignWith) > 0 { | 	if len(args.Sig) > 0 { | ||||||
| 		params.Src, err = api.whisper.GetPrivateKey(args.SignWith) | 		params.Src, err = api.whisper.GetPrivateKey(args.Sig) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| @@ -391,7 +391,7 @@ func (api *PublicWhisperAPI) Post(args PostArgs) error { | |||||||
| type PostArgs struct { | type PostArgs struct { | ||||||
| 	Type       string        `json:"type"`       // "sym"/"asym" (symmetric or asymmetric) | 	Type       string        `json:"type"`       // "sym"/"asym" (symmetric or asymmetric) | ||||||
| 	TTL        uint32        `json:"ttl"`        // time-to-live in seconds | 	TTL        uint32        `json:"ttl"`        // time-to-live in seconds | ||||||
| 	SignWith   string        `json:"signWith"`   // id of the signing key | 	Sig        string        `json:"sig"`        // id of the signing key | ||||||
| 	Key        string        `json:"key"`        // key id (in case of sym) or public key (in case of asym) | 	Key        string        `json:"key"`        // key id (in case of sym) or public key (in case of asym) | ||||||
| 	Topic      hexutil.Bytes `json:"topic"`      // topic (4 bytes) | 	Topic      hexutil.Bytes `json:"topic"`      // topic (4 bytes) | ||||||
| 	Padding    hexutil.Bytes `json:"padding"`    // optional padding bytes | 	Padding    hexutil.Bytes `json:"padding"`    // optional padding bytes | ||||||
| @@ -404,7 +404,7 @@ type PostArgs struct { | |||||||
| type WhisperFilterArgs struct { | type WhisperFilterArgs struct { | ||||||
| 	Symmetric bool     // encryption type | 	Symmetric bool     // encryption type | ||||||
| 	Key       string   // id of the key to be used for decryption | 	Key       string   // id of the key to be used for decryption | ||||||
| 	SignedWith string   // public key of the sender to be verified | 	Sig       string   // public key of the sender to be verified | ||||||
| 	MinPoW    float64  // minimal PoW requirement | 	MinPoW    float64  // minimal PoW requirement | ||||||
| 	Topics    [][]byte // list of topics (up to 4 bytes each) to match | 	Topics    [][]byte // list of topics (up to 4 bytes each) to match | ||||||
| 	AllowP2P  bool     // indicates wheather direct p2p messages are allowed for this filter | 	AllowP2P  bool     // indicates wheather direct p2p messages are allowed for this filter | ||||||
| @@ -417,7 +417,7 @@ func (args *WhisperFilterArgs) UnmarshalJSON(b []byte) (err error) { | |||||||
| 	var obj struct { | 	var obj struct { | ||||||
| 		Type     string        `json:"type"` | 		Type     string        `json:"type"` | ||||||
| 		Key      string        `json:"key"` | 		Key      string        `json:"key"` | ||||||
| 		SignedWith string        `json:"signedWith"` | 		Sig      string        `json:"sig"` | ||||||
| 		MinPoW   float64       `json:"minPoW"` | 		MinPoW   float64       `json:"minPoW"` | ||||||
| 		Topics   []interface{} `json:"topics"` | 		Topics   []interface{} `json:"topics"` | ||||||
| 		AllowP2P bool          `json:"allowP2P"` | 		AllowP2P bool          `json:"allowP2P"` | ||||||
| @@ -436,7 +436,7 @@ func (args *WhisperFilterArgs) UnmarshalJSON(b []byte) (err error) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	args.Key = obj.Key | 	args.Key = obj.Key | ||||||
| 	args.SignedWith = obj.SignedWith | 	args.Sig = obj.Sig | ||||||
| 	args.MinPoW = obj.MinPoW | 	args.MinPoW = obj.MinPoW | ||||||
| 	args.AllowP2P = obj.AllowP2P | 	args.AllowP2P = obj.AllowP2P | ||||||
|  |  | ||||||
| @@ -472,7 +472,7 @@ type WhisperMessage struct { | |||||||
| 	Topic     string  `json:"topic"` | 	Topic     string  `json:"topic"` | ||||||
| 	Payload   string  `json:"payload"` | 	Payload   string  `json:"payload"` | ||||||
| 	Padding   string  `json:"padding"` | 	Padding   string  `json:"padding"` | ||||||
| 	Src       string  `json:"signedWith"` | 	Src       string  `json:"sig"` | ||||||
| 	Dst       string  `json:"recipientPublicKey"` | 	Dst       string  `json:"recipientPublicKey"` | ||||||
| 	Timestamp uint32  `json:"timestamp"` | 	Timestamp uint32  `json:"timestamp"` | ||||||
| 	TTL       uint32  `json:"ttl"` | 	TTL       uint32  `json:"ttl"` | ||||||
|   | |||||||
| @@ -173,7 +173,7 @@ func TestUnmarshalFilterArgs(t *testing.T) { | |||||||
| 	s := []byte(`{ | 	s := []byte(`{ | ||||||
| 	"type":"sym", | 	"type":"sym", | ||||||
| 	"key":"0x70c87d191324e6712a591f304b4eedef6ad9bb9d", | 	"key":"0x70c87d191324e6712a591f304b4eedef6ad9bb9d", | ||||||
| 	"signedWith":"0x9b2055d370f73ec7d8a03e965129118dc8f5bf83", | 	"sig":"0x9b2055d370f73ec7d8a03e965129118dc8f5bf83", | ||||||
| 	"minPoW":2.34, | 	"minPoW":2.34, | ||||||
| 	"topics":["0x00000000", "0x007f80ff", "0xff807f00", "0xf26e7779"], | 	"topics":["0x00000000", "0x007f80ff", "0xff807f00", "0xf26e7779"], | ||||||
| 	"allowP2P":true | 	"allowP2P":true | ||||||
| @@ -191,8 +191,8 @@ func TestUnmarshalFilterArgs(t *testing.T) { | |||||||
| 	if f.Key != "0x70c87d191324e6712a591f304b4eedef6ad9bb9d" { | 	if f.Key != "0x70c87d191324e6712a591f304b4eedef6ad9bb9d" { | ||||||
| 		t.Fatalf("wrong key: %s.", f.Key) | 		t.Fatalf("wrong key: %s.", f.Key) | ||||||
| 	} | 	} | ||||||
| 	if f.SignedWith != "0x9b2055d370f73ec7d8a03e965129118dc8f5bf83" { | 	if f.Sig != "0x9b2055d370f73ec7d8a03e965129118dc8f5bf83" { | ||||||
| 		t.Fatalf("wrong SignedWith: %s.", f.SignedWith) | 		t.Fatalf("wrong sig: %s.", f.Sig) | ||||||
| 	} | 	} | ||||||
| 	if f.MinPoW != 2.34 { | 	if f.MinPoW != 2.34 { | ||||||
| 		t.Fatalf("wrong MinPoW: %f.", f.MinPoW) | 		t.Fatalf("wrong MinPoW: %f.", f.MinPoW) | ||||||
| @@ -229,7 +229,7 @@ func TestUnmarshalPostArgs(t *testing.T) { | |||||||
| 	s := []byte(`{ | 	s := []byte(`{ | ||||||
| 	"type":"sym", | 	"type":"sym", | ||||||
| 	"ttl":12345, | 	"ttl":12345, | ||||||
| 	"signWith":"0x70c87d191324e6712a591f304b4eedef6ad9bb9d", | 	"sig":"0x70c87d191324e6712a591f304b4eedef6ad9bb9d", | ||||||
| 	"key":"0x9b2055d370f73ec7d8a03e965129118dc8f5bf83", | 	"key":"0x9b2055d370f73ec7d8a03e965129118dc8f5bf83", | ||||||
| 	"topic":"0xf26e7779", | 	"topic":"0xf26e7779", | ||||||
| 	"padding":"0x74686973206973206D79207465737420737472696E67", | 	"padding":"0x74686973206973206D79207465737420737472696E67", | ||||||
| @@ -251,8 +251,8 @@ func TestUnmarshalPostArgs(t *testing.T) { | |||||||
| 	if a.TTL != 12345 { | 	if a.TTL != 12345 { | ||||||
| 		t.Fatalf("wrong ttl: %d.", a.TTL) | 		t.Fatalf("wrong ttl: %d.", a.TTL) | ||||||
| 	} | 	} | ||||||
| 	if a.SignWith != "0x70c87d191324e6712a591f304b4eedef6ad9bb9d" { | 	if a.Sig != "0x70c87d191324e6712a591f304b4eedef6ad9bb9d" { | ||||||
| 		t.Fatalf("wrong From: %s.", a.SignWith) | 		t.Fatalf("wrong From: %s.", a.Sig) | ||||||
| 	} | 	} | ||||||
| 	if a.Key != "0x9b2055d370f73ec7d8a03e965129118dc8f5bf83" { | 	if a.Key != "0x9b2055d370f73ec7d8a03e965129118dc8f5bf83" { | ||||||
| 		t.Fatalf("wrong Key: %s.", a.Key) | 		t.Fatalf("wrong Key: %s.", a.Key) | ||||||
| @@ -347,7 +347,7 @@ func TestIntegrationAsym(t *testing.T) { | |||||||
| 	var f WhisperFilterArgs | 	var f WhisperFilterArgs | ||||||
| 	f.Symmetric = false | 	f.Symmetric = false | ||||||
| 	f.Key = key | 	f.Key = key | ||||||
| 	f.SignedWith = sigPubKey.String() | 	f.Sig = sigPubKey.String() | ||||||
| 	f.Topics = make([][]byte, 2) | 	f.Topics = make([][]byte, 2) | ||||||
| 	f.Topics[0] = topics[0][:] | 	f.Topics[0] = topics[0][:] | ||||||
| 	f.Topics[1] = topics[1][:] | 	f.Topics[1] = topics[1][:] | ||||||
| @@ -362,7 +362,7 @@ func TestIntegrationAsym(t *testing.T) { | |||||||
| 	var p PostArgs | 	var p PostArgs | ||||||
| 	p.Type = "asym" | 	p.Type = "asym" | ||||||
| 	p.TTL = 2 | 	p.TTL = 2 | ||||||
| 	p.SignWith = sig | 	p.Sig = sig | ||||||
| 	p.Key = dstPubKey.String() | 	p.Key = dstPubKey.String() | ||||||
| 	p.Padding = []byte("test string") | 	p.Padding = []byte("test string") | ||||||
| 	p.Payload = []byte("extended test string") | 	p.Payload = []byte("extended test string") | ||||||
| @@ -449,7 +449,7 @@ func TestIntegrationSym(t *testing.T) { | |||||||
| 	f.Topics[0] = topics[0][:] | 	f.Topics[0] = topics[0][:] | ||||||
| 	f.Topics[1] = topics[1][:] | 	f.Topics[1] = topics[1][:] | ||||||
| 	f.MinPoW = DefaultMinimumPoW / 2 | 	f.MinPoW = DefaultMinimumPoW / 2 | ||||||
| 	f.SignedWith = sigPubKey.String() | 	f.Sig = sigPubKey.String() | ||||||
| 	f.AllowP2P = false | 	f.AllowP2P = false | ||||||
|  |  | ||||||
| 	id, err := api.Subscribe(f) | 	id, err := api.Subscribe(f) | ||||||
| @@ -461,7 +461,7 @@ func TestIntegrationSym(t *testing.T) { | |||||||
| 	p.Type = "sym" | 	p.Type = "sym" | ||||||
| 	p.TTL = 1 | 	p.TTL = 1 | ||||||
| 	p.Key = symKeyID | 	p.Key = symKeyID | ||||||
| 	p.SignWith = sig | 	p.Sig = sig | ||||||
| 	p.Padding = []byte("test string") | 	p.Padding = []byte("test string") | ||||||
| 	p.Payload = []byte("extended test string") | 	p.Payload = []byte("extended test string") | ||||||
| 	p.PowTarget = DefaultMinimumPoW | 	p.PowTarget = DefaultMinimumPoW | ||||||
| @@ -547,7 +547,7 @@ func TestIntegrationSymWithFilter(t *testing.T) { | |||||||
| 	f.Topics[0] = topics[0][:] | 	f.Topics[0] = topics[0][:] | ||||||
| 	f.Topics[1] = topics[1][:] | 	f.Topics[1] = topics[1][:] | ||||||
| 	f.MinPoW = DefaultMinimumPoW / 2 | 	f.MinPoW = DefaultMinimumPoW / 2 | ||||||
| 	f.SignedWith = sigPubKey.String() | 	f.Sig = sigPubKey.String() | ||||||
| 	f.AllowP2P = false | 	f.AllowP2P = false | ||||||
|  |  | ||||||
| 	id, err := api.Subscribe(f) | 	id, err := api.Subscribe(f) | ||||||
| @@ -559,7 +559,7 @@ func TestIntegrationSymWithFilter(t *testing.T) { | |||||||
| 	p.Type = "sym" | 	p.Type = "sym" | ||||||
| 	p.TTL = 1 | 	p.TTL = 1 | ||||||
| 	p.Key = symKeyID | 	p.Key = symKeyID | ||||||
| 	p.SignWith = sigKeyID | 	p.Sig = sigKeyID | ||||||
| 	p.Padding = []byte("test string") | 	p.Padding = []byte("test string") | ||||||
| 	p.Payload = []byte("extended test string") | 	p.Payload = []byte("extended test string") | ||||||
| 	p.PowTarget = DefaultMinimumPoW | 	p.PowTarget = DefaultMinimumPoW | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user