Skip to content

Commit

Permalink
Merge pull request #47 from okilisan/2024_testnet_1_fishhashplus
Browse files Browse the repository at this point in the history
Fishhash plus implementation with hard fork procedure
  • Loading branch information
lemois-1337 committed Mar 21, 2024
2 parents b9c6d1a + cd5888a commit 1b6644b
Show file tree
Hide file tree
Showing 15 changed files with 148 additions and 22 deletions.
3 changes: 3 additions & 0 deletions app/protocol/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ func (m *Manager) AddTransaction(tx *externalapi.DomainTransaction, allowOrphan

// AddBlock adds the given block to the DAG and propagates it.
func (m *Manager) AddBlock(block *externalapi.DomainBlock) error {
//TODO switch this to debug level
log.Infof("NEW BLOCK ADDED ***************************************")
log.Infof("BlueWork[%s] BlueScore[%d] DAAScore[%d] Bits[%d] Version[%d]", block.Header.BlueWork(), block.Header.BlueScore(), block.Header.DAAScore(), block.Header.Bits(), block.Header.Version())
return m.context.AddBlock(block)
}

Expand Down
2 changes: 2 additions & 0 deletions domain/consensus/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ func (f *factory) NewConsensus(config *Config, db infrastructuredatabase.Databas
config.MaxBlockParents,
config.TimestampDeviationTolerance,
config.TargetTimePerBlock,
config.HFDAAScore,
config.MaxBlockLevel,

dbManager,
Expand Down Expand Up @@ -397,6 +398,7 @@ func (f *factory) NewConsensus(config *Config, db infrastructuredatabase.Databas
blockBuilder := blockbuilder.New(
dbManager,
genesisHash,
config.HFDAAScore,

difficultyManager,
pastMedianTimeManager,
Expand Down
10 changes: 9 additions & 1 deletion domain/consensus/processes/blockbuilder/block_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
type blockBuilder struct {
databaseContext model.DBManager
genesisHash *externalapi.DomainHash
hfDAAScore uint64

difficultyManager model.DifficultyManager
pastMedianTimeManager model.PastMedianTimeManager
Expand All @@ -42,6 +43,7 @@ type blockBuilder struct {
func New(
databaseContext model.DBManager,
genesisHash *externalapi.DomainHash,
hfDAAScore uint64,

difficultyManager model.DifficultyManager,
pastMedianTimeManager model.PastMedianTimeManager,
Expand All @@ -63,6 +65,7 @@ func New(
return &blockBuilder{
databaseContext: databaseContext,
genesisHash: genesisHash,
hfDAAScore: hfDAAScore,

difficultyManager: difficultyManager,
pastMedianTimeManager: pastMedianTimeManager,
Expand Down Expand Up @@ -225,8 +228,13 @@ func (bb *blockBuilder) buildHeader(stagingArea *model.StagingArea, transactions
return nil, err
}

version := constants.BlockVersionBeforeHF
if daaScore >= bb.hfDAAScore {
version = constants.BlockVersionAfterHF
}

return blockheader.NewImmutableBlockHeader(
constants.BlockVersion,
version,
parents,
hashMerkleRoot,
acceptedIDMerkleRoot,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,14 @@ func (bb *testBlockBuilder) buildUTXOInvalidHeader(stagingArea *model.StagingAre
})
}

version := constants.BlockVersionBeforeHF
if daaScore >= bb.hfDAAScore {
version = constants.BlockVersionAfterHF
}

bb.nonceCounter++
return blockheader.NewImmutableBlockHeader(
constants.BlockVersion,
version,
parents,
hashMerkleRoot,
&externalapi.DomainHash{},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1280,7 +1280,7 @@ func initBlockWithFirstTransactionDifferentThanCoinbase(consensusConfig *consens

return &externalapi.DomainBlock{
Header: blockheader.NewImmutableBlockHeader(
constants.BlockVersion,
constants.BlockVersionBeforeHF,
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{consensusConfig.GenesisHash}},
merkle.CalculateHashMerkleRoot([]*externalapi.DomainTransaction{tx}),
&externalapi.DomainHash{},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,10 @@ func TestCheckParentsIncest(t *testing.T) {
t.Fatalf("AddBlock: %+v", err)
}

version := constants.BlockVersion
version := constants.BlockVersionBeforeHF
if consensusConfig.HFDAAScore == 0 {
version = constants.BlockVersionAfterHF
}
directParentsRelationBlock := &externalapi.DomainBlock{
Header: blockheader.NewImmutableBlockHeader(
version,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,22 @@ func (v *blockValidator) checkParentsLimit(header externalapi.BlockHeader) error
}

func (v *blockValidator) checkBlockVersion(header externalapi.BlockHeader) error {
if header.Version() != constants.BlockVersion {
return errors.Wrapf(
ruleerrors.ErrWrongBlockVersion, "The block version should be %d", constants.BlockVersion)
/*
if header.Version() != constants.BlockVersion {
return errors.Wrapf(
ruleerrors.ErrWrongBlockVersion, "The block version should be %d", constants.BlockVersion)
}
*/
if header.DAAScore() >= v.hfDAAScore {
if header.Version() != constants.BlockVersionAfterHF {
return errors.Wrapf(
ruleerrors.ErrWrongBlockVersion, "After HF1 the block version should be %d", constants.BlockVersionAfterHF)
}
} else {
if header.Version() != constants.BlockVersionBeforeHF {
return errors.Wrapf(
ruleerrors.ErrWrongBlockVersion, "Beofre HF1 the block version should be %d", constants.BlockVersionBeforeHF)
}
}
return nil
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,11 @@ func CheckBlockVersion(t *testing.T, tc testapi.TestConsensus, consensusConfig *
t.Fatalf("BuildBlockWithParents: %+v", err)
}

expectedVersion := constants.BlockVersion
expectedVersion := constants.BlockVersionBeforeHF
if consensusConfig.HFDAAScore == 0 {
expectedVersion = constants.BlockVersionAfterHF
}

block.Header = blockheader.NewImmutableBlockHeader(
expectedVersion+1,
block.Header.Parents(),
Expand Down
3 changes: 3 additions & 0 deletions domain/consensus/processes/blockvalidator/blockvalidator.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type blockValidator struct {
maxBlockParents externalapi.KType
timestampDeviationTolerance int
targetTimePerBlock time.Duration
hfDAAScore uint64
maxBlockLevel int

databaseContext model.DBReader
Expand Down Expand Up @@ -63,6 +64,7 @@ func New(powMax *big.Int,
maxBlockParents externalapi.KType,
timestampDeviationTolerance int,
targetTimePerBlock time.Duration,
hfDAAScore uint64,
maxBlockLevel int,

databaseContext model.DBReader,
Expand Down Expand Up @@ -102,6 +104,7 @@ func New(powMax *big.Int,
maxBlockMass: maxBlockMass,
mergeSetSizeLimit: mergeSetSizeLimit,
maxBlockParents: maxBlockParents,
hfDAAScore: hfDAAScore,
maxBlockLevel: maxBlockLevel,

timestampDeviationTolerance: timestampDeviationTolerance,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func TestGHOSTDAG(t *testing.T) {
blockID := StringToDomainHash(testBlockData.ID)
dagTopology.parentsMap[*blockID] = StringToDomainHashSlice(testBlockData.Parents)
blockHeadersStore.dagMap[*blockID] = blockheader.NewImmutableBlockHeader(
constants.BlockVersion,
constants.BlockVersionBeforeHF,
[]externalapi.BlockLevelParents{StringToDomainHashSlice(testBlockData.Parents)},
nil,
nil,
Expand Down
3 changes: 2 additions & 1 deletion domain/consensus/utils/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import "math"

const (
// BlockVersion represents the current block version
BlockVersion uint16 = 1
BlockVersionBeforeHF uint16 = 1
BlockVersionAfterHF uint16 = 2

// MaxTransactionVersion is the current latest supported transaction version.
MaxTransactionVersion uint16 = 0
Expand Down
71 changes: 71 additions & 0 deletions domain/consensus/utils/pow/fishhashplus_kernel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package pow

import (
"github.com/karlsen-network/karlsend/domain/consensus/model/externalapi"

//"crypto/sha3"
"encoding/binary"
)

func fishhashPlusKernel(ctx *fishhashContext, seed hash512) hash256 {
indexLimit := uint32(ctx.FullDatasetNumItems)
mix := mergeHashes(seed, seed)

//log.Debugf("lookup matrix : ")
for i := uint32(0); i < numDatasetAccesses; i++ {

mixGroup := [8]uint32{}
for c := uint32(0); c < 8; c++ {
mixGroup[c] = binary.LittleEndian.Uint32(mix[(4*4*c+0):]) ^ binary.LittleEndian.Uint32(mix[(4*4*c+4):]) ^ binary.LittleEndian.Uint32(mix[(4*4*c+8):]) ^ binary.LittleEndian.Uint32(mix[(4*4*c+12):])
}

p0 := (mixGroup[0] ^ mixGroup[3] ^ mixGroup[6]) % indexLimit
p1 := (mixGroup[1] ^ mixGroup[4] ^ mixGroup[7]) % indexLimit
p2 := (mixGroup[2] ^ mixGroup[5] ^ i) % indexLimit

fetch0 := lookup(ctx, p0)
fetch1 := lookup(ctx, p1)
fetch2 := lookup(ctx, p2)

for j := 0; j < 32; j++ {
binary.LittleEndian.PutUint32(
fetch1[4*j:],
fnv1(binary.LittleEndian.Uint32(mix[4*j:4*j+4]), binary.LittleEndian.Uint32(fetch1[4*j:4*j+4])))
binary.LittleEndian.PutUint32(
fetch2[4*j:],
binary.LittleEndian.Uint32(mix[4*j:4*j+4])^binary.LittleEndian.Uint32(fetch2[4*j:4*j+4]))
}

//fmt.Printf("The NEW fetch1 is : %x \n", fetch1)
//fmt.Printf("The NEW fetch2 is : %x \n", fetch2)

for j := 0; j < 16; j++ {
binary.LittleEndian.PutUint64(
mix[8*j:],
binary.LittleEndian.Uint64(fetch0[8*j:8*j+8])*binary.LittleEndian.Uint64(fetch1[8*j:8*j+8])+binary.LittleEndian.Uint64(fetch2[8*j:8*j+8]))
}
//log.Debugf("\n")
}

mixHash := hash256{}
for i := 0; i < (len(mix) / 4); i += 4 {
j := 4 * i
h1 := fnv1(binary.LittleEndian.Uint32(mix[j:]), binary.LittleEndian.Uint32(mix[j+4:]))
h2 := fnv1(h1, binary.LittleEndian.Uint32(mix[j+8:]))
h3 := fnv1(h2, binary.LittleEndian.Uint32(mix[j+12:]))
binary.LittleEndian.PutUint32(mixHash[i:], h3)
}

return mixHash
}

func fishHashPlus(ctx *fishhashContext, hashin *externalapi.DomainHash) *externalapi.DomainHash {

seed := hash512{}
copy(seed[:], hashin.ByteSlice())

output := fishhashPlusKernel(ctx, seed)
outputArray := [32]byte{}
copy(outputArray[:], output[:])
return externalapi.NewDomainHashFromByteArray(&outputArray)
}
32 changes: 21 additions & 11 deletions domain/consensus/utils/pow/pow.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
"math/big"
)

const hashingAlgoVersion = "fishhash-kls-0.0.1"
const hashingAlgoVersion = "fishhash-kls-0.0.2"

// State is an intermediate data structure with pre-computed values to speed up mining.
type State struct {
Expand All @@ -23,7 +23,8 @@ type State struct {
Target big.Int
prePowHash externalapi.DomainHash
//cache cache
context fishhashContext
context fishhashContext
blockVersion uint16
}

// var context *fishhashContext
Expand Down Expand Up @@ -91,14 +92,17 @@ func NewState(header externalapi.MutableBlockHeader, generatedag bool) *State {
header.SetTimeInMilliseconds(timestamp)
header.SetNonce(nonce)

log.Debugf("BlueWork[%s] BlueScore[%d] DAAScore[%d] Version[%d]", header.BlueWork(), header.BlueScore(), header.DAAScore(), header.Version())

return &State{
Target: *target,
prePowHash: *prePowHash,
//will remove matrix opow
//mat: *generateMatrix(prePowHash),
Timestamp: timestamp,
Nonce: nonce,
context: *getContext(generatedag, log),
Timestamp: timestamp,
Nonce: nonce,
context: *getContext(generatedag, log),
blockVersion: header.Version(),
}
}

Expand Down Expand Up @@ -132,19 +136,25 @@ func (state *State) CalculateProofOfWorkValue() *big.Int {
}
//log.Debugf("Hash prePowHash %x\n", state.prePowHash.ByteSlice())
//fmt.Printf("Hash prePowHash %x\n", state.prePowHash.ByteSlice())

powHash := writer.Finalize()

//middleHash := state.mat.HeavyHash(powHash)
//log.Debugf("Hash b3-1: %x\n", powHash.ByteSlice())
//fmt.Printf("Hash b3-1: %x\n", powHash.ByteSlice())
middleHash := fishHash(&state.context, powHash)
//log.Debugf("Hash fish: %x\n", middleHash.ByteSlice())
//fmt.Printf("Hash fish: %x\n", middleHash.ByteSlice())
//log.Infof("Hash b3-1: %x", powHash.ByteSlice())
middleHash := powHash
if state.blockVersion == 1 {
middleHash = fishHash(&state.context, powHash)
} else {
middleHash = fishHashPlus(&state.context, powHash)
}

//log.Infof("Hash fish: %x", middleHash.ByteSlice())

writer2 := hashes.NewPoWHashWriter()
writer2.InfallibleWrite(middleHash.ByteSlice())
finalHash := writer2.Finalize()

//log.Debugf("Hash b3-2: %x\n", finalHash.ByteSlice())
//log.Infof("Hash b3-2: %x", finalHash.ByteSlice())

return toBig(finalHash)
}
Expand Down
3 changes: 3 additions & 0 deletions domain/dagconfig/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ type Params struct {
MaxBlockLevel int

MergeDepth uint64
HFDAAScore uint64
}

// NormalizeRPCServerAddress returns addr with the current network default
Expand Down Expand Up @@ -341,6 +342,8 @@ var TestnetParams = Params{

MaxBlockLevel: 250,
MergeDepth: defaultMergeDepth,
// todo: define the fork date DAAscore
HFDAAScore: 6000000,
}

// SimnetParams defines the network parameters for the simulation test Kaspa
Expand Down
2 changes: 1 addition & 1 deletion version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const validCharacters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrs
const (
appMajor uint = 2
appMinor uint = 0
appPatch uint = 0
appPatch uint = 1
)

// appBuild is defined as a variable so it can be overridden during the build
Expand Down

0 comments on commit 1b6644b

Please sign in to comment.