Skip to content

Commit

Permalink
Switch to Blake3 from ProgPow
Browse files Browse the repository at this point in the history
  • Loading branch information
wizeguyy committed Jun 21, 2023
1 parent 90497f3 commit 4dfc811
Show file tree
Hide file tree
Showing 56 changed files with 3,692 additions and 304 deletions.
2 changes: 1 addition & 1 deletion build/update-license.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ var (
"cmd/internal/browser",
"common/bitutil/bitutil",
"common/prque/",
"consensus/blake3pow/xor.go",
"consensus/progpow/xor.go",
"crypto/bn256/",
"crypto/ecies/",
"log/",
Expand Down
24 changes: 12 additions & 12 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import (
"github.com/dominant-strategies/go-quai/common"
"github.com/dominant-strategies/go-quai/common/fdlimit"
"github.com/dominant-strategies/go-quai/consensus"
"github.com/dominant-strategies/go-quai/consensus/blake3pow"
"github.com/dominant-strategies/go-quai/consensus/progpow"
"github.com/dominant-strategies/go-quai/core"
"github.com/dominant-strategies/go-quai/core/rawdb"
"github.com/dominant-strategies/go-quai/core/vm"
Expand Down Expand Up @@ -1177,23 +1177,23 @@ func setTxPool(ctx *cli.Context, cfg *core.TxPoolConfig) {
}
}

func setBlake3pow(ctx *cli.Context, cfg *ethconfig.Config) {
func setProgpow(ctx *cli.Context, cfg *ethconfig.Config) {
// Override any default configs for hard coded networks.
switch {
case ctx.GlobalBool(ColosseumFlag.Name):
cfg.Blake3pow.DurationLimit = params.DurationLimit
cfg.Progpow.DurationLimit = params.DurationLimit
case ctx.GlobalBool(GardenFlag.Name):
cfg.Blake3pow.DurationLimit = params.GardenDurationLimit
cfg.Progpow.DurationLimit = params.GardenDurationLimit
case ctx.GlobalBool(OrchardFlag.Name):
cfg.Blake3pow.DurationLimit = params.OrchardDurationLimit
cfg.Progpow.DurationLimit = params.OrchardDurationLimit
case ctx.GlobalBool(GalenaFlag.Name):
cfg.Blake3pow.DurationLimit = params.GalenaDurationLimit
cfg.Progpow.DurationLimit = params.GalenaDurationLimit
case ctx.GlobalBool(LocalFlag.Name):
cfg.Blake3pow.DurationLimit = params.LocalDurationLimit
cfg.Progpow.DurationLimit = params.LocalDurationLimit
case ctx.GlobalBool(DeveloperFlag.Name):
cfg.Blake3pow.DurationLimit = params.DurationLimit
cfg.Progpow.DurationLimit = params.DurationLimit
default:
cfg.Blake3pow.DurationLimit = params.DurationLimit
cfg.Progpow.DurationLimit = params.DurationLimit

}
}
Expand Down Expand Up @@ -1294,7 +1294,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
}
setGPO(ctx, &cfg.GPO, ctx.GlobalString(SyncModeFlag.Name) == "light")
setTxPool(ctx, &cfg.TxPool)
setBlake3pow(ctx, cfg)
setProgpow(ctx, cfg)
setWhitelist(ctx, cfg)

// set the dominant chain websocket url
Expand Down Expand Up @@ -1592,9 +1592,9 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (*core.Core, ethdb.Database)
}
var engine consensus.Engine

engine = blake3pow.NewFaker()
engine = progpow.NewFaker()
if !ctx.GlobalBool(FakePoWFlag.Name) {
engine = blake3pow.New(blake3pow.Config{}, nil, false)
engine = progpow.New(progpow.Config{}, nil, false)
}
if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
Expand Down
18 changes: 9 additions & 9 deletions consensus/blake3pow/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ func (blake3pow *Blake3pow) verifyHeader(chain consensus.ChainHeaderReader, head
}
}

