Skip to content

Commit

Permalink
Merge pull request #2101 from blukat29/consensus-api-sighash
Browse files Browse the repository at this point in the history
api: Print sigHash in getBlockWithConsensusInfo
  • Loading branch information
blukat29 committed Jan 29, 2024
2 parents 2ca3b82 + 5368f9a commit bd7b0b0
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 51 deletions.
11 changes: 6 additions & 5 deletions cmd/utils/nodecmd/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ func parseHeaderFile(headerFile string) (*types.Header, common.Hash, error) {
}

func decodeExtra(headerFile string) (map[string]interface{}, error) {
header, hash, err := parseHeaderFile(headerFile)
header, sigHash, err := parseHeaderFile(headerFile)
if err != nil {
return nil, err
}
Expand All @@ -194,21 +194,22 @@ func decodeExtra(headerFile string) (map[string]interface{}, error) {
for idx, addr := range istanbulExtra.Validators {
validators[idx] = addr.String()
}
proposer, err := istanbul.GetSignatureAddress(hash.Bytes(), istanbulExtra.Seal)
proposer, err := istanbul.GetSignatureAddress(sigHash.Bytes(), istanbulExtra.Seal)
if err != nil {
return nil, err
}
committers, cSealsBytes, err := backend.ParseCommitteedSeals(header)
committers, err := backend.RecoverCommittedSeals(istanbulExtra, header.Hash())
if err != nil {
return nil, err
}
cSeals := make([]string, len(istanbulExtra.CommittedSeal))
for i := 0; i < len(cSeals); i++ {
cSeals[i] = hexutil.Encode(cSealsBytes[i])
cSeals[i] = hexutil.Encode(istanbulExtra.CommittedSeal[i])
}

m := make(map[string]interface{})
m["hash"] = hash
m["hash"] = header.Hash().Hex()
m["sigHash"] = sigHash.Hex()
m["validators"] = validators
m["seal"] = hexutil.Encode(istanbulExtra.Seal)
m["committedSeal"] = cSeals
Expand Down
8 changes: 6 additions & 2 deletions consensus/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,9 @@ type ChainReader interface {
StateAt(root common.Hash) (*state.StateDB, error)
}

//go:generate mockgen -destination=consensus/mocks/engine_mock.go -package=mocks github.com/klaytn/klaytn/consensus Engine
// Engine is an algorithm agnostic consensus engine.
//
//go:generate mockgen -destination=consensus/mocks/engine_mock.go -package=mocks github.com/klaytn/klaytn/consensus Engine
type Engine interface {
// Author retrieves the Klaytn address of the account that minted the given
// block.
Expand Down Expand Up @@ -168,8 +169,11 @@ type Istanbul interface {
}

type ConsensusInfo struct {
// Proposer signs [sigHash] to make seal; Validators signs [block.Hash + msgCommit] to make committedSeal
SigHash common.Hash
Proposer common.Address
OriginProposer common.Address // the proposal of 0 round at the same block number
OriginProposer common.Address // the proposer of 0th round at the same block number
Committee []common.Address
Committers []common.Address
Round byte
}
29 changes: 8 additions & 21 deletions consensus/istanbul/backend/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,39 +327,26 @@ func (api *APIExtension) makeRPCBlockOutput(b *types.Block,
}
}

committers, _, err := ParseCommitteedSeals(head)
if err != nil {
parseErr := make(map[string]interface{})
parseErr["ERROR"] = err
return parseErr
}

r["committee"] = cInfo.Committee
r["committers"] = committers
r["committers"] = cInfo.Committers
r["sigHash"] = cInfo.SigHash
r["proposer"] = cInfo.Proposer
r["round"] = cInfo.Round
r["originProposer"] = cInfo.OriginProposer
r["transactions"] = rpcTransactions
return r
}

func ParseCommitteedSeals(header *types.Header) ([]common.Address, [][]byte, error) {
if header == nil {
return nil, nil, errors.New("Empty header")
}
istanbulExtra, err := types.ExtractIstanbulExtra(header)
if err != nil {
return nil, nil, err
}
committers := make([]common.Address, len(istanbulExtra.CommittedSeal))
for idx, cs := range istanbulExtra.CommittedSeal {
committer, err := istanbul.GetSignatureAddress(istanbulCore.PrepareCommittedSeal(header.Hash()), cs)
func RecoverCommittedSeals(extra *types.IstanbulExtra, headerHash common.Hash) ([]common.Address, error) {
committers := make([]common.Address, len(extra.CommittedSeal))
for idx, cs := range extra.CommittedSeal {
committer, err := istanbul.GetSignatureAddress(istanbulCore.PrepareCommittedSeal(headerHash), cs)
if err != nil {
return nil, nil, err
return nil, err
}
committers[idx] = committer
}
return committers, istanbulExtra.CommittedSeal, nil
return committers, nil
}

// TODO-Klaytn: This API functions should be managed with API functions with namespace "klay"
Expand Down
50 changes: 50 additions & 0 deletions consensus/istanbul/backend/api_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package backend

import (
"testing"

"github.com/klaytn/klaytn/blockchain/types"
"github.com/klaytn/klaytn/common"
"github.com/klaytn/klaytn/consensus/istanbul"
istanbulCore "github.com/klaytn/klaytn/consensus/istanbul/core"
"github.com/klaytn/klaytn/rlp"
"github.com/stretchr/testify/assert"
)

func TestRecoverCommittedSeals(t *testing.T) {
// Baobab debug.getBlockRlp(144654443)
var (
blockRlp = "f904f1f903c1a046f5775da65a7c9e9a12d2ee4d010285df656ebd64c97cad2669c42c4aa39d8b94f90675a56a03f836204d66c0f923e00500ddc90aa0cec442b90b1d21e465474f7e5c233c3461e950bf383b39227917ad8a608653dfa004de211f466c3543bb2e3db8c976e9d046c214bc33c982d664b7e494d0c2c88aa0390d7c4c79e1e594bcc3236742112d9a7358652e66b1c97dea1c490e69276617b90100000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000002000000000000000000800000000000000000000010000020000000000000010000000000000000000000000000000000000006000000000000000000000004000000000000001240004000000000000000000000000000000000000004800000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000002000000000000000000000000000000000000000400000a00000000000000000000000000000000000000000000184089f406b8302c7158465b315d945b90187d883010c00846b6c617988676f312e32302e36856c696e757800000000000000f90164f85494571e53df607be97431a5bbefca1dffe5aef56f4d945cb1a7dccbd0dc446e3640898ede8820368554c89499fb17d324fa0e07f23b49d09028ac0919414db694b74ff9dea397fe9e231df545eb53fe2adf776cb2b841dc7dca1dc15d06e83a0a39217052ad7915d3b0f0a68f49d4b53498130a1212327b9dd5514362eb3e5f0ebb277e7d38baecad9cd045d3627d3a1f322422eeee8a01f8c9b8410a3fb9227632261c8520f1ee859c503f017701fdb92c2e39f532e190779888a63cf112cf2e530f656153ab64103558c26fb9ca43d5cf31425e62569f891e1eca00b8414a32097b87c481f145ae75ded4e8ec2ea4230c7b2feb3f3afcd2d22ea0b7d4596f4354e185d4f1f93b4d758ddb97e9203e1d306413ad0db1f4a779156879baa300b841fde66a2abb916bf314c82a2dfcd82ed356af829a98573d7cdb4a74cccb6ceecc22358750332ad31dccd9a890dbde7e0d4e21f173515011656f6c222169ba94620080808505d21dba00b860a027d1591d784686d063234bc000a8b9f829da534c41b555c867329b2b4abc5ef8f36245546adcc35c31dbc7c16b084a0d48487817b0eb191ac5b9aa8f3c908d413f19a1e784c3920fc0c0ef9180582902dc30ee8b70859e493af467bc227403a047f8b901fe5f4a3387cb6ccd5c14a00f7649247d2d2d315a652c378f328c1970f9012a31f90126830a596a850ba43b740083061a8094a317038414a275365ed4a085b786e83e761d20a580944dd5fa43054709155d5e68fadd3aeb3f853f34b0b844202ee0ed00000000000000000000000000000000000000000000000000000000000a596a0000000000000000000000000000000000000000000000000000000000000377f847f8458207f5a085d89c94a1e010f90b8e825e5321b1fff91ea748f50424448e17d5f1658498bda053936941c152ce9721447711a80c39b07fb36d42c8a8b6a258d8b071ab3b6c96945e6b99bca5a21818d40d12c56194674989146fc8f847f8458207f5a0c40d29e71cdd4f07051398fa35d41a25cc2f5db165d3ad8aa8b5eff20cc81996a01ea154d91320586165b139870e688a0ab4837137c5208a2da60cbdc60d7c7d81"
expectedProposer = common.HexToAddress("0x5cb1a7dccbd0dc446e3640898ede8820368554c8")
expectedValidators = []common.Address{ // the composition may differ by consensus node. this particular node has received following 3 votes.
common.HexToAddress("0x5cb1a7dccbd0dc446e3640898ede8820368554c8"),
common.HexToAddress("0x571e53df607be97431a5bbefca1dffe5aef56f4d"),
common.HexToAddress("0x99fb17d324fa0e07f23b49d09028ac0919414db6"),
}
)

var block *types.Block
assert.Nil(t, rlp.DecodeBytes(common.FromHex(blockRlp), &block))
extra, err := types.ExtractIstanbulExtra(block.Header())
assert.Nil(t, err)

// check block seal
seal := extra.Seal
sigHash := sigHash(block.Header())
proposer, _ := istanbul.GetSignatureAddress(sigHash[:], seal)
assert.Equal(t, proposer, expectedProposer)
t.Logf("%x %x -> %x\n", sigHash, seal, proposer)

// check committed seals manually
for i, seal := range extra.CommittedSeal {
sigData := istanbulCore.PrepareCommittedSeal(block.Hash())
validator, _ := istanbul.GetSignatureAddress(sigData, seal)
assert.Equal(t, validator, expectedValidators[i])
t.Logf("%x %x -> %x\n", sigData, seal, validator)
}

// check committed seals using RecoverCommittedSeals
validators, err := RecoverCommittedSeals(extra, block.Hash())
assert.Nil(t, err)
assert.Equal(t, validators, expectedValidators)
}
47 changes: 24 additions & 23 deletions consensus/istanbul/backend/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -818,34 +818,35 @@ func (sb *backend) GetConsensusInfo(block *types.Block) (consensus.ConsensusInfo
committeeAddrs[i] = v.Address()
}

// verify the committee list of the block using istanbul
//proposalSeal := istanbulCore.PrepareCommittedSeal(block.Hash())
//extra, err := types.ExtractIstanbulExtra(block.Header())
//istanbulAddrs := make([]common.Address, len(committeeAddrs))
//for i, seal := range extra.CommittedSeal {
// addr, err := istanbul.GetSignatureAddress(proposalSeal, seal)
// istanbulAddrs[i] = addr
// if err != nil {
// return proposer, []common.Address{}, err
// }
//
// var found bool = false
// for _, v := range committeeAddrs {
// if addr == v {
// found = true
// break
// }
// }
// if found == false {
// logger.Trace("validator is different!", "snap", committeeAddrs, "istanbul", istanbulAddrs)
// return proposer, committeeAddrs, errors.New("validator set is different from Istanbul engine!!")
// }
//}
// get the committers of this block from committed seals
extra, err := types.ExtractIstanbulExtra(block.Header())
if err != nil {
return consensus.ConsensusInfo{}, err
}
committers, err := RecoverCommittedSeals(extra, block.Hash())
if err != nil {
return consensus.ConsensusInfo{}, err
}

// Uncomment to validate if committers are in the committee
// for _, recovered := range committers {
// found := false
// for _, calculated := range committeeAddrs {
// if recovered == calculated {
// found = true
// }
// }
// if !found {
// return consensus.ConsensusInfo{}, errInvalidCommittedSeals
// }
// }

cInfo := consensus.ConsensusInfo{
SigHash: sigHash(block.Header()),
Proposer: proposer,
OriginProposer: originProposer,
Committee: committeeAddrs,
Committers: committers,
Round: round,
}

Expand Down

0 comments on commit bd7b0b0

Please sign in to comment.