mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-17 18:30:45 +00:00
update forensics proof data structure to accomedate vote type (#104)
* update forensics proof data structure to accomedate vote type * refactor log * change blocknum type to uint64 * fix test Co-authored-by: Liam Lai <liam.icheng.lai@gmail.com>
This commit is contained in:
parent
35b964fc16
commit
3ebaea1945
4 changed files with 78 additions and 55 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
package engine_v2
|
package engine_v2
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
@ -46,7 +47,7 @@ func (f *Forensics) SetCommittedQCs(headers []types.Header, incomingQC types.Quo
|
||||||
// highestCommitQCs is an array, assign the parentBlockQc and its child as well as its grandchild QC into this array for forensics purposes.
|
// highestCommitQCs is an array, assign the parentBlockQc and its child as well as its grandchild QC into this array for forensics purposes.
|
||||||
if len(headers) != NUM_OF_FORENSICS_QC-1 {
|
if len(headers) != NUM_OF_FORENSICS_QC-1 {
|
||||||
log.Error("[SetCommittedQcs] Received input length not equal to 2", len(headers))
|
log.Error("[SetCommittedQcs] Received input length not equal to 2", len(headers))
|
||||||
return fmt.Errorf("Received headers length not equal to 2 ")
|
return fmt.Errorf("received headers length not equal to 2 ")
|
||||||
}
|
}
|
||||||
|
|
||||||
var committedQCs []types.QuorumCert
|
var committedQCs []types.QuorumCert
|
||||||
|
|
@ -55,13 +56,13 @@ func (f *Forensics) SetCommittedQCs(headers []types.Header, incomingQC types.Quo
|
||||||
// Decode the qc1 and qc2
|
// Decode the qc1 and qc2
|
||||||
err := utils.DecodeBytesExtraFields(h.Extra, &decodedExtraField)
|
err := utils.DecodeBytesExtraFields(h.Extra, &decodedExtraField)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("[SetCommittedQCs] Fail to decode extra when committing QC to forensics", "Error", err, "Index", i)
|
log.Error("[SetCommittedQCs] Fail to decode extra when committing QC to forensics", "err", err, "index", i)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
if decodedExtraField.QuorumCert.ProposedBlockInfo.Hash != headers[i-1].Hash() {
|
if decodedExtraField.QuorumCert.ProposedBlockInfo.Hash != headers[i-1].Hash() {
|
||||||
log.Error("[SetCommittedQCs] Headers shall be on the same chain and in the right order", "ParentHash", h.ParentHash.Hex(), "headers[i-1].Hash()", headers[i-1].Hash().Hex())
|
log.Error("[SetCommittedQCs] Headers shall be on the same chain and in the right order", "parentHash", h.ParentHash.Hex(), "headers[i-1].Hash()", headers[i-1].Hash().Hex())
|
||||||
return fmt.Errorf("Headers shall be on the same chain and in the right order")
|
return fmt.Errorf("headers shall be on the same chain and in the right order")
|
||||||
} else if i == len(headers)-1 { // The last header shall be pointed by the incoming QC
|
} else if i == len(headers)-1 { // The last header shall be pointed by the incoming QC
|
||||||
if incomingQC.ProposedBlockInfo.Hash != h.Hash() {
|
if incomingQC.ProposedBlockInfo.Hash != h.Hash() {
|
||||||
log.Error("[SetCommittedQCs] incomingQc is not pointing at the last header received", "hash", h.Hash().Hex(), "incomingQC.ProposedBlockInfo.Hash", incomingQC.ProposedBlockInfo.Hash.Hex())
|
log.Error("[SetCommittedQCs] incomingQc is not pointing at the last header received", "hash", h.Hash().Hex(), "incomingQC.ProposedBlockInfo.Hash", incomingQC.ProposedBlockInfo.Hash.Hex())
|
||||||
|
|
@ -114,7 +115,7 @@ func (f *Forensics) ProcessForensics(chain consensus.ChainReader, engine *XDPoS_
|
||||||
// Not found, need a more complex approach to find the two QC
|
// Not found, need a more complex approach to find the two QC
|
||||||
ancestorQC, lowerRoundQCs, _, err := f.findAncestorQcThroughRound(chain, highestCommittedQCs, incomingQuorunCerts)
|
ancestorQC, lowerRoundQCs, _, err := f.findAncestorQcThroughRound(chain, highestCommittedQCs, incomingQuorunCerts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("[ProcessForensics] Error while trying to find ancestor QC through round number", "Error", err)
|
log.Error("[ProcessForensics] Error while trying to find ancestor QC through round number", "err", err)
|
||||||
}
|
}
|
||||||
f.SendForensicProof(chain, engine, ancestorQC, lowerRoundQCs[NUM_OF_FORENSICS_QC-1])
|
f.SendForensicProof(chain, engine, ancestorQC, lowerRoundQCs[NUM_OF_FORENSICS_QC-1])
|
||||||
}
|
}
|
||||||
|
|
@ -136,7 +137,7 @@ func (f *Forensics) SendForensicProof(chain consensus.ChainReader, engine *XDPoS
|
||||||
// Find common ancestor block
|
// Find common ancestor block
|
||||||
ancestorHash, ancestorToLowerRoundPath, ancestorToHigherRoundPath, err := f.FindAncestorBlockHash(chain, lowerRoundQC.ProposedBlockInfo, higherRoundQC.ProposedBlockInfo)
|
ancestorHash, ancestorToLowerRoundPath, ancestorToHigherRoundPath, err := f.FindAncestorBlockHash(chain, lowerRoundQC.ProposedBlockInfo, higherRoundQC.ProposedBlockInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("[SendForensicProof] Error while trying to find ancestor block hash", err)
|
log.Error("[SendForensicProof] Error while trying to find ancestor block hash", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -156,9 +157,9 @@ func (f *Forensics) SendForensicProof(chain consensus.ChainReader, engine *XDPoS
|
||||||
accrossEpoches = true
|
accrossEpoches = true
|
||||||
}
|
}
|
||||||
|
|
||||||
forensicsProof := &types.ForensicProof{
|
content, err := json.Marshal(&types.ForensicsContent{
|
||||||
DivergingHash: ancestorHash,
|
DivergingBlockHash: ancestorHash.Hex(),
|
||||||
AcrossEpochs: accrossEpoches,
|
AcrossEpoch: accrossEpoches,
|
||||||
SmallerRoundInfo: &types.ForensicsInfo{
|
SmallerRoundInfo: &types.ForensicsInfo{
|
||||||
HashPath: ancestorToLowerRoundPath,
|
HashPath: ancestorToLowerRoundPath,
|
||||||
QuorumCert: lowerRoundQC,
|
QuorumCert: lowerRoundQC,
|
||||||
|
|
@ -169,8 +170,18 @@ func (f *Forensics) SendForensicProof(chain consensus.ChainReader, engine *XDPoS
|
||||||
QuorumCert: higherRoundQC,
|
QuorumCert: higherRoundQC,
|
||||||
SignerAddresses: f.getQcSignerAddresses(higherRoundQC),
|
SignerAddresses: f.getQcSignerAddresses(higherRoundQC),
|
||||||
},
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Error("[SendForensicProof] fail to json stringify forensics content", "err", err)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
log.Info("Forensics proof report generated, sending to the stats server", forensicsProof)
|
|
||||||
|
forensicsProof := &types.ForensicProof{
|
||||||
|
ForensicsType: "QC",
|
||||||
|
Content: string(content),
|
||||||
|
}
|
||||||
|
log.Info("Forensics proof report generated, sending to the stats server", "forensicsProof", forensicsProof)
|
||||||
go f.forensicsFeed.Send(types.ForensicsEvent{ForensicsProof: forensicsProof})
|
go f.forensicsFeed.Send(types.ForensicsEvent{ForensicsProof: forensicsProof})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -187,7 +198,7 @@ func (f *Forensics) findAncestorQCs(chain consensus.ChainReader, currentQc types
|
||||||
parentHeader := chain.GetHeaderByHash(parentHash)
|
parentHeader := chain.GetHeaderByHash(parentHash)
|
||||||
if parentHeader == nil {
|
if parentHeader == nil {
|
||||||
log.Error("[findAncestorQCs] Forensics findAncestorQCs unable to find its parent block header", "BlockNum", parentHeader.Number.Int64(), "ParentHash", parentHash.Hex())
|
log.Error("[findAncestorQCs] Forensics findAncestorQCs unable to find its parent block header", "BlockNum", parentHeader.Number.Int64(), "ParentHash", parentHash.Hex())
|
||||||
return nil, fmt.Errorf("Unable to find parent block header in forensics")
|
return nil, fmt.Errorf("unable to find parent block header in forensics")
|
||||||
}
|
}
|
||||||
var decodedExtraField types.ExtraFields_v2
|
var decodedExtraField types.ExtraFields_v2
|
||||||
err := utils.DecodeBytesExtraFields(parentHeader.Extra, &decodedExtraField)
|
err := utils.DecodeBytesExtraFields(parentHeader.Extra, &decodedExtraField)
|
||||||
|
|
@ -221,7 +232,7 @@ func (f *Forensics) checkQCsOnTheSameChain(chain consensus.ChainReader, highestC
|
||||||
var decodedExtraField types.ExtraFields_v2
|
var decodedExtraField types.ExtraFields_v2
|
||||||
err := utils.DecodeBytesExtraFields(parentHeader.Extra, &decodedExtraField)
|
err := utils.DecodeBytesExtraFields(parentHeader.Extra, &decodedExtraField)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("[checkQCsOnTheSameChain] Fail to decode extra when checking the two QCs set on the same chain", "Error", err)
|
log.Error("[checkQCsOnTheSameChain] Fail to decode extra when checking the two QCs set on the same chain", "err", err)
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
proposedBlockInfo = decodedExtraField.QuorumCert.ProposedBlockInfo
|
proposedBlockInfo = decodedExtraField.QuorumCert.ProposedBlockInfo
|
||||||
|
|
@ -322,7 +333,7 @@ func (f *Forensics) FindAncestorBlockHash(chain consensus.ChainReader, firstBloc
|
||||||
for i := 0; i < int(blockNumberDifference); i++ {
|
for i := 0; i < int(blockNumberDifference); i++ {
|
||||||
ph := chain.GetHeaderByHash(higherBlockNumberHash)
|
ph := chain.GetHeaderByHash(higherBlockNumberHash)
|
||||||
if ph == nil {
|
if ph == nil {
|
||||||
return common.Hash{}, ancestorToLowerBlockNumHashPath, ancestorToHigherBlockNumHashPath, fmt.Errorf("Unable to find parent block of hash %v", higherBlockNumberHash)
|
return common.Hash{}, ancestorToLowerBlockNumHashPath, ancestorToHigherBlockNumHashPath, fmt.Errorf("unable to find parent block of hash %v", higherBlockNumberHash)
|
||||||
}
|
}
|
||||||
higherBlockNumberHash = ph.ParentHash
|
higherBlockNumberHash = ph.ParentHash
|
||||||
ancestorToHigherBlockNumHashPath = append(ancestorToHigherBlockNumHashPath, ph.ParentHash.Hex())
|
ancestorToHigherBlockNumHashPath = append(ancestorToHigherBlockNumHashPath, ph.ParentHash.Hex())
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package engine_v2_tests
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
|
"encoding/json"
|
||||||
"math/big"
|
"math/big"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -92,7 +93,7 @@ func TestSetCommittedQCsInOrder(t *testing.T) {
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
err = forensics.SetCommittedQCs(append(headers, *blockchain.GetHeaderByNumber(903), *blockchain.GetHeaderByNumber(902)), *decodedExtraField.QuorumCert)
|
err = forensics.SetCommittedQCs(append(headers, *blockchain.GetHeaderByNumber(903), *blockchain.GetHeaderByNumber(902)), *decodedExtraField.QuorumCert)
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
assert.Equal(t, "Headers shall be on the same chain and in the right order", err.Error())
|
assert.Equal(t, "headers shall be on the same chain and in the right order", err.Error())
|
||||||
|
|
||||||
err = forensics.SetCommittedQCs(append(headers, *blockchain.GetHeaderByNumber(903), *blockchain.GetHeaderByNumber(904)), *decodedExtraField.QuorumCert)
|
err = forensics.SetCommittedQCs(append(headers, *blockchain.GetHeaderByNumber(903), *blockchain.GetHeaderByNumber(904)), *decodedExtraField.QuorumCert)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
@ -169,15 +170,18 @@ func TestForensicsMonitoringNotOnSameChainButHaveSameRoundQC(t *testing.T) {
|
||||||
select {
|
select {
|
||||||
case forensics := <-forensicsEventCh:
|
case forensics := <-forensicsEventCh:
|
||||||
assert.NotNil(t, forensics.ForensicsProof)
|
assert.NotNil(t, forensics.ForensicsProof)
|
||||||
assert.False(t, forensics.ForensicsProof.AcrossEpochs)
|
assert.Equal(t, "QC", forensics.ForensicsProof.ForensicsType)
|
||||||
assert.Equal(t, types.Round(13), forensics.ForensicsProof.SmallerRoundInfo.QuorumCert.ProposedBlockInfo.Round)
|
content := &types.ForensicsContent{}
|
||||||
assert.Equal(t, uint64(913), forensics.ForensicsProof.SmallerRoundInfo.QuorumCert.ProposedBlockInfo.Number.Uint64())
|
json.Unmarshal([]byte(forensics.ForensicsProof.Content), &content)
|
||||||
assert.Equal(t, 9, len(forensics.ForensicsProof.SmallerRoundInfo.HashPath))
|
assert.False(t, content.AcrossEpoch)
|
||||||
assert.Equal(t, 4, len(forensics.ForensicsProof.SmallerRoundInfo.SignerAddresses))
|
assert.Equal(t, types.Round(13), content.SmallerRoundInfo.QuorumCert.ProposedBlockInfo.Round)
|
||||||
assert.Equal(t, types.Round(13), forensics.ForensicsProof.LargerRoundInfo.QuorumCert.ProposedBlockInfo.Round)
|
assert.Equal(t, uint64(913), content.SmallerRoundInfo.QuorumCert.ProposedBlockInfo.Number.Uint64())
|
||||||
assert.Equal(t, uint64(912), forensics.ForensicsProof.LargerRoundInfo.QuorumCert.ProposedBlockInfo.Number.Uint64())
|
assert.Equal(t, 9, len(content.SmallerRoundInfo.HashPath))
|
||||||
assert.Equal(t, 8, len(forensics.ForensicsProof.LargerRoundInfo.HashPath))
|
assert.Equal(t, 4, len(content.SmallerRoundInfo.SignerAddresses))
|
||||||
assert.Equal(t, 4, len(forensics.ForensicsProof.LargerRoundInfo.SignerAddresses))
|
assert.Equal(t, types.Round(13), content.LargerRoundInfo.QuorumCert.ProposedBlockInfo.Round)
|
||||||
|
assert.Equal(t, uint64(912), content.LargerRoundInfo.QuorumCert.ProposedBlockInfo.Number.Uint64())
|
||||||
|
assert.Equal(t, 8, len(content.LargerRoundInfo.HashPath))
|
||||||
|
assert.Equal(t, 4, len(content.LargerRoundInfo.SignerAddresses))
|
||||||
return
|
return
|
||||||
case <-time.After(5 * time.Second):
|
case <-time.After(5 * time.Second):
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
|
|
@ -225,15 +229,19 @@ func TestForensicsMonitoringNotOnSameChainDoNotHaveSameRoundQC(t *testing.T) {
|
||||||
select {
|
select {
|
||||||
case forensics := <-forensicsEventCh:
|
case forensics := <-forensicsEventCh:
|
||||||
assert.NotNil(t, forensics.ForensicsProof)
|
assert.NotNil(t, forensics.ForensicsProof)
|
||||||
assert.False(t, forensics.ForensicsProof.AcrossEpochs)
|
assert.Equal(t, "QC", forensics.ForensicsProof.ForensicsType)
|
||||||
assert.Equal(t, types.Round(14), forensics.ForensicsProof.SmallerRoundInfo.QuorumCert.ProposedBlockInfo.Round)
|
content := &types.ForensicsContent{}
|
||||||
assert.Equal(t, uint64(914), forensics.ForensicsProof.SmallerRoundInfo.QuorumCert.ProposedBlockInfo.Number.Uint64())
|
json.Unmarshal([]byte(forensics.ForensicsProof.Content), &content)
|
||||||
assert.Equal(t, 10, len(forensics.ForensicsProof.SmallerRoundInfo.HashPath))
|
|
||||||
assert.Equal(t, 4, len(forensics.ForensicsProof.SmallerRoundInfo.SignerAddresses))
|
assert.False(t, content.AcrossEpoch)
|
||||||
assert.Equal(t, types.Round(16), forensics.ForensicsProof.LargerRoundInfo.QuorumCert.ProposedBlockInfo.Round)
|
assert.Equal(t, types.Round(14), content.SmallerRoundInfo.QuorumCert.ProposedBlockInfo.Round)
|
||||||
assert.Equal(t, uint64(906), forensics.ForensicsProof.LargerRoundInfo.QuorumCert.ProposedBlockInfo.Number.Uint64())
|
assert.Equal(t, uint64(914), content.SmallerRoundInfo.QuorumCert.ProposedBlockInfo.Number.Uint64())
|
||||||
assert.Equal(t, 2, len(forensics.ForensicsProof.LargerRoundInfo.HashPath))
|
assert.Equal(t, 10, len(content.SmallerRoundInfo.HashPath))
|
||||||
assert.Equal(t, 2, len(forensics.ForensicsProof.LargerRoundInfo.SignerAddresses))
|
assert.Equal(t, 4, len(content.SmallerRoundInfo.SignerAddresses))
|
||||||
|
assert.Equal(t, types.Round(16), content.LargerRoundInfo.QuorumCert.ProposedBlockInfo.Round)
|
||||||
|
assert.Equal(t, uint64(906), content.LargerRoundInfo.QuorumCert.ProposedBlockInfo.Number.Uint64())
|
||||||
|
assert.Equal(t, 2, len(content.LargerRoundInfo.HashPath))
|
||||||
|
assert.Equal(t, 2, len(content.LargerRoundInfo.SignerAddresses))
|
||||||
return
|
return
|
||||||
case <-time.After(5 * time.Second):
|
case <-time.After(5 * time.Second):
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
|
|
@ -282,15 +290,19 @@ func TestForensicsAcrossEpoch(t *testing.T) {
|
||||||
select {
|
select {
|
||||||
case forensics := <-forensicsEventCh:
|
case forensics := <-forensicsEventCh:
|
||||||
assert.NotNil(t, forensics.ForensicsProof)
|
assert.NotNil(t, forensics.ForensicsProof)
|
||||||
assert.True(t, forensics.ForensicsProof.AcrossEpochs)
|
assert.Equal(t, "QC", forensics.ForensicsProof.ForensicsType)
|
||||||
assert.Equal(t, types.Round(900), forensics.ForensicsProof.SmallerRoundInfo.QuorumCert.ProposedBlockInfo.Round)
|
content := &types.ForensicsContent{}
|
||||||
assert.Equal(t, uint64(1800), forensics.ForensicsProof.SmallerRoundInfo.QuorumCert.ProposedBlockInfo.Number.Uint64())
|
json.Unmarshal([]byte(forensics.ForensicsProof.Content), &content)
|
||||||
assert.Equal(t, 10, len(forensics.ForensicsProof.SmallerRoundInfo.HashPath))
|
|
||||||
assert.Equal(t, 4, len(forensics.ForensicsProof.SmallerRoundInfo.SignerAddresses))
|
assert.True(t, content.AcrossEpoch)
|
||||||
assert.Equal(t, types.Round(902), forensics.ForensicsProof.LargerRoundInfo.QuorumCert.ProposedBlockInfo.Round)
|
assert.Equal(t, types.Round(900), content.SmallerRoundInfo.QuorumCert.ProposedBlockInfo.Round)
|
||||||
assert.Equal(t, uint64(1792), forensics.ForensicsProof.LargerRoundInfo.QuorumCert.ProposedBlockInfo.Number.Uint64())
|
assert.Equal(t, uint64(1800), content.SmallerRoundInfo.QuorumCert.ProposedBlockInfo.Number.Uint64())
|
||||||
assert.Equal(t, 2, len(forensics.ForensicsProof.LargerRoundInfo.HashPath))
|
assert.Equal(t, 10, len(content.SmallerRoundInfo.HashPath))
|
||||||
assert.Equal(t, 2, len(forensics.ForensicsProof.LargerRoundInfo.SignerAddresses))
|
assert.Equal(t, 4, len(content.SmallerRoundInfo.SignerAddresses))
|
||||||
|
assert.Equal(t, types.Round(902), content.LargerRoundInfo.QuorumCert.ProposedBlockInfo.Round)
|
||||||
|
assert.Equal(t, uint64(1792), content.LargerRoundInfo.QuorumCert.ProposedBlockInfo.Number.Uint64())
|
||||||
|
assert.Equal(t, 2, len(content.LargerRoundInfo.HashPath))
|
||||||
|
assert.Equal(t, 2, len(content.LargerRoundInfo.SignerAddresses))
|
||||||
return
|
return
|
||||||
case <-time.After(5 * time.Second):
|
case <-time.After(5 * time.Second):
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,22 @@
|
||||||
package types
|
package types
|
||||||
|
|
||||||
import "github.com/XinFinOrg/XDPoSChain/common"
|
|
||||||
|
|
||||||
type ForensicsInfo struct {
|
type ForensicsInfo struct {
|
||||||
HashPath []string // HashesTillSmallerRoundQc or HashesTillLargerRoundQc
|
HashPath []string `json:"hashPath"`
|
||||||
QuorumCert QuorumCert
|
QuorumCert QuorumCert `json:"quorumCert"`
|
||||||
SignerAddresses []string
|
SignerAddresses []string `json:"signerAddresses"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ForensicsContent struct {
|
||||||
|
DivergingBlockNumber uint64 `json:"divergingBlockNumber"`
|
||||||
|
DivergingBlockHash string `json:"divergingBlockHash"`
|
||||||
|
AcrossEpoch bool `json:"acrossEpoch"`
|
||||||
|
SmallerRoundInfo *ForensicsInfo `json:"smallerRoundInfo"`
|
||||||
|
LargerRoundInfo *ForensicsInfo `json:"largerRoundInfo"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ForensicProof struct {
|
type ForensicProof struct {
|
||||||
SmallerRoundInfo *ForensicsInfo
|
ForensicsType string `json:"forensicsType"` // QC or VOTE
|
||||||
LargerRoundInfo *ForensicsInfo
|
Content string `json:"content"` // Json string of the forensics data
|
||||||
DivergingHash common.Hash
|
|
||||||
AcrossEpochs bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ForensicsEvent struct {
|
type ForensicsEvent struct {
|
||||||
|
|
|
||||||
|
|
@ -547,11 +547,7 @@ func (s *Service) reportBlock(conn *websocket.Conn, block *types.Block) error {
|
||||||
|
|
||||||
// reportForensics forward the forensics repors it to the stats server.
|
// reportForensics forward the forensics repors it to the stats server.
|
||||||
func (s *Service) reportForensics(conn *websocket.Conn, forensicsProof *types.ForensicProof) error {
|
func (s *Service) reportForensics(conn *websocket.Conn, forensicsProof *types.ForensicProof) error {
|
||||||
log.Info(
|
log.Info("Sending Forensics report to ethstats", "ForensicsType", forensicsProof.ForensicsType)
|
||||||
"Sending Forensics report to ethstats",
|
|
||||||
"SmallerRoundInfo.QuorumCert.ProposedBlockInfo.Hash", forensicsProof.SmallerRoundInfo.QuorumCert.ProposedBlockInfo.Hash,
|
|
||||||
"LargerRoundInfo.QuorumCert.ProposedBlockInfo.Hash", forensicsProof.LargerRoundInfo.QuorumCert.ProposedBlockInfo.Hash,
|
|
||||||
)
|
|
||||||
|
|
||||||
stats := map[string]interface{}{
|
stats := map[string]interface{}{
|
||||||
"id": s.node,
|
"id": s.node,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue