Browse Source

add test multiple nodes adding blocks

master
arnaucube 5 years ago
parent
commit
0a48c937b2
5 changed files with 123 additions and 14 deletions
  1. +15
    -9
      core/blockchain.go
  2. +7
    -4
      core/tx.go
  3. +1
    -0
      go.mod
  4. +9
    -0
      go.sum
  5. +91
    -1
      node/node_test.go

+ 15
- 9
core/blockchain.go

@ -9,6 +9,7 @@ import (
"strconv" "strconv"
"github.com/arnaucube/slowlorisdb/db" "github.com/arnaucube/slowlorisdb/db"
log "github.com/sirupsen/logrus"
lvldberrors "github.com/syndtr/goleveldb/leveldb/errors" lvldberrors "github.com/syndtr/goleveldb/leveldb/errors"
) )
@ -102,7 +103,7 @@ func (bc *Blockchain) UpdateWalletsWithNewTx(tx *Tx) error {
if err != nil { if err != nil {
return err 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 { for _, out := range tx.Outputs {
balanceBytes, err := bc.addressdb.Get(PackPubK(tx.To)) balanceBytes, err := bc.addressdb.Get(PackPubK(tx.To))
@ -118,7 +119,7 @@ func (bc *Blockchain) UpdateWalletsWithNewTx(tx *Tx) error {
if err != nil { if err != nil {
return err 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 return nil
@ -171,14 +172,14 @@ func (bc *Blockchain) verifyBlockSignature(block *Block) bool {
} }
} }
if !signerIsMiner && len(bc.PoA.AuthMiners) > 0 { if !signerIsMiner && len(bc.PoA.AuthMiners) > 0 {
fmt.Println("signer is not miner")
log.Error("signer is not miner")
return false return false
} }
// get the signature // get the signature
sig, err := SignatureFromBytes(block.Signature) sig, err := SignatureFromBytes(block.Signature)
if err != nil { if err != nil {
fmt.Println("error parsing signature")
log.Error("error parsing signature")
return false return false
} }
@ -188,25 +189,30 @@ func (bc *Blockchain) verifyBlockSignature(block *Block) bool {
func (bc *Blockchain) VerifyBlock(block *Block) bool { func (bc *Blockchain) VerifyBlock(block *Block) bool {
// verify block signature // 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) { if !bc.verifyBlockSignature(block) {
fmt.Println("signature verification error")
log.Error("signature verification error")
return false return false
} }
// verify timestamp // verify timestamp
if block.Timestamp.Unix() < bc.LastBlock.Timestamp.Unix() {
return false
}
// verify prev hash // verify prev hash
// check that the block.PrevHash is the blockchain current last block // check that the block.PrevHash is the blockchain current last block
if !bytes.Equal(block.PrevHash[:], bc.LastBlock.Hash[:]) { 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 return false
} }
// verify block height // verify block height
// check that the block height is the last block + 1 // check that the block height is the last block + 1
if block.Height != bc.LastBlock.Height+1 { if block.Height != bc.LastBlock.Height+1 {
fmt.Println("block.Height error")
log.Error("block.Height error")
return false return false
} }
@ -215,7 +221,7 @@ func (bc *Blockchain) VerifyBlock(block *Block) bool {
for _, tx := range block.Txs { for _, tx := range block.Txs {
txVerified := CheckTx(&tx) txVerified := CheckTx(&tx)
if !txVerified { if !txVerified {
fmt.Println("tx could not be verified")
log.Error("tx could not be verified")
return false return false
} }
} }

+ 7
- 4
core/tx.go

@ -3,7 +3,8 @@ package core
import ( import (
"crypto/ecdsa" "crypto/ecdsa"
"encoding/json" "encoding/json"
"fmt"
log "github.com/sirupsen/logrus"
) )
var GenesisHashTxInput = HashBytes([]byte("genesis")) 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 // CheckTx checks if the transaction is consistent
func CheckTx(tx *Tx) bool { func CheckTx(tx *Tx) bool {
// TODO check that inputs and outputs are not empty
// check that inputs == outputs // check that inputs == outputs
totalIn := 0 totalIn := 0
for _, in := range tx.Inputs { 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) totalIn = totalIn + int(in.Value)
} }
totalOut := 0 totalOut := 0
@ -67,7 +70,7 @@ func CheckTx(tx *Tx) bool {
totalOut = totalOut + int(out.Value) totalOut = totalOut + int(out.Value)
} }
if totalIn != totalOut { if totalIn != totalOut {
fmt.Println("totalIn != totalOut")
log.Info("totalIn != totalOut")
return false return false
} }

+ 1
- 0
go.mod

@ -3,6 +3,7 @@ module github.com/arnaucube/slowlorisdb
go 1.12 go 1.12
require ( require (
github.com/sirupsen/logrus v1.4.1
github.com/stretchr/testify v1.3.0 github.com/stretchr/testify v1.3.0
github.com/syndtr/goleveldb v1.0.0 github.com/syndtr/goleveldb v1.0.0
) )

+ 9
- 0
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 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.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/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/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 h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 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/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.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.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= 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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 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.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 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 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 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= 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/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/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/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= 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= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

+ 91
- 1
node/node_test.go

@ -137,7 +137,7 @@ func TestFromGenesisToTenBlocks(t *testing.T) {
assert.NotEqual(t, genesisBlock.Hash, core.Hash{}) assert.NotEqual(t, genesisBlock.Hash, core.Hash{})
assert.Equal(t, genesisBlock.Hash, node.Bc.LastBlock.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() privK0, err := core.NewKey()
assert.Nil(t, err) assert.Nil(t, err)
pubK0 := privK0.PublicKey pubK0 := privK0.PublicKey
@ -215,3 +215,93 @@ func TestFromGenesisToTenBlocks(t *testing.T) {
fmt.Println("balance in pubK0", balance) fmt.Println("balance in pubK0", balance)
assert.Equal(t, balance, uint64(90)) 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))
}

Loading…
Cancel
Save