mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-21 08:51:32 +00:00
remove PoW from ID
This commit is contained in:
@ -368,11 +368,8 @@ func (n *Node) OnStart() error {
|
|||||||
n.sw.AddListener(l)
|
n.sw.AddListener(l)
|
||||||
|
|
||||||
// Generate node PrivKey
|
// Generate node PrivKey
|
||||||
// TODO: both the loading function and the target
|
// TODO: the loading function will need to be configurable
|
||||||
// will need to be configurable
|
nodeKey, err := p2p.LoadOrGenNodeKey(n.config.NodeKeyFile())
|
||||||
difficulty := uint8(16) // number of leading 0s in bitstring
|
|
||||||
target := p2p.MakePoWTarget(difficulty)
|
|
||||||
nodeKey, err := p2p.LoadOrGenNodeKey(n.config.NodeKeyFile(), target)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -381,7 +378,6 @@ func (n *Node) OnStart() error {
|
|||||||
// Start the switch
|
// Start the switch
|
||||||
n.sw.SetNodeInfo(n.makeNodeInfo(nodeKey.PubKey()))
|
n.sw.SetNodeInfo(n.makeNodeInfo(nodeKey.PubKey()))
|
||||||
n.sw.SetNodeKey(nodeKey)
|
n.sw.SetNodeKey(nodeKey)
|
||||||
n.sw.SetPeerIDTarget(target)
|
|
||||||
err = n.sw.Start()
|
err = n.sw.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
64
p2p/key.go
64
p2p/key.go
@ -6,7 +6,6 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math/big"
|
|
||||||
|
|
||||||
crypto "github.com/tendermint/go-crypto"
|
crypto "github.com/tendermint/go-crypto"
|
||||||
cmn "github.com/tendermint/tmlibs/common"
|
cmn "github.com/tendermint/tmlibs/common"
|
||||||
@ -42,37 +41,20 @@ func (nodeKey *NodeKey) SatisfiesTarget(target []byte) bool {
|
|||||||
return bytes.Compare(nodeKey.id(), target) < 0
|
return bytes.Compare(nodeKey.id(), target) < 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadOrGenNodeKey attempts to load the NodeKey from the given filePath,
|
// LoadOrGenNodeKey attempts to load the NodeKey from the given filePath.
|
||||||
// and checks that the corresponding ID is less than the target.
|
// If the file does not exist, it generates and saves a new NodeKey.
|
||||||
// If the file does not exist, it generates and saves a new NodeKey
|
func LoadOrGenNodeKey(filePath string) (*NodeKey, error) {
|
||||||
// with ID less than target.
|
|
||||||
func LoadOrGenNodeKey(filePath string, target []byte) (*NodeKey, error) {
|
|
||||||
if cmn.FileExists(filePath) {
|
if cmn.FileExists(filePath) {
|
||||||
nodeKey, err := loadNodeKey(filePath)
|
nodeKey, err := loadNodeKey(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !nodeKey.SatisfiesTarget(target) {
|
|
||||||
return nil, fmt.Errorf("Loaded ID (%s) does not satisfy target (%X)", nodeKey.ID(), target)
|
|
||||||
}
|
|
||||||
return nodeKey, nil
|
return nodeKey, nil
|
||||||
} else {
|
} else {
|
||||||
return genNodeKey(filePath, target)
|
return genNodeKey(filePath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MakePoWTarget returns a 20 byte target byte array.
|
|
||||||
func MakePoWTarget(difficulty uint8) []byte {
|
|
||||||
zeroPrefixLen := (int(difficulty) / 8)
|
|
||||||
prefix := bytes.Repeat([]byte{0}, zeroPrefixLen)
|
|
||||||
mod := (difficulty % 8)
|
|
||||||
if mod > 0 {
|
|
||||||
nonZeroPrefix := byte(1 << (8 - mod))
|
|
||||||
prefix = append(prefix, nonZeroPrefix)
|
|
||||||
}
|
|
||||||
return append(prefix, bytes.Repeat([]byte{255}, 20-len(prefix))...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadNodeKey(filePath string) (*NodeKey, error) {
|
func loadNodeKey(filePath string) (*NodeKey, error) {
|
||||||
jsonBytes, err := ioutil.ReadFile(filePath)
|
jsonBytes, err := ioutil.ReadFile(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -86,8 +68,8 @@ func loadNodeKey(filePath string) (*NodeKey, error) {
|
|||||||
return nodeKey, nil
|
return nodeKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func genNodeKey(filePath string, target []byte) (*NodeKey, error) {
|
func genNodeKey(filePath string) (*NodeKey, error) {
|
||||||
privKey := genPrivKeyEd25519PoW(target).Wrap()
|
privKey := crypto.GenPrivKeyEd25519().Wrap()
|
||||||
nodeKey := &NodeKey{
|
nodeKey := &NodeKey{
|
||||||
PrivKey: privKey,
|
PrivKey: privKey,
|
||||||
}
|
}
|
||||||
@ -103,20 +85,26 @@ func genNodeKey(filePath string, target []byte) (*NodeKey, error) {
|
|||||||
return nodeKey, nil
|
return nodeKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate key with address satisfying the difficult target
|
//------------------------------------------------------------------------------
|
||||||
func genPrivKeyEd25519PoW(target []byte) crypto.PrivKeyEd25519 {
|
|
||||||
secret := crypto.CRandBytes(32)
|
|
||||||
var privKey crypto.PrivKeyEd25519
|
|
||||||
for i := 0; ; i++ {
|
|
||||||
privKey = crypto.GenPrivKeyEd25519FromSecret(secret)
|
|
||||||
if bytes.Compare(privKey.PubKey().Address(), target) < 0 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
z := new(big.Int)
|
|
||||||
z.SetBytes(secret)
|
|
||||||
z = z.Add(z, big.NewInt(1))
|
|
||||||
secret = z.Bytes()
|
|
||||||
|
|
||||||
|
// MakePoWTarget returns the big-endian encoding of 2^(targetBits - difficulty) - 1.
|
||||||
|
// It can be used as a Proof of Work target.
|
||||||
|
// NOTE: targetBits must be a multiple of 8 and difficulty must be less than targetBits.
|
||||||
|
func MakePoWTarget(difficulty, targetBits uint) []byte {
|
||||||
|
if targetBits%8 != 0 {
|
||||||
|
panic(fmt.Sprintf("targetBits (%d) not a multiple of 8", targetBits))
|
||||||
}
|
}
|
||||||
return privKey
|
if difficulty >= targetBits {
|
||||||
|
panic(fmt.Sprintf("difficulty (%d) >= targetBits (%d)", difficulty, targetBits))
|
||||||
|
}
|
||||||
|
targetBytes := targetBits / 8
|
||||||
|
zeroPrefixLen := (int(difficulty) / 8)
|
||||||
|
prefix := bytes.Repeat([]byte{0}, zeroPrefixLen)
|
||||||
|
mod := (difficulty % 8)
|
||||||
|
if mod > 0 {
|
||||||
|
nonZeroPrefix := byte(1<<(8-mod) - 1)
|
||||||
|
prefix = append(prefix, nonZeroPrefix)
|
||||||
|
}
|
||||||
|
tailLen := int(targetBytes) - len(prefix)
|
||||||
|
return append(prefix, bytes.Repeat([]byte{0xFF}, tailLen)...)
|
||||||
}
|
}
|
||||||
|
@ -13,37 +13,38 @@ import (
|
|||||||
func TestLoadOrGenNodeKey(t *testing.T) {
|
func TestLoadOrGenNodeKey(t *testing.T) {
|
||||||
filePath := filepath.Join(os.TempDir(), cmn.RandStr(12)+"_peer_id.json")
|
filePath := filepath.Join(os.TempDir(), cmn.RandStr(12)+"_peer_id.json")
|
||||||
|
|
||||||
target := MakePoWTarget(2)
|
nodeKey, err := LoadOrGenNodeKey(filePath)
|
||||||
nodeKey, err := LoadOrGenNodeKey(filePath, target)
|
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
nodeKey2, err := LoadOrGenNodeKey(filePath, target)
|
nodeKey2, err := LoadOrGenNodeKey(filePath)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
assert.Equal(t, nodeKey, nodeKey2)
|
assert.Equal(t, nodeKey, nodeKey2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func repeatBytes(val byte, n int) []byte {
|
//----------------------------------------------------------
|
||||||
return bytes.Repeat([]byte{val}, n)
|
|
||||||
|
func padBytes(bz []byte, targetBytes int) []byte {
|
||||||
|
return append(bz, bytes.Repeat([]byte{0xFF}, targetBytes-len(bz))...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPoWTarget(t *testing.T) {
|
func TestPoWTarget(t *testing.T) {
|
||||||
|
|
||||||
|
targetBytes := 20
|
||||||
cases := []struct {
|
cases := []struct {
|
||||||
difficulty uint8
|
difficulty uint
|
||||||
target []byte
|
target []byte
|
||||||
}{
|
}{
|
||||||
{0, bytes.Repeat([]byte{255}, 20)},
|
{0, padBytes([]byte{}, targetBytes)},
|
||||||
{1, append([]byte{128}, repeatBytes(255, 19)...)},
|
{1, padBytes([]byte{127}, targetBytes)},
|
||||||
{8, append([]byte{0}, repeatBytes(255, 19)...)},
|
{8, padBytes([]byte{0}, targetBytes)},
|
||||||
{9, append([]byte{0, 128}, repeatBytes(255, 18)...)},
|
{9, padBytes([]byte{0, 127}, targetBytes)},
|
||||||
{10, append([]byte{0, 64}, repeatBytes(255, 18)...)},
|
{10, padBytes([]byte{0, 63}, targetBytes)},
|
||||||
{16, append([]byte{0, 0}, repeatBytes(255, 18)...)},
|
{16, padBytes([]byte{0, 0}, targetBytes)},
|
||||||
{17, append([]byte{0, 0, 128}, repeatBytes(255, 17)...)},
|
{17, padBytes([]byte{0, 0, 127}, targetBytes)},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, c := range cases {
|
for _, c := range cases {
|
||||||
assert.Equal(t, MakePoWTarget(c.difficulty), c.target)
|
assert.Equal(t, MakePoWTarget(c.difficulty, 20*8), c.target)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user