Go-ethereum: Clique: blocks are always mined by 0x0

Created on 11 Dec 2017  Â·  14Comments  Â·  Source: ethereum/go-ethereum

System information

Geth version: 1.7.3-stable
OS & Version: Linux

Expected behaviour

Block should be mined by signer

Actual behaviour

Block is mined by 0x0

Steps to reproduce the behaviour

  • geth account new
  • make a genesis with puppeth (PoA, previously generated account as signer)
  • geth init genesis.json
  • start geth
  • geth attach
  • personal.unlockAccount(eth.coinbase, 'pwd', 0)
  • miner.setEtherbase(eth.coinbase)
  • miner.start()

Notes

Above I described how I setup the testnet, there should be more signers but it's more clear with one.
The command clique.getSnapshot() shows the block is correctly signed, but the miner is set to 0x0, ignoring miner.setEtherbase().
Am I missing something?

All 14 comments

same behavior for my clique dev net with 2 nodes. The blockchain is up and running but miner is always: 'miner': '0x0000000000000000000000000000000000000000'

‘miner’ field is used to indicate the candidate miner。or you can get signers by blockhash:

clique.getSignersAtHash('0x86837f148f096f1ce53463ecb4acf3d99bae0b2f0297dacbb6d33fcfdb7c04d9')
["0x5252781539b365e08015fa7ed77af5a36097f39d", "0x63f1de588c7ce855b66cf24b595a8991f921130d", "0xa1629411f4e8608a7bb88e8a7700f11c59175e72"]

or recover block miner from block.extraData.

I'm having the same issue. How is that https://www.rinkeby.io/#explorer gets the miner? @karalabe can you give us a clue on this?

Has someone solved this?

The beneficiary field of the block header in the Clique protocol is used for a different purpose than in ethash.

In the PoW consensus engine, it's the miner. However in PoA, the signer is determined from a digital signature, which wouldn't fit into the beneficiary field (20 bytes vs. 65 byte signature), so in Clique, the beneficiary is used for voting on adding/removing signers. The signature for the block is contained within the block header's extradata field, and the address can be recovered from the signature.

https://github.com/ethereum/go-ethereum/issues/15651#issuecomment-369812845 already contains the answer on how you can get the signer address from a Clique block.

For more infos, please see the Clique consensus engine EIP https://github.com/ethereum/EIPs/issues/225.

@karalabe thanks!

EDIT:

In Go:

blk, err := conn.BlockByNumber(context.Background(), big.NewInt(2078))
pubkey, err := crypto.SigToPub(sigHash(blk.Header()).Bytes(), blk.Extra()[32:])
// log.Println(pubkey)
log.Println(err)
log.Println(crypto.PubkeyToAddress(*pubkey).Hex())

conn is ethclient.Client (returned by ethclient.Dial)

@facundomedica where does sigHash in the above snippet of yours come from?

@Swader as you can see I did comment that a long time ago but I was able to find that snippet on my machine, here you have sigHash:

func sigHash(header *types.Header) (hash common.Hash) {
    hasher := sha3.NewKeccak256()

    rlp.Encode(hasher, []interface{}{
        header.ParentHash,
        header.UncleHash,
        header.Coinbase,
        header.Root,
        header.TxHash,
        header.ReceiptHash,
        header.Bloom,
        header.Difficulty,
        header.Number,
        header.GasLimit,
        header.GasUsed,
        header.Time,
        header.Extra[:len(header.Extra)-65], // Yes, this will panic if extra is too short
        header.MixDigest,
        header.Nonce,
    })
    hasher.Sum(hash[:0])
    return hash
}

I'm afraid I cannot answer any questions about this as I don't even remember what this was for. Hope it helped!

@facundomedica thank you, perfect! That solved it!

@shiqinfeng1 : How can I use web3, or web3_extended to call clique.getSignersAtHash() function to get miner address? thanks

‘miner’ field is used to indicate the candidate miner。or you can get signers by blockhash:

clique.getSignersAtHash('0x86837f148f096f1ce53463ecb4acf3d99bae0b2f0297dacbb6d33fcfdb7c04d9')
["0x5252781539b365e08015fa7ed77af5a36097f39d", "0x63f1de588c7ce855b66cf24b595a8991f921130d", "0xa1629411f4e8608a7bb88e8a7700f11c59175e72"]

or recover block miner from block.extraData.

Geth exposes the clique methods on the RPC. From this point onward it's up to you to call them with whatever library. The RPC method is clique_getSignersAtHash, I assume web3 or any other library should be able to make a low level query.

When I send json RPC call using postman, it really works.
But I call the mothed via web3, it says TypeError: web3.clique_getSignersAtHash is not a function. What's the correct way to call the method using web3 library?
Thanks.

My call code lines are as below:

const Web3 = require('web3');
const web3 = new Web3(new Web3.providers.HttpProvider("http://192.168.43.185:8545"));
//blockhash: 0x4122fc7595ded3760f5cd988927efa75a8df15ca955ebe740ba7ae70d4f160b8
web3.clique_getSignersAtHash('0x4122fc7595ded3760f5cd988927efa75a8df15ca955ebe740ba7ae70d4f160b8'); 

You'll need to find a low level way to directly call a method. If it's not integrated into the JS api, you'll need to pass it by string to something. I'd recommend you open an issue/question on the web3.js repo (https://github.com/ethereum/web3.js/), I'm not familiar with that at all so can't really help beyond the above.

I found a strange problem:
To verify, I set up a private POA chain with 3 nodes, all of them are has a sealer account.
I launch two nodes only, the blocks can be signed by the two nodes correctly.
when I call clique.getSignersAtHash('block hash value') in attached geth console, the result also include the third signer, It's rather strange because the third node is not working.
How can I get correct signer address of each block?
Thanks.
//
I verified you suggestion, sending low level RPC call to node via web3, it works,thanks for you help.
I share the code I use here for reference to who need:
const Web3 = require('web3');

const web3 = new Web3('http://localhost:8545');
var async = require('asyncawait/async');
var await = require('asyncawait/await');
const main = async () => {
    test = await web3.currentProvider.send("clique_getSignersAtHash",['block hash value']);
    console.log(test);
};
main();
Was this page helpful?
0 / 5 - 0 ratings

Related issues

VenusHu picture VenusHu  Â·  3Comments

VoR0220 picture VoR0220  Â·  3Comments

phpsamsb picture phpsamsb  Â·  3Comments

aomiba picture aomiba  Â·  3Comments

AdrianScott picture AdrianScott  Â·  3Comments