Skip to content

Commit

Permalink
get block miner for Rinkeby (#59)
Browse files Browse the repository at this point in the history
* for PoA network like Rinkeby "miner" field is empty due to consensus algorithm ethereum/EIPs#225
Miner address is derivable from "extra" field. Last 65 bytes are miner signature

* use node version 15 in Github Action

* Jest doesn't recognize Buffer as Uint8Array. To fix it added custom jest environment

* fix linter error
  • Loading branch information
ramilexe committed Jun 23, 2021
1 parent 0ea9646 commit 2aef36b
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 4 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/on-master.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [10.x, 12.x, 14.x, 15.x]
node-version: [15.x]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/on-pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [10.x, 12.x, 14.x, 15.x]
node-version: [15.x]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
Expand Down
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ module.exports = {
transform: {
"^.+\\.ts$": "ts-jest"
},
testEnvironment: './src/jest-environment.js',
};
15 changes: 15 additions & 0 deletions src/jest-environment.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const NodeEnvironment = require('jest-environment-node');

class WatcherEnvironment extends NodeEnvironment{
constructor (config) {
super(Object.assign({}, config, {
globals: Object.assign({}, config.globals, {
Uint8Array: Uint8Array,
ArrayBuffer: ArrayBuffer
})
}))
}
}


module.exports = WatcherEnvironment
10 changes: 9 additions & 1 deletion src/utils/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Contract from "../models/contract/contract";
import {decodeStorageCid, getContractsFromLogs, increaseHexByOne, mhDataToBuffer} from "./index";
import {decodeStorageCid, extractMinerFromExtra, getContractsFromLogs, increaseHexByOne, mhDataToBuffer} from "./index";
import {EthStorageCid} from "../types";

function dummyContract(address: string): Contract {
Expand Down Expand Up @@ -90,4 +90,12 @@ describe('utils', () => {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c]));
});

test('extractMinerFromExtra', () => {
// block 8647996 on Rinkeby
const blockRlp = "f9025ca00a84ebb80b8616551e251a42273bc0860e1db619affc009a7d17b96b8dba6cbaa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0d7ce7224e063acb68e6dd5ba4e0ef90d4c6e61d4e30cdc6b6b5ef5adfc32a8c6a09db0cbfa54f72435c8f15326d01924bb0b9c1aa4ffa1b05eef9e4dbafc4179a1a0e9602d458a57dd10df00ac06b014da188c1bfb2276fd8b39cde58a82cf78169eb9010000020100400000100000400040008800000000100404008000000000004000000000820100000800210000400080200000010000800000000800000000a00240000000820000000800000008008000000000000800000401100000400000001430000000200000000000000010808000200090000000001520080010400000000100000100042000001840000100000080000040104088000000010000040000228000000000400040200000040000040000084000100020000000004000800000104002200000000000000000000047012080010000040040001000000000a00010000000000040000000020000120000000080000006008000100001000000018383f53c8398c5278324527d8460ad1423b861d883010a04846765746888676f312e31362e33856c696e7578000000000000009e5b0e7ed267a159861a0c8a5b982adb1c3d4cfd12cd85eed6389e113ba614e23350342cd4cfeb8ea0d34bcaacadfa1a108be9c204ea5c95642fb8c03b6493df01a00000000000000000000000000000000000000000000000000000000000000000880000000000000000";
const miner = "0x7ffc57839b00206d1ad20c69a1981b489f772031";

expect(extractMinerFromExtra(blockRlp)).toEqual(miner);
});
});
30 changes: 29 additions & 1 deletion src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {rlp, BN} from 'ethereumjs-util';
import {rlp, BN, fromRpcSig, keccak, ecrecover, addHexPrefix, pubToAddress} from 'ethereumjs-util';
import Contract from "../models/contract/contract";
import {EthStorageCid} from "../types";

Expand Down Expand Up @@ -99,4 +99,32 @@ export const decodeExtra = (data: string) => { // eslint-disable-line
}
return `${str}/${value.toString('utf-8')}`
}, '');
}

/**
* Returns miner address for PoA networks. Extract it from block extra field
*
* @param blockRlp
*/
export const extractMinerFromExtra = (blockRlp: string): string => {
const blockRlpBuf = mhDataToBuffer(blockRlp);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const decoded: any = rlp.decode(blockRlpBuf);
const extra = decoded[12];
// last 65 bytes are miner signature
const sig = extra.slice(extra.length - 65);

// convert hex signature to v, r, s format
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const signature = fromRpcSig(sig as any as string);

// to recovery miner address from signature we need to get block hash without this signature
decoded[12] = extra.slice(0, extra.length - 65);
const encodedBlock = rlp.encode(decoded);
const blockHash = keccak(encodedBlock);
console.log(blockHash, signature);
const pub = ecrecover(blockHash, signature.v, signature.r, signature.s)
const address = addHexPrefix(pubToAddress(pub).toString('hex'));

return address;
}

0 comments on commit 2aef36b

Please sign in to comment.