diff --git a/core/blockchain.go b/core/blockchain.go index 2f32a59e..896fb21e 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -2,4 +2,5 @@ package core type Blockchain interface { RegisterObserver(observer BlockchainObserver) + SubscribeToEvents() } diff --git a/core/blockchain_logging_observer.go b/core/blockchain_logging_observer.go index 4ea5ae9b..61eab638 100644 --- a/core/blockchain_logging_observer.go +++ b/core/blockchain_logging_observer.go @@ -5,5 +5,5 @@ import "fmt" type BlockchainLoggingObserver struct{} func (blockchainObserver BlockchainLoggingObserver) NotifyBlockAdded(block Block) { - fmt.Println("Added block: %f", block.Number) + fmt.Printf("New block was added: %d\n", block.Number) } diff --git a/core/fake_blockchain_test.go b/core/fake_blockchain_test.go index fbc71bc0..6484d83e 100644 --- a/core/fake_blockchain_test.go +++ b/core/fake_blockchain_test.go @@ -12,6 +12,11 @@ import ( var _ = Describe("The fake blockchain", func() { + It("conforms to the Blockchain interface", func() { + var blockchain core.Blockchain = &fakes.Blockchain{} + Expect(blockchain).ShouldNot(BeNil()) + }) + It("lets the only observer know when a block was added", func() { blockchain := fakes.Blockchain{} blockchainObserver := &fakes.BlockchainObserver{} diff --git a/core/geth_blockchain.go b/core/geth_blockchain.go index 177314f6..b7df9d94 100644 --- a/core/geth_blockchain.go +++ b/core/geth_blockchain.go @@ -1,14 +1,43 @@ package core -import "fmt" +import ( + "fmt" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethclient" + "golang.org/x/net/context" + "reflect" +) -type GethBlockchain struct{} +type GethBlockchain struct { + client *ethclient.Client + observers []BlockchainObserver +} func NewGethBlockchain() *GethBlockchain { - fmt.Println("Creating Gethblockchain") - return &GethBlockchain{} + fmt.Println("Creating Geth Blockchain") + blockchain := GethBlockchain{} + client, _ := ethclient.Dial("/var/folders/b3/z7fhy7cs06q8d7y3_pwwt4x40000gn/T/ethereum_dev_mode/geth.ipc") + // TODO: handle error gracefully + blockchain.client = client + return &blockchain +} +func (blockchain GethBlockchain) notifyObservers(header *types.Header) { + block := Block{Number: header.Number} + for _, observer := range blockchain.observers { + observer.NotifyBlockAdded(block) + } } -func (blockchain *GethBlockchain) RegisterObserver(_ BlockchainObserver) { - +func (blockchain *GethBlockchain) RegisterObserver(observer BlockchainObserver) { + fmt.Printf("Registering observer: %v\n", reflect.TypeOf(observer)) + blockchain.observers = append(blockchain.observers, observer) +} + +func (blockchain *GethBlockchain) SubscribeToEvents() { + blocks := make(chan *types.Header, 10) + myContext := context.Background() + blockchain.client.SubscribeNewHead(myContext, blocks) + for block := range blocks { + blockchain.notifyObservers(block) + } } diff --git a/fakes/blockchain.go b/fakes/blockchain.go index 3c6c08ac..633f4d55 100644 --- a/fakes/blockchain.go +++ b/fakes/blockchain.go @@ -17,3 +17,6 @@ func (blockchain *Blockchain) AddBlock(block core.Block) { observer.NotifyBlockAdded(block) } } + +func (_ *Blockchain) SubscribeToEvents() { +} diff --git a/main.go b/main.go index 65411828..ee24ef17 100644 --- a/main.go +++ b/main.go @@ -1,13 +1,11 @@ package main import ( - "fmt" - "github.com/8thlight/vulcanizedb/core" ) func main() { - fmt.Println("Starting connection") var blockchain core.Blockchain = core.NewGethBlockchain() blockchain.RegisterObserver(core.BlockchainLoggingObserver{}) + blockchain.SubscribeToEvents() }