|
|
package node
import ( "crypto/ecdsa" "encoding/hex" "fmt" "io/ioutil" "testing"
"github.com/arnaucube/slowlorisdb/core" "github.com/arnaucube/slowlorisdb/db" "github.com/stretchr/testify/assert" )
func newTestPoABlockchain() (*ecdsa.PrivateKey, *core.Blockchain, error) { dir, err := ioutil.TempDir("", "db") if err != nil { return nil, nil, err } db, err := db.New(dir) if err != nil { return nil, nil, err }
privK, err := core.NewKey() if err != nil { return nil, nil, err }
var authNodes []*ecdsa.PublicKey authNodes = append(authNodes, &privK.PublicKey)
bc := core.NewPoABlockchain(db, authNodes) return privK, bc, nil }
func TestNode(t *testing.T) { dir, err := ioutil.TempDir("", "db") assert.Nil(t, err) db, err := db.New(dir) assert.Nil(t, err)
privK, err := core.NewKey() assert.Nil(t, err)
dif := uint64(1) bc := core.NewBlockchain(db, dif) node, err := NewNode(privK, bc, true) assert.Nil(t, err)
assert.Equal(t, node.Addr, core.AddressFromPrivK(node.PrivK)) }
func TestNodeSignature(t *testing.T) { dir, err := ioutil.TempDir("", "db") assert.Nil(t, err) db, err := db.New(dir) assert.Nil(t, err)
privK, err := core.NewKey() assert.Nil(t, err)
dif := uint64(1) bc := core.NewBlockchain(db, dif) node, err := NewNode(privK, bc, true) assert.Nil(t, err)
m := []byte("test") sig, err := node.Sign(m) assert.Nil(t, err) pubK := node.PrivK.PublicKey assert.True(t, core.VerifySignature(&pubK, m, *sig)) }
func TestBlockFromPendingTxs(t *testing.T) { privK, bc, err := newTestPoABlockchain() assert.Nil(t, err)
node, err := NewNode(privK, bc, true) assert.Nil(t, err)
privK0, err := core.NewKey() assert.Nil(t, err) pubK0 := privK0.PublicKey privK1, err := core.NewKey() assert.Nil(t, err) pubK1 := privK1.PublicKey tx := core.NewTx(&pubK0, &pubK1, []core.Input{}, []core.Output{}) node.AddToPendingTxs(*tx) block, err := node.BlockFromPendingTxs() assert.Nil(t, err) assert.True(t, core.CheckBlockPoW(block, node.Bc.Difficulty)) assert.True(t, node.Bc.VerifyBlock(block)) }
func TestBlockFromPendingTxsIteration(t *testing.T) { privK, bc, err := newTestPoABlockchain() assert.Nil(t, err)
node, err := NewNode(privK, bc, true) assert.Nil(t, err)
privK0, err := core.NewKey() assert.Nil(t, err) pubK0 := privK0.PublicKey privK1, err := core.NewKey() assert.Nil(t, err) pubK1 := privK1.PublicKey
for i := 0; i < 10; i++ { tx := core.NewTx(&pubK0, &pubK1, []core.Input{}, []core.Output{}) node.AddToPendingTxs(*tx) } block, err := node.BlockFromPendingTxs() assert.Nil(t, err) assert.True(t, core.CheckBlockPoW(block, node.Bc.Difficulty)) assert.True(t, node.Bc.VerifyBlock(block)) }
func TestFromGenesisToTenBlocks(t *testing.T) { privK, bc, err := newTestPoABlockchain() assert.Nil(t, err)
node, err := NewNode(privK, bc, true) assert.Nil(t, err)
// create the genesis block
// genesisBlock sends 100 to pubK
genesisBlock, err := node.CreateGenesis(&privK.PublicKey, uint64(100)) assert.Nil(t, err) assert.NotEqual(t, genesisBlock.Signature, core.Signature{}) assert.NotEqual(t, genesisBlock.Hash, core.Hash{}) assert.True(t, node.Bc.VerifyBlock(genesisBlock))
// add the genesis block into the blockchain
err = node.Bc.AddBlock(genesisBlock) assert.Nil(t, err) assert.NotEqual(t, genesisBlock.Hash, core.Hash{}) assert.Equal(t, genesisBlock.Hash, node.Bc.LastBlock.Hash)
// add a tx sending coins to the pubK0
privK0, err := core.NewKey() assert.Nil(t, err) pubK0 := privK0.PublicKey
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(&privK.PublicKey, &pubK0, ins, outs)
// verify tx
txVerified := core.CheckTx(tx) assert.True(t, txVerified)
// then create a new block with the tx and add it to the blockchain
var txs []core.Tx txs = append(txs, *tx) block, err := node.NewBlock(txs) assert.Nil(t, err) err = node.Bc.AddBlock(block) assert.Nil(t, err)
balance, err := node.Bc.GetBalance(&pubK0) assert.Nil(t, err) fmt.Println(hex.EncodeToString(core.PackPubK(&pubK0)[:10])) fmt.Println("balance in pubK0", balance) assert.Equal(t, balance, uint64(100))
// add another tx sending coins to the pubK1
privK1, err := core.NewKey() assert.Nil(t, err) pubK1 := privK1.PublicKey
ins = []core.Input{} in = core.Input{ TxId: block.Txs[0].TxId, Vout: 0, Value: 10, } ins = append(ins, in) outs = []core.Output{} out0 = core.Output{ Value: 10, } outs = append(outs, out0) tx = core.NewTx(&pubK0, &pubK1, ins, outs)
// verify tx
txVerified = core.CheckTx(tx) assert.True(t, txVerified)
// then create a new block with the tx and add it to the blockchain
txs = []core.Tx{} txs = append(txs, *tx) block, err = node.NewBlock(txs) assert.Nil(t, err) err = node.Bc.AddBlock(block) assert.Nil(t, err)
balance, err = node.Bc.GetBalance(&pubK0) assert.Nil(t, err) fmt.Println(hex.EncodeToString(core.PackPubK(&pubK0)[:10])) 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)) }
|