(Updated on 2016-10-21 v3)


What do you need to develop a GPU miner for PascalCoin


"If you like it, make a donation to PascalCoin project: 
BTC 16K3HCZRhFUtM8GdWRcfKeaa6KsuyxZaYk 
... Thanks! The PascalCoin dev."


**************************
First:
**************************
- Download and install a PascalCoin node Build 1.0.7   (Released on 2016-10-10, perhaps there are some newer versions when you read this)
- Execute it and Wait until ready (downloaded blockhain)
- Configure it (options menu) with you preferred ports, and include a Miner name
- Open JSON-RPC Server miner port (By default 4009)

**************************
Second:  Test JSON-RPC server
**************************
- Open a telnet terminal (for example, Putty)
- Connect with your Application with telnet mode (By default, localhost and port 4009)
- You will receive a "miner-notify" message written in JSON-RPC (version 1.0)

Example of JSON-RPC received: (Note: JSON-RPC has no whitespaces)
{"method":"miner-notify","params":[{"block":20110,"version":1,"part1":"8F4E0000CA022000DC01BE5ACD50092CA653D0763CCCE7A9E408908B2F7D177C080C78186D3558FC2000A48CEC0E7031689D40AF8C7C73330E06E27788F0339729F53A3AF4ED47C2E45040420F000000000001000000B74D7926","payload_start":"546573744A534F4E32","part3":"0D1F997AB584AF8A86476135A9F091073A3FE28A6A07D4112BF8595144F0E666E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B85500000000","target":645483959,"target_pow":"00000000030D6490000000000000000000000000000000000000000000000000","timestamp":1476103385}],"id":null}

- while connected, everytime a change in PoW calculation is produced, you will receive a "miner-notify" message

**************************
Third:  Try sending "miner-submit" messages to the server
**************************

"miner-submit" JSON-RPC messages are to notify server a valid PoW found... and integrate to the block.

- In Telnet, try to send this messages:

EXAMPLE 1: Send first "miner-submit" message (copy/paste)
SEND --> {"method":"miner-submit","params":[{"payload":"5744","timestamp":1234567890,"nonce":1234}]}

And you will receive a message similar to this:
RECEIVE <--- {"result":null,"error":"Invalid payload (WD). Need start with: TestJSON","id":null}

Explanation: You received a JSON-RPC error. Error is explained in plain text. In above example, you've sent a "miner-submit" message with a not valid payload. Note that payload must be equal or greater than param "payload_start" provided on a "miner-notify" message.

EXAMPLE 2:
Now we will correct example 1, sending this message: (copy/paste)
SEND --> {"method":"miner-submit","params":[{"payload":"546573744A534F4E32","timestamp":1234567890,"nonce":1234}]}

You will receive a message similar tho this:
RECEIVE <-- {"result":null,"error":"Error: Invalid timestamp (New timestamp:1234567890 last timestamp (20110):1476103364)","id":null}
Explanation: timestamp provided is invalid, because its lower than "1476103364" (JSON-RPC server time)
So: Remember that server and clients must be time syncrhonized!

EXAMPLE 3:
Now we will correct example 1 and 2, sending this message: (copy/paste)
SEND --> {"method":"miner-submit","params":[{"payload":"546573744A534F4E32","timestamp":1476106610,"nonce":1234}]}
RECEIVE <-- {"result":null,"error":"Error: Invalid timestamp (Future time 1476106610-1476105971=639 > 180)","id":null}
This error is similar to Example 2, but in this case we have sent a invalid timestamp, greater than 180 seconds than server time

EXAMPLE 4:
Sending a valid timestamp sending this message: (copy/paste)
SEND --> {"method":"miner-submit","params":[{"payload":"546573744A534F4E32","timestamp":1476106050,"nonce":1234}]}
RECEIVE <-- {"result":null,"error":"Error: Proof of work is higher than target","id":null}
This is a valid PoW. So... your payload is good, your timestamp is good, but your nonce is not good