order, err := header.CalcOrder()
_, order, err := blake3pow.CalcOrder(header)
if err != nil {
return err
}
Expand All @@ -266,21 +266,21 @@ func (blake3pow *Blake3pow) verifyHeader(chain consensus.ChainHeaderReader, head
}

// Verify that the parent entropy is calculated correctly on the header
parentEntropy := parent.CalcS()
parentEntropy := blake3pow.TotalLogS(parent)
if parentEntropy.Cmp(header.ParentEntropy()) != 0 {
return fmt.Errorf("invalid parent entropy: have %v, want %v", header.ParentEntropy(), parentEntropy)
}

// If not prime, verify the parentDeltaS field as well
if nodeCtx > common.PRIME_CTX {
parentOrder, _ := parent.CalcOrder()
_, parentOrder, _ := blake3pow.CalcOrder(parent)
// If parent was dom, deltaS is zero and otherwise should be the calc delta s on the parent
if parentOrder < nodeCtx {
if common.Big0.Cmp(header.ParentDeltaS()) != 0 {
return fmt.Errorf("invalid parent delta s: have %v, want %v", header.ParentDeltaS(), common.Big0)
}
} else {
parentDeltaS := parent.CalcDeltaS()
parentDeltaS := blake3pow.DeltaLogS(parent)
if parentDeltaS.Cmp(header.ParentDeltaS()) != 0 {
return fmt.Errorf("invalid parent delta s: have %v, want %v", header.ParentDeltaS(), parentDeltaS)
}
Expand Down Expand Up @@ -319,7 +319,7 @@ func (blake3pow *Blake3pow) verifyHeader(chain consensus.ChainHeaderReader, head
}
// Verify the engine specific seal securing the block
if seal {
if err := blake3pow.verifySeal(chain, header, false); err != nil {
if err := blake3pow.verifySeal(header, false); err != nil {
return err
}
}
Expand Down Expand Up @@ -381,8 +381,8 @@ func (blake3pow *Blake3pow) CalcDifficulty(chain consensus.ChainHeaderReader, pa
return x
}

func (blake3pow *Blake3pow) IsDomCoincident(header *types.Header) bool {
order, err := header.CalcOrder()
func (blake3pow *Blake3pow) IsDomCoincident(chain consensus.ChainHeaderReader, header *types.Header) bool {
order, err := blake3pow.CalcOrder(header)
if err != nil {
return false
}
Expand All @@ -392,7 +392,7 @@ func (blake3pow *Blake3pow) IsDomCoincident(header *types.Header) bool {
// verifySeal checks whether a block satisfies the PoW difficulty requirements,
// either using the usual blake3pow cache for it, or alternatively using a full DAG
// to make remote mining fast.
func (blake3pow *Blake3pow) verifySeal(chain consensus.ChainHeaderReader, header *types.Header, fulldag bool) error {
func (blake3pow *Blake3pow) verifySeal(header *types.Header) error {
// If we're running a fake PoW, accept any seal as valid
if blake3pow.config.PowMode == ModeFake || blake3pow.config.PowMode == ModeFullFake {
time.Sleep(blake3pow.fakeDelay)
Expand All @@ -403,7 +403,7 @@ func (blake3pow *Blake3pow) verifySeal(chain consensus.ChainHeaderReader, header
}
// If we're running a shared PoW, delegate verification to it
if blake3pow.shared != nil {
return blake3pow.shared.verifySeal(chain, header, fulldag)
return blake3pow.shared.verifySeal(chain, header)
}
// Ensure that we have a valid difficulty for the block
if header.Difficulty().Sign() <= 0 {
Expand Down
125 changes: 125 additions & 0 deletions consensus/blake3pow/poem.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package blake3pow

import (
"math/big"

"github.com/dominant-strategies/go-quai/common"
"github.com/dominant-strategies/go-quai/core/types"
"github.com/dominant-strategies/go-quai/params"
"modernc.org/mathutil"
)

// CalcOrder returns the order of the block within the hierarchy of chains
func (blake3pow *Blake3pow) CalcOrder(header *types.Header) (*big.Int, int, error) {
// Verify the seal and get the powHash for the given header
powHash, err := blake3pow.verifySeal(header)
if err != nil {
return big0, -1, err
}

// Get entropy reduction of this header
intrinsicS := blake3pow.IntrinsicLogS(powHash)

// This is the updated the threshold calculation based on the zone difficulty threshold
target := new(big.Int).Div(big2e256, header.Difficulty()).Bytes()
zoneThresholdS := blake3pow.IntrinsicLogS(common.BytesToHash(target))
timeFactorHierarchyDepthMultiple := new(big.Int).Mul(params.TimeFactor, big.NewInt(common.HierarchyDepth))

// Prime case
primeEntropyThreshold := new(big.Int).Mul(timeFactorHierarchyDepthMultiple, timeFactorHierarchyDepthMultiple)
primeEntropyThreshold = new(big.Int).Mul(primeEntropyThreshold, zoneThresholdS)
primeBlockThreshold := new(big.Int).Quo(primeEntropyThreshold, big.NewInt(2))
primeEntropyThreshold = new(big.Int).Sub(primeEntropyThreshold, primeBlockThreshold)

primeBlockEntropyThresholdAdder, _ := mathutil.BinaryLog(primeBlockThreshold, 8)
primeBlockEntropyThreshold := new(big.Int).Add(zoneThresholdS, big.NewInt(int64(primeBlockEntropyThresholdAdder)))

totalDeltaS := new(big.Int).Add(header.ParentDeltaS(common.REGION_CTX), header.ParentDeltaS(common.ZONE_CTX))
totalDeltaS.Add(totalDeltaS, intrinsicS)
if intrinsicS.Cmp(primeBlockEntropyThreshold) > 0 && totalDeltaS.Cmp(primeEntropyThreshold) > 0 {
return intrinsicS, common.PRIME_CTX, nil
}

// Region case
regionEntropyThreshold := new(big.Int).Mul(timeFactorHierarchyDepthMultiple, zoneThresholdS)
regionBlockThreshold := new(big.Int).Quo(regionEntropyThreshold, big.NewInt(2))
regionEntropyThreshold = new(big.Int).Sub(regionEntropyThreshold, regionBlockThreshold)

regionBlockEntropyThresholdAdder, _ := mathutil.BinaryLog(regionBlockThreshold, 8)
regionBlockEntropyThreshold := new(big.Int).Add(zoneThresholdS, big.NewInt(int64(regionBlockEntropyThresholdAdder)))

totalDeltaS = new(big.Int).Add(header.ParentDeltaS(common.ZONE_CTX), intrinsicS)
if intrinsicS.Cmp(regionBlockEntropyThreshold) > 0 && totalDeltaS.Cmp(regionEntropyThreshold) > 0 {
return intrinsicS, common.REGION_CTX, nil
}

return intrinsicS, common.ZONE_CTX, nil
}

// IntrinsicLogS returns the logarithm of the intrinsic entropy reduction of a PoW hash
func (blake3pow *Blake3pow) IntrinsicLogS(powHash common.Hash) *big.Int {
x := new(big.Int).SetBytes(powHash.Bytes())
d := new(big.Int).Div(big2e256, x)
c, m := mathutil.BinaryLog(d, mantBits)
bigBits := new(big.Int).Mul(big.NewInt(int64(c)), new(big.Int).Exp(big.NewInt(2), big.NewInt(mantBits), nil))
bigBits = new(big.Int).Add(bigBits, m)
return bigBits
}

// TotalLogS() returns the total entropy reduction if the chain since genesis to the given header
func (blake3pow *Blake3pow) TotalLogS(header *types.Header) *big.Int {
intrinsicS, order, err := blake3pow.CalcOrder(header)
if err != nil {
return big.NewInt(0)
}
switch order {
case common.PRIME_CTX:
totalS := new(big.Int).Add(header.ParentEntropy(common.PRIME_CTX), header.ParentDeltaS(common.REGION_CTX))
totalS.Add(totalS, header.ParentDeltaS(common.ZONE_CTX))
totalS.Add(totalS, intrinsicS)
return totalS
case common.REGION_CTX:
totalS := new(big.Int).Add(header.ParentEntropy(common.REGION_CTX), header.ParentDeltaS(common.ZONE_CTX))
totalS.Add(totalS, intrinsicS)
return totalS
case common.ZONE_CTX:
totalS := new(big.Int).Add(header.ParentEntropy(common.ZONE_CTX), intrinsicS)
return totalS
}
return big.NewInt(0)
}

func (blake3pow *Blake3pow) TotalLogPhS(header *types.Header) *big.Int {
switch common.NodeLocation.Context() {
case common.PRIME_CTX:
totalS := header.ParentEntropy(common.PRIME_CTX)
return totalS
case common.REGION_CTX:
totalS := new(big.Int).Add(header.ParentEntropy(common.PRIME_CTX), header.ParentDeltaS(common.REGION_CTX))
return totalS
case common.ZONE_CTX:
totalS := new(big.Int).Add(header.ParentEntropy(common.PRIME_CTX), header.ParentDeltaS(common.REGION_CTX))
totalS.Add(totalS, header.ParentDeltaS(common.ZONE_CTX))
return totalS
}
return big.NewInt(0)
}

func (blake3pow *Blake3pow) DeltaLogS(header *types.Header) *big.Int {
intrinsicS, order, err := blake3pow.CalcOrder(header)
if err != nil {
return big.NewInt(0)
}
switch order {
case common.PRIME_CTX:
return big.NewInt(0)
case common.REGION_CTX:
totalDeltaS := new(big.Int).Add(header.ParentDeltaS(common.REGION_CTX), header.ParentDeltaS(common.ZONE_CTX))
totalDeltaS = new(big.Int).Add(totalDeltaS, intrinsicS)
return totalDeltaS
case common.ZONE_CTX:
totalDeltaS := new(big.Int).Add(header.ParentDeltaS(common.ZONE_CTX), intrinsicS)
return totalDeltaS
}
return big.NewInt(0)
}
1 change: 1 addition & 0 deletions consensus/blake3pow/sealer.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
const (
// staleThreshold is the maximum depth of the acceptable stale but valid blake3pow solution.
staleThreshold = 7
mantBits = 64
)

var (
Expand Down
17 changes: 16 additions & 1 deletion consensus/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,21 @@ type Engine interface {
// engine is based on signatures.
Author(header *types.Header) (common.Address, error)

// IntrinsicLogS returns the logarithm of the intrinsic entropy reduction of a PoW hash
IntrinsicLogS(powHash common.Hash) *big.Int

// CalcOrder returns the order of the block within the hierarchy of chains
CalcOrder(header *types.Header) (*big.Int, int, error)

// TotalLogS returns the log of the total entropy reduction if the chain since genesis to the given header
TotalLogS(header *types.Header) *big.Int

// TotalLogPhS returns the log of the total entropy reduction if the chain since genesis for a pending header
TotalLogPhS(header *types.Header) *big.Int

// DeltaLogS returns the log of the entropy delta for a chain since its prior coincidence
DeltaLogS(header *types.Header) *big.Int

// VerifyHeader checks whether a header conforms to the consensus rules of a
// given engine. Verifying the seal may be done optionally here, or explicitly
// via the VerifySeal method.
Expand Down Expand Up @@ -113,7 +128,7 @@ type Engine interface {
//
// Importantly, this check does NOT mean the block is canonical in the
// dominant chain, or even that the claimed dominant difficulty is valid.
IsDomCoincident(header *types.Header) bool
IsDomCoincident(chain ChainHeaderReader, header *types.Header) bool

// APIs returns the RPC APIs this consensus engine provides.
APIs(chain ChainHeaderReader) []rpc.API
Expand Down
2 changes: 1 addition & 1 deletion consensus/misc/basefee_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import (
func copyConfig(original *params.ChainConfig) *params.ChainConfig {
return &params.ChainConfig{
ChainID: original.ChainID,
Blake3pow: original.Blake3pow,
Progpow: original.Progpow,
}
}

Expand Down
Loading

0 comments on commit 4dfc811

Please sign in to comment.