From 48d590093eed801d1d38548a59579bb24f214bc9 Mon Sep 17 00:00:00 2001 From: Sammy Libre Date: Tue, 5 Jan 2016 17:32:53 +0500 Subject: [PATCH] Add ethash.VerifyWithTarget to get target along with share validation result --- ethash.go | 16 +++++++++++----- ethash_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/ethash.go b/ethash.go index 2199dbec..cdb22578 100644 --- a/ethash.go +++ b/ethash.go @@ -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() @@ -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) @@ -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. @@ -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 { diff --git a/ethash_test.go b/ethash_test.go index e0ca0bd8..9e8407a0 100644 --- a/ethash_test.go +++ b/ethash_test.go @@ -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 { @@ -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) {