Create a Pool miner - PascalCoin/PascalCoin GitHub Wiki

How to create a Pool for PascalCoin

PascalCoin server uses a JSON-RPC specific port for mining, port 4009 (by default) It's a TCP/IP port (no HTTP) with live connections

All communications are using JSON-RPC 2.0 ending each command with a new line command /n

When connected to server, server will send a message like this:

{"id":null,"method":"miner-notify",
 "params":
   [{"block":64151,"version":1,
    "part1":"97FA0000CA022000D8EAD81B96515F5B411F388E55F127FF535A269D5C4B461BAE6650CC6663130520004EADAE2457688AC9701A4D9F8DC192F84BF040ACB72D5D1E63DC97898CF7770040420F00000000000100010068AD8531",
    "payload_start":"545354",
    "part3":"10BE87A02489BB53517150C78213E1A80F7CD7573BE741FDDF5A99A353ECDF4EA2CECFBD4ECDE6B8E70C5B4F013D5C9E75D25112C78B6718D904D5CD54053C0002000000",
    "target":830844264,
    "target_pow":"0000000000005E94A5C000000000000000000000000000000000000000000000",
    "timestamp":1487357643
   }]
}

If you want to create a Pool using Stratum protocol, you must addapt PascalCoin values to Stratum valid values and send them to miners.

Messages from server to client:

Only 1: "miner-notify"

Method "miner-notify"

This is an automated message (server will send "id":null so is not waiting for response) that servers send to miners with information about current mining values

Params

  • "block": This is the next block number to generate
  • "version": This is the PascalCoin current protocol version
  • "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 in UTC. You must use allways a timestamp equal or higher than the server. Past timestamps will be rejected by server! Also future timestamp higher than 180 seconds will be rejected too
  • "target_pow": This is a hexa string with the PoW target you must generate
  • "target": This is the target_pow in original format (compact format). Target is a 32 bits value, first byte indicates how many leading bits ("0") on the left the "target_pow" has. Next 3 bytes indicates next value after first "1" bit

What to do with miner-notify

When your pool server receives a "miner-notify", it must send a new job to miners with new values

Stratum protocol: You must addapt PascalCoin params to stratum params. Miners will need: "part1","payload_start","part3","timestamp" and "target_pow" or "target" (probably you will need to convert "target_pow" or "target" to difficulty)

Messages from client to server:

Method "miner-submit"

This message is provided from pool server/miner to PascalCoin server when a valid nOnce is found

{"method":"miner-submit","params":[{"payload":"545354","timestamp":1487359496,"nonce":1234}]}

Params

  • "payload": Hexa string starting equal to "payload_start" provided by "miner-notify" method. Payload will be a Human readable string, so, only chars from 32 to 254 are allowed. Example: Hexa string 12F3 = Byte(18)+Byte(243) is invalid because 18<32
  • "timestamp": Int32. Legit timestamp. Must be equal or greater than "timestamp" provided by "miner-notify" and will not be higher than current server timestamp + 180. If not valid, will be rejected
  • "nonce": Int32. Note that server expects a SIGNED value. So value -184220411 is valid (0xF5050505) but value 4110746885 not (because is not a signed 32 bits)

What can change miner

  • Miner cad ADD chars to "payload". Each variation will generate different PoW
  • Miner must use a legit timestamp, always >= than server timestamp
  • Miner can use 2^32 variations of nonce

Digest methods

These 2 method2 will return a hash calculated using the RandomHash or RandomHash2 digest algo

  • rh : Will calculate a RandomHash
  • rh2 : Will calculate a RandomHash2

Pool can use this methods to validate a share provided by miners

Example:

Call from miner to server

{"id":123,"method":"rh2","params":["a02f3a4b5c62102e1a9a983f"]}

Response from server to miner

{"id":123,"error":null, 
  "result": {
     "digest":"A02F3A4B5C62102E1A9A983F",
     "hash":"5D825627E1E9865C17050E55B05D7D3A0C36C11D855261A511880C3CBF015AA9",
     "algo":"rh2"
   } 
}

The above response will hash the content of params value and return all info on result

How to generate a valid nonce (by miner)

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

TEST: 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":"545354","timestamp":1487359496,"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