forked from bnb-chain/bsc
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cmd/geth: Set compatible genesis and IBFT hash method (#3)
## Description The rlp hasher of PolygonEdge is wired, but we still need to support it since huge amount data already exist in Dogechain Mainnet. And the PR adds hard forks of Dogechain too, including `portland` and `detroit`. We separate the `Header` rlp Hasher(for indexing) and rlp Encoder(for persistence), so as to support IBFT verification consensus (which shall be deprecated in next hard fork). ## Test cases ### Multiple consensus * Parlia(BSC) Mainnet genesis and normal header. * Clique(Rinkeby) Testnet genesis and normal header. * IBFT(Dogechain) Devnet genesis and normal header. Compare the header hash, and they are correct. ### Dogechain Mainnet Provide Mainnet genesis: [genesis-dbsc.json](https://github.com/dogechain-lab/dbsc/files/11145646/genesis-dbsc.txt) Compile and use current PR branch geth to init genesis block in datadir. ```bash go run cmd/geth init --datadir $PWD/data genesis-dbsc.json ``` The log should print like this: ``` Successfully wrote genesis state database=chaindata hash=5ee4e7..da5b74 ``` Query the [genesis block](https://explorer.dogechain.dog/block/0) in Dogechain explorer, found the hash `0x5ee4e79b3d798f8bd5a3a5f92e24f62198888aed028354ad5463aea8e5da5b74` is equal and right. Use [leveldb-tools](https://github.com/dogechain-lab/leveldb-tools) to query local database: ```bash $ ldb show "h*" 0x485ee4e79b3d798f8bd5a3a5f92e24f62198888aed028354ad5463aea8e5da5b74:0x0000000000000000 0x6800000000000000005ee4e79b3d798f8bd5a3a5f92e24f62198888aed028354ad5463aea8e5da5b74:0xf9026fa00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0de17336927fa082de0b75e9c9853121e2711419f33e434799df5ab20d9863ad6a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001808401c9c3808307000080b87a0000000000000000000000000000000000000000000000000000000000000000f858f85494d668bba507d0438ff22ee8ceb341323765669a24947175996ff9dcb8fbb83b68e2b88f1a029014555b9492bb5d1a856e54157232b43fe1c9c7e89ee36abe9464f2686e3ac7492c3b3f662d32ecb8b6bfa548fe80c0a00000000000000000000000000000000000000000000000000000000000000000880000000000000000 0x6800000000000000005ee4e79b3d798f8bd5a3a5f92e24f62198888aed028354ad5463aea8e5da5b7474:0x01 0x6800000000000000006e:0x5ee4e79b3d798f8bd5a3a5f92e24f62198888aed028354ad5463aea8e5da5b74 ``` Use [online rlp decoder](https://codechain-io.github.io/rlp-debugger/) to parse the header info (key: `0x6800000000000000005ee4e79b3d798f8bd5a3a5f92e24f62198888aed028354ad5463aea8e5da5b74`): We'll find that all fields are correctly set, including IBFT verifying field `Extra`.
- Loading branch information
1 parent
dc2a5af
commit d68e36f
Showing
8 changed files
with
310 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
package types | ||
|
||
import ( | ||
"bytes" | ||
"errors" | ||
"io" | ||
|
||
"github.com/ethereum/go-ethereum/common" | ||
"github.com/ethereum/go-ethereum/rlp" | ||
) | ||
|
||
const ( | ||
// IBFTExtraVanity (Istanbul BFT Vanity) represents a fixed number of extra-data bytes reserved for proposer vanity | ||
IBFTExtraVanity = 32 | ||
) | ||
|
||
var ( | ||
ErrIBFTInvalidMixHash = errors.New("invalid ibft mix hash") | ||
ErrInvalidIBFTExtraLength = errors.New("invalid ibft extra length") | ||
ErrNotIBFTExtraPrefix = errors.New("not ibft extra prefix") | ||
) | ||
|
||
var ( | ||
// IBFTMixHash represents a hash of "Istanbul practical byzantine fault tolerance" | ||
// to identify whether the block is from Istanbul consensus engine | ||
IBFTMixHash = common.HexToHash("0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365") | ||
|
||
// IBFTExtraPrefix represents extra hash prefix of "Istanbul practical byzantine fault tolerance". | ||
// The difference of extra between geth, bsc and dogechain (ibft) is that ibft uses zero instead of | ||
// client version on prefix | ||
IBFTExtraPrefix = common.Hash{} | ||
) | ||
|
||
// IBFTExtra defines the structure of the extra field for I(stanbul)BFT | ||
type IBFTExtra struct { | ||
Validators []common.Address | ||
Seal []byte | ||
CommittedSeal [][]byte | ||
} | ||
|
||
// getIbftExtra returns the istanbul extra data field from the passed in header | ||
func getIbftExtra(h *Header) (*IBFTExtra, error) { | ||
// must longer than ibft extra prefix | ||
if len(h.Extra) < IBFTExtraVanity { | ||
return nil, ErrInvalidIBFTExtraLength | ||
} | ||
|
||
// must be ibft extra prefix | ||
if !bytes.Equal(h.Extra[:IBFTExtraVanity], IBFTExtraPrefix[:]) { | ||
return nil, ErrNotIBFTExtraPrefix | ||
} | ||
|
||
data := h.Extra[IBFTExtraVanity:] | ||
extra := &IBFTExtra{} | ||
|
||
if err := rlp.DecodeBytes(data, extra); err != nil { | ||
return nil, err | ||
} | ||
|
||
return extra, nil | ||
} | ||
|
||
// putIBFTExtraValidators is a helper method that adds validators to the extra field in the header | ||
func putIBFTExtraValidators(h *Header, validators []common.Address) error { | ||
ibftExtra := &IBFTExtra{ | ||
Validators: validators, | ||
Seal: []byte{}, | ||
CommittedSeal: [][]byte{}, | ||
} | ||
|
||
extra, err := rlp.EncodeToBytes(ibftExtra) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
var zeroBytes = make([]byte, 32) | ||
h.Extra = append(zeroBytes, extra...) | ||
|
||
return nil | ||
} | ||
|
||
func ibftHeaderHashRLP(_w io.Writer, obj *Header) error { | ||
// genesis will not check ibft mix hash | ||
if obj.Number.Sign() > 0 && obj.MixDigest != IBFTMixHash { | ||
return ErrIBFTInvalidMixHash | ||
} | ||
|
||
// when hashing the block for signing we have to remove from | ||
// the extra field the seal and committed seal items | ||
extra, err := getIbftExtra(obj) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// this function replaces extra so we need to make a copy | ||
h := CopyHeader(obj) // Remove later | ||
|
||
putIBFTExtraValidators(h, extra.Validators) | ||
|
||
w := rlp.NewEncoderBuffer(_w) | ||
_tmp0 := w.List() | ||
w.WriteBytes(h.ParentHash[:]) | ||
w.WriteBytes(h.UncleHash[:]) | ||
w.WriteBytes(h.Coinbase[:]) | ||
w.WriteBytes(h.Root[:]) | ||
w.WriteBytes(h.TxHash[:]) | ||
w.WriteBytes(h.ReceiptHash[:]) | ||
w.WriteBytes(h.Bloom[:]) | ||
if h.Difficulty == nil { | ||
w.Write(rlp.EmptyString) | ||
} else { | ||
if h.Difficulty.Sign() == -1 { | ||
return rlp.ErrNegativeBigInt | ||
} | ||
w.WriteBigInt(h.Difficulty) | ||
} | ||
if h.Number == nil { | ||
w.Write(rlp.EmptyString) | ||
} else { | ||
if h.Number.Sign() == -1 { | ||
return rlp.ErrNegativeBigInt | ||
} | ||
w.WriteBigInt(h.Number) | ||
} | ||
w.WriteUint64(h.GasLimit) | ||
w.WriteUint64(h.GasUsed) | ||
w.WriteUint64(h.Time) | ||
w.WriteBytes(h.Extra) | ||
w.ListEnd(_tmp0) | ||
return w.Flush() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.