Skip to content
Merged
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
2 changes: 1 addition & 1 deletion blockproducer/interfaces/mixins.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type TransactionTypeMixin struct {
func NewTransactionTypeMixin(txType TransactionType) *TransactionTypeMixin {
return &TransactionTypeMixin{
TxType: txType,
Timestamp: time.Now(),
Timestamp: time.Now().UTC(),
}
}

Expand Down
31 changes: 7 additions & 24 deletions blockproducer/metastate.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,10 @@ package blockproducer
import (
"bytes"
"sort"
"time"

pi "github.com/CovenantSQL/CovenantSQL/blockproducer/interfaces"
"github.com/CovenantSQL/CovenantSQL/conf"
"github.com/CovenantSQL/CovenantSQL/crypto"
"github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
"github.com/CovenantSQL/CovenantSQL/crypto/hash"
"github.com/CovenantSQL/CovenantSQL/crypto/kms"
"github.com/CovenantSQL/CovenantSQL/proto"
"github.com/CovenantSQL/CovenantSQL/types"
"github.com/CovenantSQL/CovenantSQL/utils"
Expand Down Expand Up @@ -651,7 +647,7 @@ func (s *metaState) matchProvidersWithUser(tx *types.CreateDatabase) (err error)
AdvancePayment: tx.AdvancePayment,
}
// generate genesis block
gb, err := s.generateGenesisBlock(dbID, tx.ResourceMeta)
gb, err := s.generateGenesisBlock(dbID, tx)
if err != nil {
log.WithFields(log.Fields{
"dbID": dbID,
Expand Down Expand Up @@ -1161,32 +1157,19 @@ func (s *metaState) applyTransaction(tx pi.Transaction) (err error) {
return
}

func (s *metaState) generateGenesisBlock(dbID proto.DatabaseID, resourceMeta types.ResourceMeta) (genesisBlock *types.Block, err error) {
// TODO(xq262144): following is stub code, real logic should be implemented in the future
emptyHash := hash.Hash{}

var privKey *asymmetric.PrivateKey
if privKey, err = kms.GetLocalPrivateKey(); err != nil {
return
}
var nodeID proto.NodeID
if nodeID, err = kms.GetLocalNodeID(); err != nil {
return
}

func (s *metaState) generateGenesisBlock(dbID proto.DatabaseID, tx *types.CreateDatabase) (genesisBlock *types.Block, err error) {
emptyNode := &proto.RawNodeID{}
genesisBlock = &types.Block{
SignedHeader: types.SignedHeader{
Header: types.Header{
Version: 0x01000000,
Producer: nodeID,
GenesisHash: emptyHash,
ParentHash: emptyHash,
Timestamp: time.Now().UTC(),
Version: 0x01000000,
Producer: emptyNode.ToNodeID(),
Timestamp: tx.Timestamp,
},
},
}

err = genesisBlock.PackAndSignBlock(privKey)
err = genesisBlock.PackAsGenesis()

return
}
Expand Down
31 changes: 9 additions & 22 deletions client/helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import (
"github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
"github.com/CovenantSQL/CovenantSQL/crypto/hash"
"github.com/CovenantSQL/CovenantSQL/crypto/kms"
"github.com/CovenantSQL/CovenantSQL/pow/cpuminer"
"github.com/CovenantSQL/CovenantSQL/proto"
"github.com/CovenantSQL/CovenantSQL/route"
"github.com/CovenantSQL/CovenantSQL/rpc"
Expand Down Expand Up @@ -271,7 +270,7 @@ func initNode() (cleanupFunc func(), tempDir string, server *rpc.Server, err err
// copied from sqlchain.xxx_test.
func createRandomBlock(parent hash.Hash, isGenesis bool) (b *types.Block, err error) {
// Generate key pair
priv, pub, err := asymmetric.GenSecp256k1KeyPair()
priv, _, err := asymmetric.GenSecp256k1KeyPair()

if err != nil {
return
Expand All @@ -293,26 +292,14 @@ func createRandomBlock(parent hash.Hash, isGenesis bool) (b *types.Block, err er
}

if isGenesis {
// Compute nonce with public key
nonceCh := make(chan cpuminer.NonceInfo)
quitCh := make(chan struct{})
miner := cpuminer.NewCPUMiner(quitCh)
go miner.ComputeBlockNonce(cpuminer.MiningBlock{
Data: pub.Serialize(),
NonceChan: nonceCh,
Stop: nil,
}, cpuminer.Uint256{A: 0, B: 0, C: 0, D: 0}, 4)
nonce := <-nonceCh
close(quitCh)
close(nonceCh)
// Add public key to KMS
id := cpuminer.HashBlock(pub.Serialize(), nonce.Nonce)
b.SignedHeader.Header.Producer = proto.NodeID(id.String())
err = kms.SetPublicKey(proto.NodeID(id.String()), nonce.Nonce, pub)

if err != nil {
return nil, err
}
emptyNode := &proto.RawNodeID{}
b.SignedHeader.ParentHash = hash.Hash{}
b.SignedHeader.GenesisHash = hash.Hash{}
b.SignedHeader.Producer = emptyNode.ToNodeID()
b.SignedHeader.MerkleRoot = hash.Hash{}

err = b.PackAsGenesis()
return
}

err = b.PackAndSignBlock(priv)
Expand Down
31 changes: 9 additions & 22 deletions cmd/cql-minerd/dbms.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import (
"github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
"github.com/CovenantSQL/CovenantSQL/crypto/hash"
"github.com/CovenantSQL/CovenantSQL/crypto/kms"
"github.com/CovenantSQL/CovenantSQL/pow/cpuminer"
"github.com/CovenantSQL/CovenantSQL/proto"
"github.com/CovenantSQL/CovenantSQL/rpc"
"github.com/CovenantSQL/CovenantSQL/types"
Expand Down Expand Up @@ -150,7 +149,7 @@ func loadGenesisBlock(fixture *conf.MinerDatabaseFixture) (block *types.Block, e
// copied from sqlchain.xxx_test.
func createRandomBlock(parent hash.Hash, isGenesis bool) (b *types.Block, err error) {
// Generate key pair
priv, pub, err := asymmetric.GenSecp256k1KeyPair()
priv, _, err := asymmetric.GenSecp256k1KeyPair()

if err != nil {
return
Expand All @@ -172,26 +171,14 @@ func createRandomBlock(parent hash.Hash, isGenesis bool) (b *types.Block, err er
}

if isGenesis {
// Compute nonce with public key
nonceCh := make(chan cpuminer.NonceInfo)
quitCh := make(chan struct{})
miner := cpuminer.NewCPUMiner(quitCh)
go miner.ComputeBlockNonce(cpuminer.MiningBlock{
Data: pub.Serialize(),
NonceChan: nonceCh,
Stop: nil,
}, cpuminer.Uint256{}, 4)
nonce := <-nonceCh
close(quitCh)
close(nonceCh)
// Add public key to KMS
id := cpuminer.HashBlock(pub.Serialize(), nonce.Nonce)
b.SignedHeader.Header.Producer = proto.NodeID(id.String())
err = kms.SetPublicKey(proto.NodeID(id.String()), nonce.Nonce, pub)

if err != nil {
return nil, err
}
emptyNode := &proto.RawNodeID{}
b.SignedHeader.ParentHash = hash.Hash{}
b.SignedHeader.GenesisHash = hash.Hash{}
b.SignedHeader.Producer = emptyNode.ToNodeID()
b.SignedHeader.MerkleRoot = hash.Hash{}

err = b.PackAsGenesis()
return
}

err = b.PackAndSignBlock(priv)
Expand Down
2 changes: 1 addition & 1 deletion proto/nodeinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ func (id *NodeID) ToRawNodeID() *RawNodeID {

// IsEmpty test if a nodeID is empty.
func (id *NodeID) IsEmpty() bool {
return id == nil || "" == string(*id)
return id == nil || "" == string(*id) || id.ToRawNodeID().IsEqual(&hash.Hash{})
}

// IsEqual returns if two node id is equal.
Expand Down
12 changes: 0 additions & 12 deletions sqlchain/chain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,6 @@ func TestMultiChain(t *testing.T) {
t.Fatalf("error occurred: %v", err)
}

gnonce, err := kms.GetNodeInfo(genesis.Producer())

if err != nil {
t.Fatalf("error occurred: %v", err)
}

// Create peer list: `testPeersNumber` miners + 1 block producer
nis, peers, err := createTestPeers(testPeersNumber + 1)

Expand Down Expand Up @@ -268,12 +262,6 @@ func TestMultiChain(t *testing.T) {
// Test chain data reloading before exit
for _, v := range chains {
defer func(p *chainParams) {
if _, err := kms.GetPublicKey(genesis.Producer()); err != nil {
if err = kms.SetPublicKey(genesis.Producer(), gnonce.Nonce, genesis.Signee()); err != nil {
t.Errorf("error occurred: %v", err)
}
}

if chain, err := NewChain(p.config); err != nil {
t.Errorf("error occurred: %v", err)
} else {
Expand Down
19 changes: 9 additions & 10 deletions sqlchain/xxx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ func registerNodesWithPublicKey(pub *asymmetric.PublicKey, diff int, num int) (

func createRandomBlock(parent hash.Hash, isGenesis bool) (b *types.Block, err error) {
// Generate key pair
priv, pub, err := asymmetric.GenSecp256k1KeyPair()
priv, _, err := asymmetric.GenSecp256k1KeyPair()

if err != nil {
return
Expand Down Expand Up @@ -271,16 +271,15 @@ func createRandomBlock(parent hash.Hash, isGenesis bool) (b *types.Block, err er
}

if isGenesis {
// Register node for genesis verification
var nis []cpuminer.NonceInfo
nis, err = registerNodesWithPublicKey(pub, testDifficulty, 1)

if err != nil {
return
}

emptyNode := &proto.RawNodeID{}
b.SignedHeader.ParentHash = hash.Hash{}
b.SignedHeader.GenesisHash = hash.Hash{}
b.SignedHeader.Header.Producer = proto.NodeID(nis[0].Hash.String())
b.SignedHeader.Producer = emptyNode.ToNodeID()
b.SignedHeader.MerkleRoot = hash.Hash{}
b.Acks = nil

err = b.PackAsGenesis()
Comment thread
xq262144 marked this conversation as resolved.
return
}

err = b.PackAndSignBlock(priv)
Expand Down
57 changes: 30 additions & 27 deletions types/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,10 @@ import (

ca "github.com/CovenantSQL/CovenantSQL/crypto/asymmetric"
"github.com/CovenantSQL/CovenantSQL/crypto/hash"
"github.com/CovenantSQL/CovenantSQL/crypto/kms"
"github.com/CovenantSQL/CovenantSQL/crypto/verifier"
"github.com/CovenantSQL/CovenantSQL/merkle"
"github.com/CovenantSQL/CovenantSQL/proto"
"github.com/CovenantSQL/CovenantSQL/utils/log"
"github.com/pkg/errors"
)

//go:generate hsp
Expand Down Expand Up @@ -56,24 +55,14 @@ func (s *SignedHeader) Verify() error {
return s.HSV.Verify(&s.Header)
}

// VerifyAsGenesis verifies the signed header as a genesis block header.
func (s *SignedHeader) VerifyAsGenesis() (err error) {
var pk *ca.PublicKey
log.WithFields(log.Fields{
"producer": s.Producer,
"root": s.GenesisHash.String(),
"parent": s.ParentHash.String(),
"merkle": s.MerkleRoot.String(),
"block": s.HSV.Hash().String(),
}).Debug("verifying genesis block header")
if pk, err = kms.GetPublicKey(s.Producer); err != nil {
return
}
if !pk.IsEqual(s.HSV.Signee) {
err = ErrNodePublicKeyNotMatch
return
}
return s.Verify()
// VerifyHash verifies the hash of the signed header.
func (s *SignedHeader) VerifyHash() error {
return s.HSV.VerifyHash(&s.Header)
}

// ComputeHash computes the hash of the signed header.
func (s *SignedHeader) ComputeHash() error {
return s.HSV.SetHash(&s.Header)
}

// QueryAsTx defines a tx struct which is combined with request and signed response header
Expand Down Expand Up @@ -115,6 +104,11 @@ func (b *Block) PackAndSignBlock(signer *ca.PrivateKey) (err error) {
return b.SignedHeader.Sign(signer)
}

// PackAsGenesis generates the hash of the genesis block.
func (b *Block) PackAsGenesis() (err error) {
return b.SignedHeader.ComputeHash()
}

// Verify verifies the merkle root and header signature of the block.
func (b *Block) Verify() (err error) {
// Verify merkle root
Expand All @@ -126,15 +120,24 @@ func (b *Block) Verify() (err error) {

// VerifyAsGenesis verifies the block as a genesis block.
func (b *Block) VerifyAsGenesis() (err error) {
var pk *ca.PublicKey
if pk, err = kms.GetPublicKey(b.SignedHeader.Producer); err != nil {
return
if !b.SignedHeader.Producer.IsEmpty() {
// not empty
return errors.Wrap(ErrInvalidGenesis, "invalid producer")
}
if !b.SignedHeader.GenesisHash.IsEqual(&hash.Hash{}) {
// not empty
return errors.Wrap(ErrInvalidGenesis, "invalid genesis hash")
}
if !pk.IsEqual(b.SignedHeader.HSV.Signee) {
err = ErrNodePublicKeyNotMatch
return
if !b.SignedHeader.ParentHash.IsEqual(&hash.Hash{}) {
// not empty
return errors.Wrap(ErrInvalidGenesis, "invalid parent hash")
}
return b.Verify()
if !b.SignedHeader.MerkleRoot.IsEqual(&hash.Hash{}) {
// not empty
return errors.Wrap(ErrInvalidGenesis, "invalid merkle root")
}

return b.SignedHeader.VerifyHash()
}

// Timestamp returns the timestamp field of the block header.
Expand Down
Loading