Skip to content

Commit

Permalink
Merge branch 'dev' of https://github.com/ubclaunchpad/cumulus into 93…
Browse files Browse the repository at this point in the history
…-create-common-folder
  • Loading branch information
david-julien committed Jul 13, 2017
2 parents 6563c96 + f4f8b68 commit 997158a
Show file tree
Hide file tree
Showing 9 changed files with 254 additions and 50 deletions.
39 changes: 27 additions & 12 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,10 @@ func Run(cfg conf.Config) {
go peer.MaintainConnections()

// Request the blockchain.
log.Info("Requesting blockchain from peers... ")
RequestBlockChain()
if chain == nil {
log.Info("Request blockchain from peers not yet implemented.")
initializeChain()
}

// Return to command line.
select {} // Hang main thread. Everything happens in goroutines from here
Expand All @@ -123,19 +125,28 @@ func ConnectAndDiscover(target string) {
// on peers whos RequestHandlers have been overridden.
func RequestHandler(req *msg.Request) msg.Response {
res := msg.Response{ID: req.ID}
typeErr := msg.NewProtocolError(msg.InvalidResourceType,
"Invalid resource type")
paramErr := msg.NewProtocolError(msg.InvalidResourceType,
"Invalid request parameter, blockNumber must be uint32.")

switch req.ResourceType {
case msg.ResourcePeerInfo:
res.Resource = peer.PStore.Addrs()
case msg.ResourceBlock:
work := BlockWork{}
BlockWorkQueue <- work
case msg.ResourceTransaction:
work := TransactionWork{}
TransactionWorkQueue <- work
blockNumber, ok := req.Params["blockNumber"].(uint32)
if ok {
blk, err := chain.CopyBlockByIndex(blockNumber)
if err != nil {
res.Error = paramErr
} else {
res.Resource = blk
}
} else {
res.Error = paramErr
}
default:
res.Error = msg.NewProtocolError(msg.InvalidResourceType,
"Invalid resource type")
res.Error = typeErr
}

return res
Expand Down Expand Up @@ -191,13 +202,17 @@ func initializeWorkers() {
}
}

// initializeChain creates the blockchain for the node.
func initializeChain() {
chain, _ = blockchain.NewValidTestChainAndBlock()
// TODO: Check if chain exists on disk.
// TODO: If not, request chain from peers.
}

// killWorkers kills all workers.
func killWorkers() {
for i := 0; i < nWorkers; i++ {
QuitChan <- i
workers[i] = nil
}
}

// RequestBlockChain asks existing peers for a copy of the blockchain.
func RequestBlockChain() {}
89 changes: 67 additions & 22 deletions app/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"time"

log "github.com/Sirupsen/logrus"
"github.com/stretchr/testify/assert"
"github.com/ubclaunchpad/cumulus/blockchain"
"github.com/ubclaunchpad/cumulus/msg"
)
Expand All @@ -13,6 +14,15 @@ func init() {
log.SetLevel(log.InfoLevel)
}

func createNewBlockRequest(blockNumber interface{}) *msg.Request {
params := make(map[string]interface{}, 1)
params["blockNumber"] = blockNumber
return &msg.Request{
ResourceType: msg.ResourceBlock,
Params: params,
}
}

func TestKillWorkers(t *testing.T) {
intializeQueues()
time.Sleep(20 * time.Millisecond)
Expand Down Expand Up @@ -91,28 +101,63 @@ func TestPushHandlerNewTestTransaction(t *testing.T) {
// Add more here...
}

func TestRequestHandlerNewBlock(t *testing.T) {
intializeQueues()
push := msg.Request{ResourceType: msg.ResourceBlock}
RequestHandler(&push)
select {
case _, ok := <-BlockWorkQueue:
if !ok {
t.FailNow()
}
}
// Add more here...
func TestRequestHandlerNewBlockOK(t *testing.T) {
initializeChain()

// Set up a request (requesting block 0)
blockNumber := uint32(0)
req := createNewBlockRequest(blockNumber)

resp := RequestHandler(req)
block, ok := resp.Resource.(*blockchain.Block)

// Assertion time!
assert.True(t, ok, "resource should contain block")
assert.Equal(t, block.BlockNumber, blockNumber,
"block number should be "+string(blockNumber))
}

func TestRequestHandlerNewTestTransaction(t *testing.T) {
intializeQueues()
push := msg.Request{ResourceType: msg.ResourceTransaction}
RequestHandler(&push)
select {
case _, ok := <-TransactionWorkQueue:
if !ok {
t.FailNow()
}
}
// Add more here...
func TestRequestHandlerNewBlockBadParams(t *testing.T) {
initializeChain()

// Set up a request.
blockNumber := "definitelynotanindex"
req := createNewBlockRequest(blockNumber)

resp := RequestHandler(req)
block, ok := resp.Resource.(*blockchain.Block)

// Make sure request failed.
assert.False(t, ok, "resource should not contain block")
assert.Nil(t, block, "resource should not contain block")
}

func TestRequestHandlerNewBlockBadType(t *testing.T) {
initializeChain()

// Set up a request.
req := createNewBlockRequest("doesntmatter")
req.ResourceType = 25

resp := RequestHandler(req)
block, ok := resp.Resource.(*blockchain.Block)

// Make sure request failed.
assert.False(t, ok, "resource should not contain block")
assert.Nil(t, block, "resource should not contain block")
}

func TestRequestHandlerPeerInfo(t *testing.T) {
initializeChain()

// Set up a request.
req := createNewBlockRequest("doesntmatter")
req.ResourceType = msg.ResourcePeerInfo

resp := RequestHandler(req)
res := resp.Resource

// Make sure request did not fail.
assert.NotNil(t, res, "resource should contain peer info")
// Assert peer address returned valid.
}
8 changes: 7 additions & 1 deletion app/worker.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package app

import log "github.com/Sirupsen/logrus"
import (
log "github.com/Sirupsen/logrus"
"github.com/ubclaunchpad/cumulus/miner"
)

// nWorkers is how many workers this node has.
const nWorkers = 10
Expand Down Expand Up @@ -74,6 +77,9 @@ func (w *AppWorker) HandleBlock(work BlockWork) {
ok, _ := chain.ValidBlock(work.Block)
if ok {
chain.AppendBlock(work.Block)
if miner.IsMining() {
miner.RestartMiner(chain, work.Block)
}
}

// Respond to the request if a response method was provided.
Expand Down
13 changes: 13 additions & 0 deletions blockchain/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package blockchain

import (
"encoding/gob"
"errors"
"io"
)

Expand Down Expand Up @@ -67,3 +68,15 @@ func (bc *BlockChain) ContainsTransaction(t *Transaction, start, stop uint32) (b
}
return false, 0, 0
}

// CopyLocalBlockByIndex returns a copy of a block in the local chain by index.
func (bc *BlockChain) CopyBlockByIndex(i uint32) (*Block, error) {
if i >= 0 && i < uint32(len(bc.Blocks)) {
blk := bc.Blocks[i]
b := *blk
b.Transactions = make([]*Transaction, len(blk.Transactions))
copy(b.Transactions, blk.Transactions)
return &b, nil
}
return nil, errors.New("block request out of bounds")
}
15 changes: 15 additions & 0 deletions blockchain/blockchain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package blockchain

import (
"bytes"
"reflect"
"testing"

log "github.com/Sirupsen/logrus"
Expand All @@ -23,3 +24,17 @@ func TestEncodeDecodeBlockChain(t *testing.T) {
t.Fail()
}
}

func TestCopyBlock(t *testing.T) {
bc, _ := NewValidTestChainAndBlock()
b, _ := bc.CopyBlockByIndex(0)

if !reflect.DeepEqual(b, bc.Blocks[0]) {
t.FailNow()
}

// Enforce copy.
if b == bc.Blocks[0] {
t.FailNow()
}
}
20 changes: 16 additions & 4 deletions glide.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 11 additions & 1 deletion glide.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,14 @@ import:
- package: github.com/spf13/cobra
- package: github.com/spf13/viper
- package: github.com/spf13/pflag
- package: github.com/abiosoft/ishell
- package: github.com/onsi/ginkgo
version: ^1.3.1
subpackages:
- ginkgo
- package: github.com/onsi/gomega
version: ^1.1.0
- package: github.com/stretchr/testify
version: ~1.1.4
subpackages:
- assert
- package: github.com/abiosoft/ishell
Loading

0 comments on commit 997158a

Please sign in to comment.