EXAMPLE 5:
Sending an invalid JSON-RPC... you will not receive anything
SEND --> {"no_method":"bla","params":[{"payload":"546573744A534F4E32","timestamp":1476106050,"nonce":1234}]}
RECEIVE <-- (... Anything ...)
You will not receive anything because this JSON is not a JSON-RPC (standard 1.0). It must include "method" param!
Server will log this event, and delete its buffer, but you will still be connected... Try again with a "method" param

EXAMPLE 6:
Sending a valid JSON-RPC... but invalid method:
SEND --> {"method":"INCORRECTa","params":[{"payload":"546573744A534F4E32","timestamp":1476106050,"nonce":1234}]}
RECEIVE <-- (... Anything ...)
You will not receive anything because this is a JSON-RPC with a "method" but WITHOUT "id"

EXAMPLE 7:
Sending a valid JSON-RPC... but invalid method and including "id"
SEND --> {"method":"NONE","params":[{"payload":"546573744A534F4E32","timestamp":1476106050,"nonce":1234}],"id":999}
RECEIVE <-- {"result":null,"error":"method not found: NONE","id":999}
This indicates that method "NONE" is not a valid method


**************************
Third:  How to generate a valid nonce
**************************

Take a look at "miner-notify" params (message received from server)

{"method":"miner-notify","params":[{"block":20110,"version":1,"part1":"8F4E0000CA022000DC01BE5ACD50092CA653D0763CCCE7A9E408908B2F7D177C080C78186D3558FC2000A48CEC0E7031689D40AF8C7C73330E06E27788F0339729F53A3AF4ED47C2E45040420F000000000001000000B74D7926","payload_start":"546573744A534F4E32","part3":"0D1F997AB584AF8A86476135A9F091073A3FE28A6A07D4112BF8595144F0E666E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B85500000000","target":645483959,"target_pow":"00000000030D6490000000000000000000000000000000000000000000000000","timestamp":1476103385}],"id":null}

You need this params:
- "block": This is the next block number to generate... you will not use it
- "version": This is the PascalCoin core version. If in future it changes... you would need to develop a new GPU miner... check that allways is 1
- "part1" : This is a Hexa string, you must convert it to RAW and store to a buffer called "buffer_part1"
- "payload_start": This is the miner name included in the payload when mining. You can ADD characters (only from ASCII from 32 to 254). Store it in a buffer - "buffer_payload"
- "part3" : equal to part1
- "timestamp": This is the server timestamp. You must use allways a timestamp equal or higher than the server... so... be synchronized
- "target_pow": This is a hexa string with the PoW target you must to generate
- "target": This is the target in original format. You will not use it.


Then, your GPU miner, must do this:

Create a buffer with:
"buffer_part1" + "buffer_payload" + "buffer_part3" + UNIX_TIMESTAMP + NONCE
(UNIX_TIMESTAMP and NONCE are 32bits unsigned integers, saved in LITTLE ENDIAN)

Make a Double SHA256 and save it to "buffer_pow"

Check if "buffer_pow" is lower or equal to "target_pow" provided by server in "miner-notify"

If NO, then create a new buffer changing NONCE or UNIX_TIMESAMP (or also, adding valid ASCII chars to buffer_payload), and check again
If YES: Submit a "miner-submit" like example 4... and check if you win

IMPORTANT: In Build 1.0.9 only accepts Signed 32 bits value for "timestamp" and "nonce", so you must convert a Unsigned Integer (Uint32) to a Signed integer (Int32) and send it with negative symbol if negative (Example: "nonce":"-123456" for negative Int32)


REMEMBER: buffer_payload only accepts ASCII chars from 32 to 254, must start exactly than "payload_start" param, and can be length max of 255 bytes.

NOTE: PascalCoin.exe will provide the miner name at "payload_start" plus a number indicating which client is mining. If there are 2 clients, and Miner name is "MyMiner" first will have "MyMiner1" and second "MyMiner2".


THAT'S ALL!!!

If you like it, make a donation to PascalCoin project: BTC 16K3HCZRhFUtM8GdWRcfKeaa6KsuyxZaYk



Thanks!!!
