From 4c1951d90388a29dccbf0aba16955edb53e8d8cf Mon Sep 17 00:00:00 2001
From: Benjamin Bollen <ben@monax.io>
Date: Tue, 21 Feb 2017 16:19:21 +0100
Subject: [PATCH] genesis: corrections to clone and other minor fixes

---
 genesis/genesis.go |  8 ++++----
 genesis/maker.go   | 23 +++++++++++++++--------
 genesis/types.go   | 23 +++++++++++++++--------
 3 files changed, 34 insertions(+), 20 deletions(-)

diff --git a/genesis/genesis.go b/genesis/genesis.go
index 85bc3a83..fb348693 100644
--- a/genesis/genesis.go
+++ b/genesis/genesis.go
@@ -39,17 +39,17 @@ func MakeGenesisDocFromAccounts(chainName string, accounts []*GenesisAccount,
 	}
 	// copy slice of pointers to accounts into slice of accounts
 	accountsCopy := make([]GenesisAccount, len(accounts))
-	for _, genesisAccount := range accounts {
-		accountsCopy = append(accountsCopy, genesisAccount.Clone())
+	for i, genesisAccount := range accounts {
+		accountsCopy[i] = genesisAccount.Clone()
 	}
 	// copy slice of pointers to validators into slice of validators
 	validatorsCopy := make([]GenesisValidator, len(validators))
-	for _, genesisValidator := range validators {
+	for i, genesisValidator := range validators {
 		genesisValidatorCopy, err := genesisValidator.Clone()
 		if err != nil {
 			return GenesisDoc{}, err
 		}
-		validatorsCopy = append(validatorsCopy, genesisValidatorCopy)
+		validatorsCopy[i] = genesisValidatorCopy
 	}
 	genesisDoc := GenesisDoc{
 		GenesisTime: time.Now(),
diff --git a/genesis/maker.go b/genesis/maker.go
index e913a115..184be977 100644
--- a/genesis/maker.go
+++ b/genesis/maker.go
@@ -36,8 +36,8 @@ func NewGenesisAccount(address []byte, amount int64, name string,
 
 func NewGenesisValidator(amount int64, name string, unbondToAddress []byte,
 	unbondAmount int64, keyType string, publicKeyBytes []byte) (*GenesisValidator, error) {
-	var publicKey crypto.PubKey
 	// convert the key bytes into a typed fixed size byte array
+	var typedPublicKeyBytes []byte
 	switch keyType {
 	case "ed25519":
 		// TODO: [ben] functionality and checks need to be inherit in the type
@@ -45,25 +45,32 @@ func NewGenesisValidator(amount int64, name string, unbondToAddress []byte,
 			return nil, fmt.Errorf("Invalid length provided for ed25519 public key (len %v)",
 				len(publicKeyBytes))
 		}
-		publicKey := crypto.PubKeyEd25519{}
-		copy(publicKey[:], publicKeyBytes[:32])
+		// ed25519 has type byte 0x01
+		typedPublicKeyBytes = make([]byte, 33)
+		// prepend type byte to public key
+		typedPublicKeyBytes = append([]byte{crypto.PubKeyTypeEd25519}, publicKeyBytes...)
 	case "secp256k1":
 		if len(publicKeyBytes) != 64 {
 			return nil, fmt.Errorf("Invalid length provided for secp256k1 public key (len %v)",
 				len(publicKeyBytes))
 		}
-		publicKey := crypto.PubKeySecp256k1{}
-		copy(publicKey[:], publicKeyBytes[:64])
+		// secp256k1 has type byte 0x02
+		typedPublicKeyBytes = make([]byte, 65)
+		// prepend type byte to public key
+		typedPublicKeyBytes = append([]byte{crypto.PubKeyTypeSecp256k1}, publicKeyBytes...)
 	default:
 		return nil, fmt.Errorf("Unsupported key type (%s)", keyType)
 	}
-
+	newPublicKey, err := crypto.PubKeyFromBytes(typedPublicKeyBytes)
+	if err != nil {
+		return nil, err
+	}
 	// ability to unbond to multiple accounts currently unused
 	var unbondTo []BasicAccount
 
 	return &GenesisValidator{
-		PubKey: publicKey,
-		Amount: amount,
+		PubKey: newPublicKey,
+		Amount: unbondAmount,
 		Name:   name,
 		UnbondTo: append(unbondTo, BasicAccount{
 			Address: unbondToAddress,
diff --git a/genesis/types.go b/genesis/types.go
index 292c4851..5b60154f 100644
--- a/genesis/types.go
+++ b/genesis/types.go
@@ -58,12 +58,12 @@ type GenesisValidator struct {
 // is defined in genesis and not under consensus, where
 // PrivateValidator (currently inherited from Tendermint) is.
 type GenesisPrivateValidator struct {
-	Address    []byte         `json:"address"`
-	PubKey     crypto.PubKey  `json:"pub_key"`
-	PrivKey    crypto.PrivKey `json:"priv_key"`
-	LastHeight int64          `json:"last_height"`
-	LastRound  int64          `json:"last_round"`
-	LastStep   int64          `json:"last_step"`
+	Address    string        `json:"address"`
+	PubKey     []interface{} `json:"pub_key"`
+	PrivKey    []interface{} `json:"priv_key"`
+	LastHeight int64         `json:"last_height"`
+	LastRound  int64         `json:"last_round"`
+	LastStep   int64         `json:"last_step"`
 }
 
 type GenesisParams struct {
@@ -123,6 +123,13 @@ func (genesisAccount *GenesisAccount) Clone() GenesisAccount {
 
 // Clone clones the genesis validator
 func (genesisValidator *GenesisValidator) Clone() (GenesisValidator, error) {
+	if genesisValidator == nil {
+		return GenesisValidator{}, fmt.Errorf("Cannot clone nil GenesisValidator.")
+	}
+	if genesisValidator.PubKey == nil {
+		return GenesisValidator{}, fmt.Errorf("Invalid GenesisValidator %s with nil public key.",
+			genesisValidator.Name)
+	}
 	// clone the public key by writing and reading over go-wire serialisation
 	// TODO! write unit test to see whether this is correct
 	publicKeyClone, err := crypto.PubKeyFromBytes(genesisValidator.PubKey.Bytes())
@@ -131,8 +138,8 @@ func (genesisValidator *GenesisValidator) Clone() (GenesisValidator, error) {
 	}
 	// clone the addresses to unbond to
 	unbondToClone := make([]BasicAccount, len(genesisValidator.UnbondTo))
-	for _, basicAccount := range genesisValidator.UnbondTo {
-		unbondToClone = append(unbondToClone, basicAccount.Clone())
+	for i, basicAccount := range genesisValidator.UnbondTo {
+		unbondToClone[i] = basicAccount.Clone()
 	}
 	return GenesisValidator{
 		PubKey:   publicKeyClone,
-- 
GitLab