Re-order uncles if calculated uncle hash doesn't match #188
2
go.mod
2
go.mod
@ -274,7 +274,7 @@ require (
|
|||||||
go.uber.org/multierr v1.8.0 // indirect
|
go.uber.org/multierr v1.8.0 // indirect
|
||||||
go.uber.org/zap v1.21.0 // indirect
|
go.uber.org/zap v1.21.0 // indirect
|
||||||
go4.org v0.0.0-20200411211856-f5505b9728dd // indirect
|
go4.org v0.0.0-20200411211856-f5505b9728dd // indirect
|
||||||
golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8 // indirect
|
golang.org/x/crypto v0.0.0-20220824171710-5757bc0c5503 // indirect
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect
|
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect
|
||||||
golang.org/x/net v0.0.0-20220607020251-c690dde0001d // indirect
|
golang.org/x/net v0.0.0-20220607020251-c690dde0001d // indirect
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
||||||
|
4
go.sum
4
go.sum
@ -1953,8 +1953,8 @@ golang.org/x/crypto v0.0.0-20210813211128-0a44fdfbc16e/go.mod h1:GvvjBRRGRdwPK5y
|
|||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8 h1:GIAS/yBem/gq2MUqgNIzUHW7cJMmx3TGZOrnyYaNQ6c=
|
golang.org/x/crypto v0.0.0-20220824171710-5757bc0c5503 h1:vJ2V3lFLg+bBhgroYuRfyN583UzVveQmIXjc8T/y3to=
|
||||||
golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220824171710-5757bc0c5503/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
|
@ -177,6 +177,7 @@ func (pea *PublicEthAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockN
|
|||||||
// GetBlockByHash returns the requested block. When fullTx is true all transactions in the block are returned in full
|
// GetBlockByHash returns the requested block. When fullTx is true all transactions in the block are returned in full
|
||||||
// detail, otherwise only the transaction hash is returned.
|
// detail, otherwise only the transaction hash is returned.
|
||||||
func (pea *PublicEthAPI) GetBlockByHash(ctx context.Context, hash common.Hash, fullTx bool) (map[string]interface{}, error) {
|
func (pea *PublicEthAPI) GetBlockByHash(ctx context.Context, hash common.Hash, fullTx bool) (map[string]interface{}, error) {
|
||||||
|
logrus.Debug("Received getBlockByHash request for hash ", hash.Hex())
|
||||||
block, err := pea.B.BlockByHash(ctx, hash)
|
block, err := pea.B.BlockByHash(ctx, hash)
|
||||||
if block != nil && err == nil {
|
if block != nil && err == nil {
|
||||||
return pea.rpcMarshalBlock(block, true, fullTx)
|
return pea.rpcMarshalBlock(block, true, fullTx)
|
||||||
@ -1095,13 +1096,13 @@ func (pea *PublicEthAPI) writeStateDiffFor(blockHash common.Hash) {
|
|||||||
func (pea *PublicEthAPI) rpcMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
|
func (pea *PublicEthAPI) rpcMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
|
||||||
fields, err := RPCMarshalBlock(b, inclTx, fullTx)
|
fields, err := RPCMarshalBlock(b, inclTx, fullTx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Error("error RPC marshalling block with hash", b.Hash().String(), err)
|
logrus.Errorf("error RPC marshalling block with hash %s: %s", b.Hash().String(), err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if inclTx {
|
if inclTx {
|
||||||
td, err := pea.B.GetTd(b.Hash())
|
td, err := pea.B.GetTd(b.Hash())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Error("error getting td for block with hash and number", b.Hash().String(), b.Number().String(), err)
|
logrus.Errorf("error getting td for block with hash and number %s, %s: %s", b.Hash().String(), b.Number().String(), err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
fields["totalDifficulty"] = (*hexutil.Big)(td)
|
fields["totalDifficulty"] = (*hexutil.Big)(td)
|
||||||
|
@ -334,6 +334,18 @@ var _ = Describe("API", func() {
|
|||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(block["baseFee"].(*big.Int)).To(Equal(baseFee))
|
Expect(block["baseFee"].(*big.Int)).To(Equal(baseFee))
|
||||||
})
|
})
|
||||||
|
It("Retrieves a block by number with uncles in correct order", func() {
|
||||||
|
block, err := api.GetBlockByNumber(ctx, londonBlockNum, false)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
expectedUncles := []common.Hash{
|
||||||
|
test_helpers.MockLondonUncles[0].Hash(),
|
||||||
|
test_helpers.MockLondonUncles[1].Hash(),
|
||||||
|
}
|
||||||
|
Expect(block["uncles"]).To(Equal(expectedUncles))
|
||||||
|
Expect(block["sha3Uncles"]).To(Equal(test_helpers.MockLondonBlock.UncleHash()))
|
||||||
|
Expect(block["hash"]).To(Equal(test_helpers.MockLondonBlock.Hash()))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
Describe("eth_getBlockByHash", func() {
|
Describe("eth_getBlockByHash", func() {
|
||||||
@ -375,6 +387,18 @@ var _ = Describe("API", func() {
|
|||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
Expect(block["baseFee"].(*big.Int)).To(Equal(baseFee))
|
Expect(block["baseFee"].(*big.Int)).To(Equal(baseFee))
|
||||||
})
|
})
|
||||||
|
It("Retrieves a block by hash with uncles in correct order", func() {
|
||||||
|
block, err := api.GetBlockByHash(ctx, test_helpers.MockLondonBlock.Hash(), false)
|
||||||
|
Expect(err).ToNot(HaveOccurred())
|
||||||
|
|
||||||
|
expectedUncles := []common.Hash{
|
||||||
|
test_helpers.MockLondonUncles[0].Hash(),
|
||||||
|
test_helpers.MockLondonUncles[1].Hash(),
|
||||||
|
}
|
||||||
|
Expect(block["uncles"]).To(Equal(expectedUncles))
|
||||||
|
Expect(block["sha3Uncles"]).To(Equal(test_helpers.MockLondonBlock.UncleHash()))
|
||||||
|
Expect(block["hash"]).To(Equal(test_helpers.MockLondonBlock.Hash()))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -366,6 +366,23 @@ func (b *Backend) BlockByHash(ctx context.Context, hash common.Hash) (*types.Blo
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When num. of uncles = 2,
|
||||||
|
// Check if calculated uncle hash matches the one in header
|
||||||
|
// If not, re-order the two uncles
|
||||||
|
// Assumption: Max num. of uncles in mainnet = 2
|
||||||
|
if len(uncles) == 2 {
|
||||||
|
uncleHash := types.CalcUncleHash(uncles)
|
||||||
|
if uncleHash != header.UncleHash {
|
||||||
|
uncles[0], uncles[1] = uncles[1], uncles[0]
|
||||||
|
|
||||||
|
uncleHash = types.CalcUncleHash(uncles)
|
||||||
|
// Check if uncle hash matches after re-ordering
|
||||||
|
if uncleHash != header.UncleHash {
|
||||||
|
log.Error("uncle hash mismatch for block hash: ", hash.Hex())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Fetch transactions
|
// Fetch transactions
|
||||||
transactions, err := b.GetTransactionsByBlockHash(tx, hash)
|
transactions, err := b.GetTransactionsByBlockHash(tx, hash)
|
||||||
if err != nil && err != sql.ErrNoRows {
|
if err != nil && err != sql.ErrNoRows {
|
||||||
|
@ -74,7 +74,8 @@ const (
|
|||||||
uncle_cids.mh_key = blocks.key
|
uncle_cids.mh_key = blocks.key
|
||||||
AND uncle_cids.block_number = blocks.block_number
|
AND uncle_cids.block_number = blocks.block_number
|
||||||
)
|
)
|
||||||
WHERE header_cids.block_hash = $1`
|
WHERE header_cids.block_hash = $1
|
||||||
|
ORDER BY uncle_cids.parent_hash`
|
||||||
RetrieveUnclesByBlockNumberPgStr = `SELECT uncle_cids.cid, data
|
RetrieveUnclesByBlockNumberPgStr = `SELECT uncle_cids.cid, data
|
||||||
FROM eth.uncle_cids
|
FROM eth.uncle_cids
|
||||||
INNER JOIN eth.header_cids ON (
|
INNER JOIN eth.header_cids ON (
|
||||||
|
@ -594,7 +594,29 @@ var (
|
|||||||
}
|
}
|
||||||
|
|
||||||
MockLondonTransactions, MockLondonReceipts, _ = createDynamicTransactionsAndReceipts(LondonBlockNum)
|
MockLondonTransactions, MockLondonReceipts, _ = createDynamicTransactionsAndReceipts(LondonBlockNum)
|
||||||
MockLondonBlock = createNewBlock(&MockLondonHeader, MockLondonTransactions, nil, MockLondonReceipts, new(trie.Trie))
|
MockLondonUncles = []*types.Header{
|
||||||
|
{
|
||||||
|
Time: 1,
|
||||||
|
Number: new(big.Int).Add(BlockNumber, big.NewInt(1)),
|
||||||
|
ParentHash: common.HexToHash("0x2"),
|
||||||
|
Root: common.HexToHash("0x1"),
|
||||||
|
TxHash: common.HexToHash("0x1"),
|
||||||
|
ReceiptHash: common.HexToHash("0x1"),
|
||||||
|
Difficulty: big.NewInt(500001),
|
||||||
|
Extra: []byte{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Time: 2,
|
||||||
|
Number: new(big.Int).Add(BlockNumber, big.NewInt(1)),
|
||||||
|
ParentHash: common.HexToHash("0x1"),
|
||||||
|
Root: common.HexToHash("0x2"),
|
||||||
|
TxHash: common.HexToHash("0x2"),
|
||||||
|
ReceiptHash: common.HexToHash("0x2"),
|
||||||
|
Difficulty: big.NewInt(500002),
|
||||||
|
Extra: []byte{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
MockLondonBlock = createNewBlock(&MockLondonHeader, MockLondonTransactions, MockLondonUncles, MockLondonReceipts, new(trie.Trie))
|
||||||
)
|
)
|
||||||
|
|
||||||
func createNewBlock(header *types.Header, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt, hasher types.TrieHasher) *types.Block {
|
func createNewBlock(header *types.Header, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt, hasher types.TrieHasher) *types.Block {
|
||||||
|
Loading…
Reference in New Issue
Block a user