Skip to content
This repository has been archived by the owner on Dec 17, 2024. It is now read-only.

Add ethash.VerifyWithTarget to get target along with share validation… #78

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions ethash.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,17 @@ type Light struct {

// Verify checks whether the block's nonce is valid.
func (l *Light) Verify(block pow.Block) bool {
result, _ := l.VerifyWithTarget(block)
return result
}

func (l *Light) VerifyWithTarget(block pow.Block) (bool, *big.Int) {
// TODO: do ethash_quick_verify before getCache in order
// to prevent DOS attacks.
blockNum := block.NumberU64()
if blockNum >= epochLength*2048 {
glog.V(logger.Debug).Infof("block number %d too high, limit is %d", epochLength*2048)
return false
return false, nil
}

difficulty := block.Difficulty()
Expand All @@ -132,7 +137,7 @@ func (l *Light) Verify(block pow.Block) bool {
*/
if difficulty.Cmp(common.Big0) == 0 {
glog.V(logger.Debug).Infof("invalid block difficulty")
return false
return false, nil
}

cache := l.getCache(blockNum)
Expand All @@ -145,12 +150,12 @@ func (l *Light) Verify(block pow.Block) bool {
hash := hashToH256(block.HashNoNonce())
ret := C.ethash_light_compute_internal(cache.ptr, dagSize, hash, C.uint64_t(block.Nonce()))
if !ret.success {
return false
return false, nil
}

// avoid mixdigest malleability as it's not included in a block's "hashNononce"
if block.MixDigest() != h256ToHash(ret.mix_hash) {
return false
return false, nil
}

// Make sure cache is live until after the C call.
Expand All @@ -159,7 +164,8 @@ func (l *Light) Verify(block pow.Block) bool {
_ = cache
// The actual check.
target := new(big.Int).Div(maxUint256, difficulty)
return h256ToHash(ret.result).Big().Cmp(target) <= 0
blockTarget := h256ToHash(ret.result).Big()
return blockTarget.Cmp(target) <= 0, blockTarget
}

func h256ToHash(in C.ethash_h256_t) common.Hash {
Expand Down
25 changes: 25 additions & 0 deletions ethash_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,20 @@ var invalidZeroDiffBlock = testBlock{
mixDigest: crypto.Sha3Hash([]byte("bar")),
}

func TestEthashVerifyValidWithTarget(t *testing.T) {
eth := New()
for i, block := range validBlocks {
isValid, target := eth.VerifyWithTarget(block)
if !isValid {
t.Errorf("block %d (%x) did not validate.", i, block.hashNoNonce[:6])
}
blockTarget := new(big.Int).Div(maxUint256, block.Difficulty())
if target.Cmp(blockTarget) >= 0 {
t.Errorf("target should be greater than or equal to")
}
}
}

func TestEthashVerifyValid(t *testing.T) {
eth := New()
for i, block := range validBlocks {
Expand All @@ -94,6 +108,17 @@ func TestEthashVerifyValid(t *testing.T) {
}
}

func TestEthashVerifyWithTargetInvalid(t *testing.T) {
eth := New()
isValid, diff := eth.VerifyWithTarget(&invalidZeroDiffBlock)
if isValid {
t.Errorf("should not validate - we just ensure it does not panic on this block")
}
if diff != nil {
t.Errorf("target should be nil for invalid block")
}
}

func TestEthashVerifyInvalid(t *testing.T) {
eth := New()
if eth.Verify(&invalidZeroDiffBlock) {
Expand Down