Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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