eth: monitor malicious header retrieval requests
This commit is contained in:
parent
a7cc3248fe
commit
e482b5694f
@ -17,6 +17,7 @@
|
|||||||
package eth
|
package eth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
@ -371,14 +372,24 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
|||||||
}
|
}
|
||||||
case query.Origin.Hash != (common.Hash{}) && !query.Reverse:
|
case query.Origin.Hash != (common.Hash{}) && !query.Reverse:
|
||||||
// Hash based traversal towards the leaf block
|
// Hash based traversal towards the leaf block
|
||||||
if header := pm.blockchain.GetHeaderByNumber(origin.Number.Uint64() + query.Skip + 1); header != nil {
|
var (
|
||||||
if pm.blockchain.GetBlockHashesFromHash(header.Hash(), query.Skip+1)[query.Skip] == query.Origin.Hash {
|
current = origin.Number.Uint64()
|
||||||
query.Origin.Hash = header.Hash()
|
next = current + query.Skip + 1
|
||||||
|
)
|
||||||
|
if next <= current {
|
||||||
|
infos, _ := json.MarshalIndent(p.Peer.Info(), "", " ")
|
||||||
|
glog.V(logger.Warn).Infof("%v: GetBlockHeaders skip overflow attack (current %v, skip %v, next %v)\nMalicious peer infos: %s", p, current, query.Skip, next, infos)
|
||||||
|
unknown = true
|
||||||
|
} else {
|
||||||
|
if header := pm.blockchain.GetHeaderByNumber(next); header != nil {
|
||||||
|
if pm.blockchain.GetBlockHashesFromHash(header.Hash(), query.Skip+1)[query.Skip] == query.Origin.Hash {
|
||||||
|
query.Origin.Hash = header.Hash()
|
||||||
|
} else {
|
||||||
|
unknown = true
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
unknown = true
|
unknown = true
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
unknown = true
|
|
||||||
}
|
}
|
||||||
case query.Reverse:
|
case query.Reverse:
|
||||||
// Number based traversal towards the genesis block
|
// Number based traversal towards the genesis block
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
package eth
|
package eth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"testing"
|
"testing"
|
||||||
@ -173,6 +174,20 @@ func testGetBlockHeaders(t *testing.T, protocol int) {
|
|||||||
pm.blockchain.GetBlockByNumber(0).Hash(),
|
pm.blockchain.GetBlockByNumber(0).Hash(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
// Check a corner case where skipping overflow loops back into the chain start
|
||||||
|
{
|
||||||
|
&getBlockHeadersData{Origin: hashOrNumber{Hash: pm.blockchain.GetBlockByNumber(3).Hash()}, Amount: 2, Reverse: false, Skip: math.MaxUint64 - 1},
|
||||||
|
[]common.Hash{
|
||||||
|
pm.blockchain.GetBlockByNumber(3).Hash(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Check a corner case where skipping overflow loops back to the same header
|
||||||
|
{
|
||||||
|
&getBlockHeadersData{Origin: hashOrNumber{Hash: pm.blockchain.GetBlockByNumber(1).Hash()}, Amount: 2, Reverse: false, Skip: math.MaxUint64},
|
||||||
|
[]common.Hash{
|
||||||
|
pm.blockchain.GetBlockByNumber(1).Hash(),
|
||||||
|
},
|
||||||
|
},
|
||||||
// Check that non existing headers aren't returned
|
// Check that non existing headers aren't returned
|
||||||
{
|
{
|
||||||
&getBlockHeadersData{Origin: hashOrNumber{Hash: unknown}, Amount: 1},
|
&getBlockHeadersData{Origin: hashOrNumber{Hash: unknown}, Amount: 1},
|
||||||
|
Loading…
Reference in New Issue
Block a user