Skip to content

Instantly share code, notes, and snippets.

@atif-konasl
Last active September 18, 2020 10:53
Show Gist options
  • Save atif-konasl/e799378270daa9996c2dd7850840b33c to your computer and use it in GitHub Desktop.
Save atif-konasl/e799378270daa9996c2dd7850840b33c to your computer and use it in GitHub Desktop.

Aura Consensus Implementation & Integration Investigation

Our goal is to solve the genesis header hash mismatch and ported all the necessary changes from goerli/go-ethereum-aura to our lukso go-ethereum codebase.

What goerli have done to implement aura consensus in geth

1. They finished the flow for embedding aura consensus engine.
2. They introduced a flag --goerli and finished default network setup staff for geth-aura.
3. Created basic building block for aura engine. From my estimation, they have done 40-50% implementation of aura engine.
4. They faced an issue like mismatching header hash of genesis with parity aura genesis header hash.

What we have done so far

1. Ported all necessary and working changes from goerli/go-ethereum-aura codebase.
2. Make it working.
3. Then fixed the genesis header hash mismatch issue.
4. Now geth-aura network can communicate with parity-aura network.

How did we fix the genesis header hash mismatch issue

1. There is a mismatch in geth header struct and parity header struct. 
2. Nonce and mixDigest is absent in parity aura header and seal field is present. In geth there is not seal field in the header struct.
3. We have intorduced seal field in geth header and avoid nonce and mixDisgest when making rlp hash of genesis header. According to this solution, we have achieved to solve the genesis header mismatch problem with parity-arua.
4. Now successfully we have created a newtork with geth-aura and parity-aura nodes.

genesis.json for geth-aura -

		{
		  "config": {
		    "chainId": 6283,
		    "homesteadBlock": 0,
		    "eip150Block": 0,
		    "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
		    "eip155Block": 0,
		    "eip158Block": 0,
		    "aura":{
		      "period"  : 4,
		      "epoch"   : 500,
		      "authorities":[
		        "0x76814b3644f20903b8472434e8c8efb2aa79e546"],
		      "difficulty" : 131072
		    }
		  },
		  "seal": {
		      "step": "0x",
		      "signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
		  },
		  "difficulty": "0x20000",
		  "coinbase": "0x0000000000000000000000000000000000000000",
		  "timestamp": "0x00",
		  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
		  "extraData": "0x",
		  "gasLimit": "0x222222",
		  "alloc": {
		    "0000000000000000000000000000000000000001": { "balance": "0x1" },
		    "0000000000000000000000000000000000000002": { "balance": "0x1" },
		    "0000000000000000000000000000000000000003": { "balance": "0x1" },
		    "0000000000000000000000000000000000000004": { "balance": "0x1" },
		    "0xea294b897567b3a677c499a051e9032d52bd7347": { "balance": "0x21e19e0c9bab2400000"}
		  }
		}

spec.json for parity-aura -

		{
		    "name": "DemoPoA",
		    "engine": {
		        "authorityRound": {
		            "params": {
		                "stepDuration": "5",
		                "validators" : {
		                    "list": [
		                        "0x76814b3644f20903b8472434e8c8efb2aa79e546"
		                    ]
		                }
		            }
		        }
		    },
		    "params": {
		        "gasLimitBoundDivisor": "0x400",
		        "maximumExtraDataSize": "0x20",
		        "minGasLimit": "0x1388",
		        "networkID" : "0x2323",
		        "eip155Transition": 0,
		        "validateChainIdTransition": 0,
		        "eip140Transition": 0,
		        "eip211Transition": 0,
		        "eip214Transition": 0,
		        "eip658Transition": 0
		    },
		    "genesis": {
		        "seal": {
		            "authorityRound": {
		                "step": "0x0",
		                "signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
		            }
		        },
		        "difficulty": "0x20000",
		        "author": "0x0000000000000000000000000000000000000000",
		        "timestamp": "0x00",
		        "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
		        "extraData": "0x",
		        "gasLimit": "0x222222"
		    },
		    "accounts": {
		        "0x0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
		        "0x0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
		        "0x0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
		        "0x0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
		        "0xea294b897567b3a677c499a051e9032d52bd7347": { "balance": "10000000000000000000000" }
		    }
		}

Issues

Though we have successfully created network, we have some mejor issues in our geth-aura node- 1. geth-aura node fails to synce any block from pairty aura because we know that header structure is the very important structure in whole codebase. I have shown below the geth header structure and parity header structure -

geth header struct -

	// Header represents a block header in the Ethereum blockchain.
	type Header struct {
		ParentHash  common.Hash    `json:"parentHash"       gencodec:"required"`
		UncleHash   common.Hash    `json:"sha3Uncles"       gencodec:"required"`
		Coinbase    common.Address `json:"miner"            gencodec:"required"`
		Root        common.Hash    `json:"stateRoot"        gencodec:"required"`
		TxHash      common.Hash    `json:"transactionsRoot" gencodec:"required"`
		ReceiptHash common.Hash    `json:"receiptsRoot"     gencodec:"required"`
		Bloom       Bloom          `json:"logsBloom"        gencodec:"required"`
		Difficulty  *big.Int       `json:"difficulty"       gencodec:"required"`
		Number      *big.Int       `json:"number"           gencodec:"required"`
		GasLimit    uint64         `json:"gasLimit"         gencodec:"required"`
		GasUsed     uint64         `json:"gasUsed"          gencodec:"required"`
		Time        uint64         `json:"timestamp"        gencodec:"required"`
		Extra       []byte         `json:"extraData"        gencodec:"required"`
		MixDigest   common.Hash    `json:"mixHash"`
		Nonce       BlockNonce     `json:"nonce"`
		// seal field for aura engine
		Seal		[][]byte  	   `json:"seal"`
	}

parity header struct -

		pub struct Header {
			parent_hash: H256,
			timestamp: u64,
			number: BlockNumber,
			author: Address,
			transactions_root: H256,
			uncles_hash: H256,
			extra_data: Bytes,
			state_root: H256,
			receipts_root: H256,
			log_bloom: Bloom,
			gas_used: U256,
			gas_limit: U256,
			difficulty: U256,
			seal: Vec<Bytes>,.
			hash: Option<H256>,
		}
2. We can observe that nonce and mixDisgest are missing in parity header. When syncing block from parity-aura to geth-aura, geth tries to decode the block header to its header struct and it fails because no nonce and mixDisgest fields exist in incoming header. 
3. Another problem happens right now is that mining in geth. When mining worker tries to commit a new block, it fails to decode previous parent block. We know that decoding happens using go reflection, so it fails to decaode it.

Result

We have partially achieved our goal but also created some major issues which need to be solved.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment