From 0a48c937b2049a33c2b49aa0cb7d77423542fe69 Mon Sep 17 00:00:00 2001 From: arnaucube Date: Fri, 12 Apr 2019 06:47:29 +0200 Subject: [PATCH] add test multiple nodes adding blocks --- core/blockchain.go | 24 +++++++----- core/tx.go | 11 ++++-- go.mod | 1 + go.sum | 9 +++++ node/node_test.go | 92 +++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 123 insertions(+), 14 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index 95d8856..63e71c7 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -9,6 +9,7 @@ import ( "strconv" "github.com/arnaucube/slowlorisdb/db" + log "github.com/sirupsen/logrus" lvldberrors "github.com/syndtr/goleveldb/leveldb/errors" ) @@ -102,7 +103,7 @@ func (bc *Blockchain) UpdateWalletsWithNewTx(tx *Tx) error { if err != nil { return err } - fmt.Println("sent-->: balance of " + hex.EncodeToString(PackPubK(tx.From)[:10]) + ": " + strconv.Itoa(int(balance))) + log.Info("sent-->: balance of " + hex.EncodeToString(PackPubK(tx.From)[:10]) + ": " + strconv.Itoa(int(balance))) } for _, out := range tx.Outputs { balanceBytes, err := bc.addressdb.Get(PackPubK(tx.To)) @@ -118,7 +119,7 @@ func (bc *Blockchain) UpdateWalletsWithNewTx(tx *Tx) error { if err != nil { return err } - fmt.Println("--> received: balance of " + hex.EncodeToString(PackPubK(tx.To)[:10]) + ": " + strconv.Itoa(int(balance))) + log.Info("--> received: balance of " + hex.EncodeToString(PackPubK(tx.To)[:10]) + ": " + strconv.Itoa(int(balance))) } return nil @@ -171,14 +172,14 @@ func (bc *Blockchain) verifyBlockSignature(block *Block) bool { } } if !signerIsMiner && len(bc.PoA.AuthMiners) > 0 { - fmt.Println("signer is not miner") + log.Error("signer is not miner") return false } // get the signature sig, err := SignatureFromBytes(block.Signature) if err != nil { - fmt.Println("error parsing signature") + log.Error("error parsing signature") return false } @@ -188,25 +189,30 @@ func (bc *Blockchain) verifyBlockSignature(block *Block) bool { func (bc *Blockchain) VerifyBlock(block *Block) bool { // verify block signature - // TODO for the moment just covered the case of PoA blockchain + // for the moment just covered the case of PoA blockchain if !bc.verifyBlockSignature(block) { - fmt.Println("signature verification error") + log.Error("signature verification error") return false } // verify timestamp + if block.Timestamp.Unix() < bc.LastBlock.Timestamp.Unix() { + return false + } // verify prev hash // check that the block.PrevHash is the blockchain current last block if !bytes.Equal(block.PrevHash[:], bc.LastBlock.Hash[:]) { - fmt.Println("block.PrevHash not equal to last block hash") + fmt.Println(block.PrevHash.String()) + fmt.Println(bc.LastBlock.Hash.String()) + log.Error("block.PrevHash not equal to last block hash") return false } // verify block height // check that the block height is the last block + 1 if block.Height != bc.LastBlock.Height+1 { - fmt.Println("block.Height error") + log.Error("block.Height error") return false } @@ -215,7 +221,7 @@ func (bc *Blockchain) VerifyBlock(block *Block) bool { for _, tx := range block.Txs { txVerified := CheckTx(&tx) if !txVerified { - fmt.Println("tx could not be verified") + log.Error("tx could not be verified") return false } } diff --git a/core/tx.go b/core/tx.go index ad43bc8..a157a13 100644 --- a/core/tx.go +++ b/core/tx.go @@ -3,7 +3,8 @@ package core import ( "crypto/ecdsa" "encoding/json" - "fmt" + + log "github.com/sirupsen/logrus" ) var GenesisHashTxInput = HashBytes([]byte("genesis")) @@ -55,11 +56,13 @@ func NewTx(from, to *ecdsa.PublicKey, in []Input, out []Output) *Tx { // CheckTx checks if the transaction is consistent func CheckTx(tx *Tx) bool { - // TODO check that inputs and outputs are not empty - // check that inputs == outputs totalIn := 0 for _, in := range tx.Inputs { + // check that inputs are not empty, to avoid spam tx + if in.Value == uint64(0) { + return false + } totalIn = totalIn + int(in.Value) } totalOut := 0 @@ -67,7 +70,7 @@ func CheckTx(tx *Tx) bool { totalOut = totalOut + int(out.Value) } if totalIn != totalOut { - fmt.Println("totalIn != totalOut") + log.Info("totalIn != totalOut") return false } diff --git a/go.mod b/go.mod index b62324d..c8a4f71 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/arnaucube/slowlorisdb go 1.12 require ( + github.com/sirupsen/logrus v1.4.1 github.com/stretchr/testify v1.3.0 github.com/syndtr/goleveldb v1.0.0 ) diff --git a/go.sum b/go.sum index 2c50525..b8409b9 100644 --- a/go.sum +++ b/go.sum @@ -1,22 +1,31 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 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/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/node/node_test.go b/node/node_test.go index d8bdc97..3da5ed9 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -137,7 +137,7 @@ func TestFromGenesisToTenBlocks(t *testing.T) { assert.NotEqual(t, genesisBlock.Hash, core.Hash{}) assert.Equal(t, genesisBlock.Hash, node.Bc.LastBlock.Hash) - // add another tx sending coins to the pubK0 + // add a tx sending coins to the pubK0 privK0, err := core.NewKey() assert.Nil(t, err) pubK0 := privK0.PublicKey @@ -215,3 +215,93 @@ func TestFromGenesisToTenBlocks(t *testing.T) { fmt.Println("balance in pubK0", balance) assert.Equal(t, balance, uint64(90)) } + +func TestMultipleNodesAddingBlocks(t *testing.T) { + dirA, err := ioutil.TempDir("", "dbA") + assert.Nil(t, err) + dbA, err := db.New(dirA) + assert.Nil(t, err) + dirB, err := ioutil.TempDir("", "dbB") + assert.Nil(t, err) + dbB, err := db.New(dirB) + assert.Nil(t, err) + + // node A + privKA, err := core.NewKey() + assert.Nil(t, err) + + // node B + privKB, err := core.NewKey() + assert.Nil(t, err) + + var authNodes []*ecdsa.PublicKey + authNodes = append(authNodes, &privKA.PublicKey) + authNodes = append(authNodes, &privKB.PublicKey) + bcA := core.NewPoABlockchain(dbA, authNodes) + bcB := core.NewPoABlockchain(dbB, authNodes) + + nodeA, err := NewNode(privKA, bcA, true) + assert.Nil(t, err) + nodeB, err := NewNode(privKB, bcB, true) + assert.Nil(t, err) + + // create genesisBlock that sends 100 to pubK of nodeA + genesisBlock, err := nodeA.CreateGenesis(&privKA.PublicKey, uint64(100)) + assert.Nil(t, err) + assert.NotEqual(t, genesisBlock.Signature, core.Signature{}) + assert.NotEqual(t, genesisBlock.Hash, core.Hash{}) + assert.True(t, nodeA.Bc.VerifyBlock(genesisBlock)) + // add the genesis block into the blockchain + assert.Equal(t, nodeA.Bc.LastBlock.Hash, nodeB.Bc.LastBlock.Hash) + err = nodeA.Bc.AddBlock(genesisBlock) + assert.Nil(t, err) + assert.NotEqual(t, genesisBlock.Hash, core.Hash{}) + assert.Equal(t, genesisBlock.Hash, nodeA.Bc.LastBlock.Hash) + err = nodeB.Bc.AddBlock(genesisBlock) + assert.Nil(t, err) + assert.NotEqual(t, genesisBlock.Hash, core.Hash{}) + assert.Equal(t, genesisBlock.Hash, nodeB.Bc.LastBlock.Hash) + assert.Equal(t, nodeA.Bc.LastBlock.Hash, nodeB.Bc.LastBlock.Hash) + + // add a tx sending coins to the pubKB (of nodeB) + var ins []core.Input + in := core.Input{ + TxId: genesisBlock.Txs[0].TxId, + Vout: 0, + Value: 100, + } + ins = append(ins, in) + var outs []core.Output + out0 := core.Output{ + Value: 10, + } + out1 := core.Output{ + Value: 90, + } + outs = append(outs, out0) + outs = append(outs, out1) + tx := core.NewTx(&privKA.PublicKey, &privKB.PublicKey, ins, outs) + // verify tx + assert.True(t, core.CheckTx(tx)) + // create a new block with the tx and add it to the blockchain + var txs []core.Tx + txs = append(txs, *tx) + block, err := nodeA.NewBlock(txs) + assert.Nil(t, err) + + // nodeA adds the block + err = nodeA.Bc.AddBlock(block) + assert.Nil(t, err) + // nodeB adds the block + err = nodeB.Bc.AddBlock(block) + assert.Nil(t, err) + + balanceA, err := nodeA.Bc.GetBalance(&privKA.PublicKey) + assert.Nil(t, err) + balanceB, err := nodeB.Bc.GetBalance(&privKB.PublicKey) + assert.Nil(t, err) + fmt.Println(hex.EncodeToString(core.PackPubK(&privKA.PublicKey)[:10])) + // check that the coins are moved from nodeA to nodeB + assert.Equal(t, balanceA, uint64(0)) + assert.Equal(t, balanceB, uint64(100)) +}