Skip to content

Commit

Permalink
refactor: count difficulty; bit resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
bryanchriswhite committed Nov 16, 2023
1 parent 4e66081 commit a1d18ce
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 10 deletions.
4 changes: 2 additions & 2 deletions pkg/relayer/miner/miner.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ var (
// TODO_BLOCKER: query on-chain governance params once available.
// Setting this to 0 to effectively disables mining for now.
// I.e., all relays are added to the tree.
defaultRelayDifficulty = 0
defaultRelayDifficultyBits = 0
)

// Miner is responsible for observing servedRelayObs, hashing and checking the
Expand Down Expand Up @@ -102,7 +102,7 @@ func (mnr *miner) mapMineRelay(
relayHash := mnr.hash(relayBz)

// The relay IS NOT volume / reward applicable
if !protocol.BytesDifficultyGreaterThan(relayHash, defaultRelayDifficulty) {
if protocol.MustCountDifficultyBits(relayHash) >= defaultRelayDifficultyBits {
return either.Success[*relayer.MinedRelay](nil), true
}

Expand Down
39 changes: 31 additions & 8 deletions pkg/relayer/protocol/difficulty.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,40 @@
package protocol

import (
"encoding/hex"
"strings"
"math/bits"
)

// TODO_BLOCKER: Revisit this part of the algorithm after initial TestNet Launch.
// TODO_TEST: Add extensive tests for the core relay mining business logic.
// BytesDifficultyGreaterThan determines if the bytes exceed a certain difficulty, and it
// is used to determine if a relay is volume applicable. See the spec for more details: https://github.com/pokt-network/pocket-network-protocol
func BytesDifficultyGreaterThan(bz []byte, compDifficultyBytes int) bool {
hexZerosPrefix := strings.Repeat("0", compDifficultyBytes*2) // 2 hex chars per byte.
hexBz := hex.EncodeToString(bz)

return strings.HasPrefix(hexBz, hexZerosPrefix)
// MustCountDifficultyBits returns the number of leading zero bits in the given
// byte slice. It panics if an error is encountered.
func MustCountDifficultyBits(bz []byte) int {
diff, err := CountDifficultyBits(bz)
if err != nil {
panic(err)
}

return diff
}

// CountDifficultyBits returns the number of leading zero bits in the given byte
// slice. It returns an error if the byte slice is all zero bits.
func CountDifficultyBits(bz []byte) (int, error) {
bzLen := len(bz)

var zeroBits int
for i, b := range bz {
if b != 0 {
zeroBits = bits.LeadingZeros8(b)
if zeroBits == 8 {
// we already checked that b != 0.
return 0, ErrDifficulty.Wrap("impossible code path")
}

return (i)*8 + zeroBits, nil
}
}

return 0, ErrDifficulty.Wrapf("difficulty matches bytes length: %d; bytes (hex): % x", bzLen, bz)
}
8 changes: 8 additions & 0 deletions pkg/relayer/protocol/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package protocol

import errorsmod "cosmossdk.io/errors"

var (
ErrDifficulty = errorsmod.New(codespace, 1, "difficulty error")
codespace = "relayer/protocol"
)

0 comments on commit a1d18ce

Please sign in to comment.