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

Verge integration for algos #2

Draft
wants to merge 18 commits into
base: master
Choose a base branch
from
Draft
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
9 changes: 5 additions & 4 deletions blockchain/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,11 +324,12 @@ func checkProofOfWork(header *wire.BlockHeader, powLimit *big.Int, flags Behavio
// to avoid proof of work checks is set.
if flags&BFNoPoWCheck != BFNoPoWCheck {
// The block hash must be less than the claimed target.
hash := header.BlockHash()
algorithm := header.GetAlgorithmString()
hash := header.BlockPoWHash()
hashNum := HashToBig(&hash)
if hashNum.Cmp(target) > 0 {
str := fmt.Sprintf("block hash of %064x is higher than "+
"expected max of %064x", hashNum, target)
str := fmt.Sprintf("%s block hash of %064x is higher than "+
"expected max of %064x", algorithm, hashNum, target)
return ruleError(ErrHighHash, str)
}
}
Expand Down Expand Up @@ -674,7 +675,7 @@ func (b *BlockChain) checkBlockHeaderContext(header *wire.BlockHeader, prevNode
blockHeight := prevNode.height + 1

// Ensure chain matches up to predetermined checkpoints.
blockHash := header.BlockHash()
blockHash := header.BlockPoWHash()
if !b.verifyCheckpoint(blockHeight, &blockHash) {
str := fmt.Sprintf("block at height %d does not match "+
"checkpoint hash", blockHeight)
Expand Down
69 changes: 67 additions & 2 deletions chaincfg/chainhash/hashfuncs.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,15 @@
package chainhash

import (
"crypto"
"crypto/sha256"

// Blake2s is required due to Hash.New(blake2s)
_ "golang.org/x/crypto/blake2s"

"github.com/Groestlcoin/go-groestl-hash/groestl"
"github.com/bitgoin/lyra2rev2"
"github.com/marpme/go-x17"
"golang.org/x/crypto/scrypt"
)

Expand Down Expand Up @@ -38,11 +45,69 @@ func DoubleHashH(b []byte) Hash {

// ScryptHash calculates scryptHash(b) and returns the resulting bytes as a Hash
func ScryptHash(b []byte) Hash {
scryptHash, _ := scrypt.Key(b, b, 1024, 1, 1, 32)
var hash [32]byte
scryptHash, err := scrypt.Key(b, b, 1024, 1, 1, 32)
if err != nil {
panic(err)
}

var hash [32]byte
for i := 0; i < len(hash); i++ {
hash[i] = scryptHash[i]
}
return Hash(hash)
}

// GroestlHash calculates GroestlHash(b) and returns the resulting bytes as a Hash
func GroestlHash(b []byte) Hash {
groestl, out := groestl.New(), [32]byte{}

_, err := groestl.Write(b)
if err != nil {
panic(err)
}

groestl.Close(out[:], 0, 0)

return Hash(out)
}

// BlakeHash calculates GroestlHash(b) and returns the resulting bytes as a Hash
func BlakeHash(b []byte) Hash {
blake2s, out := crypto.BLAKE2s_256.New(), []byte{}

_, err := blake2s.Write(b)
if err != nil {
panic(err)
}

out = blake2s.Sum(out)
var hash [32]byte
for i := 0; i < len(hash); i++ {
hash[i] = out[i]
}

return Hash(hash)
}

// Lyra2Rev2Hash calculates Lyra2Rev2Hash(b) and returns the resulting bytes as a Hash
func Lyra2Rev2Hash(b []byte) Hash {
lyraHash, err := lyra2rev2.Sum(b)

if err != nil {
panic(err)
}

var hash [32]byte
for i := 0; i < len(hash); i++ {
hash[i] = lyraHash[i]
}

return Hash(hash)
}

func X17Hash(b []byte) Hash {
var dst [32]byte
x17.New().Hash(b, dst[:])

return Hash(dst)
}
7 changes: 7 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
module github.com/btcsuite/btcd

require (
github.com/Groestlcoin/go-groestl-hash v0.0.0-20181012171753-790653ac190c
github.com/aead/siphash v1.0.1 // indirect
github.com/aead/skein v0.0.0-20160722084837-9365ae6e95d2 // indirect
github.com/bitgoin/lyra2rev2 v0.0.0-20161212102046-bae9ad2043bb
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d
github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd
github.com/btcsuite/snappy-go v1.0.0 // indirect
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792
github.com/btcsuite/winsvc v1.0.0
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495
github.com/dchest/blake256 v1.1.0 // indirect
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89
github.com/jrick/logrotate v1.0.0
github.com/kkdai/bstream v1.0.0 // indirect
github.com/marpme/go-x17 v0.0.0-20200509121422-6d9b9d475fc4
github.com/onsi/ginkgo v1.12.0 // indirect
github.com/onsi/gomega v1.10.0 // indirect
github.com/vergecurrency/go-socks v0.0.0-20170105172521-4720035b7bfd
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d
)
Expand Down
31 changes: 31 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
github.com/Groestlcoin/go-groestl-hash v0.0.0-20181012171753-790653ac190c h1:8bYNmjELeCj7DEh/dN7zFzkJ0upK3GkbOC/0u1HMQ5s=
github.com/Groestlcoin/go-groestl-hash v0.0.0-20181012171753-790653ac190c/go.mod h1:DwgC62sAn4RgH4L+O8REgcE7f0XplHPNeRYFy+ffy1M=
github.com/aead/siphash v1.0.1 h1:FwHfE/T45KPKYuuSAKyyvE+oPWcaQ+CUmFW0bPlM+kg=
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
github.com/aead/skein v0.0.0-20160722084837-9365ae6e95d2 h1:q5TSngwXJdajCyZPQR+eKyRRgI3/ZXC/Nq1ZxZ4Zxu8=
github.com/aead/skein v0.0.0-20160722084837-9365ae6e95d2/go.mod h1:4JBZEId5BaLqvA2DGU53phvwkn2WpeLhNSF79/uKBPs=
github.com/bitgoin/lyra2rev2 v0.0.0-20161212102046-bae9ad2043bb h1:2FbdV3Tfmli5z4jYgKrosbBRAA48PtYbt4igU5HaXY4=
github.com/bitgoin/lyra2rev2 v0.0.0-20161212102046-bae9ad2043bb/go.mod h1:0vfuB+dfDvUoqr7oGBAZzGvaAyxfKFsYnRwUrNM4ft8=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d h1:yJzD/yFppdVCf6ApMkVy8cUxV0XrxdP9rVf6D87/Mng=
Expand All @@ -12,11 +18,17 @@ github.com/btcsuite/snappy-go v1.0.0 h1:ZxaA6lo2EpxGddsA8JwWOcxlzRybb444sgmeJQMJ
github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 h1:R8vQdOQdZ9Y3SkEwmHoWBmX1DNXhXZqlTpq6s4tyJGc=
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
github.com/btcsuite/winsvc v1.0.0 h1:J9B4L7e3oqhXOcm+2IuNApwzQec85lE+QaikUcCs+dk=
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495 h1:6IyqGr3fnd0tM3YxipK27TUskaOVUjU2nG45yzwcQKY=
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dchest/blake256 v1.1.0 h1:4AuEhGPT/3TTKFhTfBpZ8hgZE7wJpawcYaEawwsbtqM=
github.com/dchest/blake256 v1.1.0/go.mod h1:xXNWCE1jsAP8DAjP+rKw2MbeqLczjI3TRx2VK+9OEYY=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89 h1:12K8AlpT0/6QUXSfV0yi4Q0jkbq8NDtIKFtF61AoqV0=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
Expand All @@ -26,9 +38,16 @@ github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23 h1:FOOIBWrEkLgmlgGfM
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
github.com/kkdai/bstream v1.0.0 h1:Se5gHwgp2VT2uHfDrkbbgbgEvV9cimLELwrPJctSjg8=
github.com/kkdai/bstream v1.0.0/go.mod h1:FDnDOHt5Yx4p3FaHcioFT0QjDOtgUpvjeZqAs+NVZZA=
github.com/marpme/go-x17 v0.0.0-20200509121422-6d9b9d475fc4 h1:lMcyl4aT/t1f7hnNaIqBnF5B2IaOeIZh4k47CW5LSB4=
github.com/marpme/go-x17 v0.0.0-20200509121422-6d9b9d475fc4/go.mod h1:UXVI5YpkJ0BSeK3qdqm8HJpn19FhZC6dTt1PGQt7QY8=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU=
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.0 h1:Gwkk+PTu/nfOwNMtUB/mRUv0X7ewW5dO4AERT1ThVKo=
github.com/onsi/gomega v1.10.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
github.com/vergecurrency/btcd v0.0.1 h1:I1bcbSlpf4R+hw9mef34syZCt+jVBJ1TSFLw8nCI0tE=
github.com/vergecurrency/btcd v0.0.1/go.mod h1:ruG6jds8I8hXUFWlOEfbICGa+HqfdBSfvR73nYcMfII=
github.com/vergecurrency/go-socks v0.0.0-20170105172521-4720035b7bfd h1:MuBrkpFHTqXc+cCdoRMWE/cWsdO15TdiDVsiJaiqpqU=
Expand All @@ -37,13 +56,25 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d h1:9FCpayM9Egr1baVnV1SX0H87m+XB0B8S0hAMi99X/3U=
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e h1:N7DeIrjYszNmSW409R3frPPwglRwMkXSBzwVbkOjLLA=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
61 changes: 61 additions & 0 deletions wire/blockalgorithm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package wire

// AlgorithmBitMask to extract the algo id from the actual version number
const AlgorithmBitMask int32 = (15 << 11)

// OldAlgorithmBitMask to extract the algo id from the actual version number
const OldAlgorithmBitMask int32 = (10 << 11)

// Algorithm represents all available algorithm signatures within a block version
type Algorithm int32

// represents all algorithms possible with the current core node
const (
SCRYPT Algorithm = (1 << 11)
GROESTL Algorithm = (2 << 11)
X17 Algorithm = (3 << 11)
BLAKE Algorithm = (4 << 11)
LYRA2RE Algorithm = (10 << 11)
)

// BlockAlgorithm returns the block algorithm that has been within the blockheader
func (h *BlockHeader) BlockAlgorithm() Algorithm {
var extractedAlgorithm Algorithm = Algorithm(h.Version & AlgorithmBitMask)

switch extractedAlgorithm {
case SCRYPT:
return SCRYPT
case GROESTL:
return GROESTL
case X17:
return X17
case BLAKE:
return BLAKE
case LYRA2RE:
return LYRA2RE
default:
// Everything that possibly moves out of range will identified as scrypt.
return SCRYPT
}
}

// GetAlgorithmString returns the block algorithm string that has been within the blockheader
func (h *BlockHeader) GetAlgorithmString() string {
var extractedAlgorithm Algorithm = Algorithm(h.Version & AlgorithmBitMask)

switch extractedAlgorithm {
case SCRYPT:
return "scrypt"
case GROESTL:
return "Groestl"
case X17:
return "x17"
case BLAKE:
return "blake2s"
case LYRA2RE:
return "lyra2re"
default:
// Everything that possibly moves out of range will identified as scrypt.
return "scrypt"
}
}
61 changes: 61 additions & 0 deletions wire/blockalgorithm_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package wire

import "testing"

func TestBlockAlgorithm(t *testing.T) {
tests := []struct {
name string
header BlockHeader
want Algorithm
}{
{
"Scrypt + Version",
BlockHeader{
Version: int32(SCRYPT | (1 << 20)),
},
Algorithm(2048),
},
{
"Groestl + Version",
BlockHeader{
Version: int32(GROESTL | (1 << 20)),
},
Algorithm(4096),
},
{
"X17 + Version",
BlockHeader{
Version: int32(X17 | (1 << 20)),
},
Algorithm(6144),
},
{
"Blake2s + Version",
BlockHeader{
Version: int32(BLAKE | (1 << 20)),
},
Algorithm(8192),
},
{
"Lyra2Re + Version",
BlockHeader{
Version: int32(LYRA2RE | (1 << 20)),
},
Algorithm(20480),
},
{
"Unkown",
BlockHeader{
Version: int32(LYRA2RE | (5 << 11)),
},
Algorithm(2048), // fallback to Scrypt
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.header.BlockAlgorithm(); got != tt.want {
t.Errorf("BlockAlgorithm() = %v, want %v", got, tt.want)
}
})
}
}
25 changes: 24 additions & 1 deletion wire/blockheader.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,30 @@ func (h *BlockHeader) BlockHash() chainhash.Hash {
buf := bytes.NewBuffer(make([]byte, 0, MaxBlockHeaderPayload))
_ = writeBlockHeader(buf, 0, h)

return chainhash.ScryptHash(buf.Bytes())
return chainhash.ScryptHash(buf.Bytes()) // default to hash2scrypt
}

// BlockPoWHash computes the block identifier hash for the given block header.
func (header *BlockHeader) BlockPoWHash() chainhash.Hash {
// Encode the header and double sha256 everything prior to the number of
// transactions. Ignore the error returns since there is no way the
// encode could fail except being out of memory which would cause a
// run-time panic.
buf := bytes.NewBuffer(make([]byte, 0, MaxBlockHeaderPayload))
_ = writeBlockHeader(buf, 0, header)

switch header.BlockAlgorithm() {
case GROESTL:
return chainhash.GroestlHash(buf.Bytes())
case X17:
return chainhash.X17Hash(buf.Bytes())
case BLAKE:
return chainhash.BlakeHash(buf.Bytes())
case LYRA2RE:
return chainhash.Lyra2Rev2Hash(buf.Bytes())
}

return chainhash.ScryptHash(buf.Bytes()) // default to hash2scrypt
}

// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
Expand Down
Loading