Browse Source

reconstructBlockchainFromBlock, deletePeerFromPeersList when conn is closed, REST routes: GenesisBlock, NextBlock, LastBlock

master
arnaucode 6 years ago
parent
commit
d9f2bca34c
12 changed files with 207 additions and 30 deletions
  1. +64
    -0
      blockchainIDsystem.postman_collection.json
  2. +3
    -2
      peer/README.md
  3. +55
    -0
      peer/blockchain.go
  4. +2
    -1
      peer/config.json
  5. +3
    -0
      peer/connections.go
  6. +8
    -5
      peer/main.go
  7. +0
    -14
      peer/messages.go
  8. BIN
      peer/peer
  9. +8
    -0
      peer/peers.go
  10. +7
    -6
      peer/readConfig.go
  11. +55
    -0
      peer/restRoutes.go
  12. +2
    -2
      peer/restServer.go

+ 64
- 0
blockchainIDsystem.postman_collection.json

@ -0,0 +1,64 @@
{
"variables": [],
"info": {
"name": "blockchainIDsystem",
"_postman_id": "4f8e319b-3c66-8ce8-ae09-091c53a281f1",
"description": "",
"schema": "https://schema.getpostman.com/json/collection/v2.0.0/collection.json"
},
"item": [
{
"name": "http://127.0.0.1:3002/register",
"request": {
"url": "http://127.0.0.1:3002/register",
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json",
"description": ""
}
],
"body": {
"mode": "raw",
"raw": "{\n\t\"address\": \"asdf1\"\n}"
},
"description": ""
},
"response": []
},
{
"name": "http://127.0.0.1:3002/peers",
"request": {
"url": "http://127.0.0.1:3002/peers",
"method": "GET",
"header": [],
"body": {},
"description": ""
},
"response": []
},
{
"name": "http://127.0.0.1:3002/blocks/genesis",
"request": {
"url": "http://127.0.0.1:3002/blocks/genesis",
"method": "GET",
"header": [],
"body": {},
"description": ""
},
"response": []
},
{
"name": "http://127.0.0.1:3004/blocks/next/a5B-sv24LTvo80ZvQg1uf3bmDwqyjU9LxVEtIrmkkn0=",
"request": {
"url": "http://127.0.0.1:3004/blocks/next/a5B-sv24LTvo80ZvQg1uf3bmDwqyjU9LxVEtIrmkkn0=",
"method": "GET",
"header": [],
"body": {},
"description": ""
},
"response": []
}
]
}

+ 3
- 2
peer/README.md

@ -64,8 +64,9 @@ Needs the config.json file:
## TODO
- When a peer connects to the network, sends his last Block, and receives the new Blocks from this last Block
- Delete the peer from the peers list when the connection is closed
- When a peer connects to the network, sends his last Block, and receives the new Blocks from this last Block --> DONE with REST petitions, maybe is better with tcp conn
- Delete the peer from the peers list when the connection is closed --> DONE
- REST:
- endpoint to get if the address is in the blockchain (to verify users)
- parameters Date or LastUpdate on the structs needs to be updated values
- implement rsa encryption between peers

+ 55
- 0
peer/blockchain.go

@ -1,8 +1,14 @@
package main
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"time"
"github.com/fatih/color"
)
type Block struct {
@ -57,7 +63,11 @@ func (bc *Blockchain) blockExists(block Block) bool {
}
return false
}
func (bc *Blockchain) addBlock(block Block) error {
if blockchain.blockExists(block) {
return errors.New("[Error adding Block]: Block already exists in the Blockchain")
}
if len(bc.Blocks) > 0 {
bc.Blocks[len(bc.Blocks)-1].NextHash = block.Hash
} else {
@ -67,3 +77,48 @@ func (bc *Blockchain) addBlock(block Block) error {
return nil
}
func reconstructBlockchainFromBlock(urlAPI string, h string) {
color.Yellow("reconstructing the blockchain from last block in memory")
var block Block
if h == "" {
//no genesis block yet
color.Green(urlAPI + "/blocks/genesis")
res, err := http.Get(urlAPI + "/blocks/genesis")
check(err)
body, err := ioutil.ReadAll(res.Body)
check(err)
err = json.Unmarshal(body, &block)
check(err)
color.Yellow("[New Block]: " + block.Hash)
err = blockchain.addBlock(block)
check(err)
} else {
block.NextHash = h
}
for block.NextHash != "" {
res, err := http.Get(urlAPI + "/blocks/next/" + block.Hash)
check(err)
body, err := ioutil.ReadAll(res.Body)
check(err)
err = json.Unmarshal(body, &block)
check(err)
color.Yellow("[New Block]: " + block.Hash)
err = blockchain.addBlock(block)
check(err)
}
blockchain.print()
}
func (bc *Blockchain) print() {
color.Green("Printing Blockchain stored in memory")
color.Green("Genesis Block: " + bc.GenesisBlock)
for _, b := range bc.Blocks {
color.Green("Block height:")
fmt.Println(b.Height)
color.Green("Hash: " + b.Hash)
color.Green("Date: " + b.Date.String())
color.Green("---")
}
}

+ 2
- 1
peer/config.json

@ -4,5 +4,6 @@
"restip": "127.0.0.1",
"restport": "3002",
"serverip": "127.0.0.1",
"serverport": "3000"
"serverport": "3000",
"serverrestport": "3002"
}

+ 3
- 0
peer/connections.go

@ -88,4 +88,7 @@ func handleConn(conn net.Conn, connPeer Peer) {
log.Println("Peer: " + conn.RemoteAddr().String() + " connection closed")
conn.Close()
//TODO delete the peer from the outcomingPeersList
deletePeerFromPeersList(connPeer, &outcomingPeersList)
color.Yellow("peer deleted, current peerList:")
printPeersList()
}

+ 8
- 5
peer/main.go

@ -11,11 +11,12 @@ import (
)
type Peer struct {
ID string `json:"id"` //in the future, this will be the peer hash
IP string `json:"ip"`
Port string `json:"port"`
Role string `json:"role"` //client or server
Conn net.Conn `json:"conn"`
ID string `json:"id"` //in the future, this will be the peer hash
IP string `json:"ip"`
Port string `json:"port"`
RESTPort string `json:"restport"`
Role string `json:"role"` //client or server
Conn net.Conn `json:"conn"`
}
var running bool
@ -34,6 +35,7 @@ func main() {
//runningPeer.ID = strconv.Itoa(randInt(1, 1000)) //0 is reserved for server
runningPeer.IP = config.IP
runningPeer.Port = config.Port
runningPeer.RESTPort = config.RESTPort
runningPeer.ID = hashPeer(runningPeer)
runningPeer.Role = "client"
@ -66,6 +68,7 @@ func main() {
serverPeer.ID = hashPeer(serverPeer)
serverPeer.Role = "server"
connectToPeer(serverPeer)
reconstructBlockchainFromBlock("http://"+config.IP+":"+config.ServerRESTPort, blockchain.GenesisBlock)
go acceptPeers(runningPeer)
}

+ 0
- 14
peer/messages.go

@ -44,20 +44,6 @@ func messageHandler(peer Peer, msg Msg) {
updateNetworkPeersList(peer.Conn, msg.PeersList)
printPeersList()
break
case "MyID":
color.Blue("MyID")
fmt.Println(msg.Content)
color.Green(peer.Conn.RemoteAddr().String())
peer.ID = msg.Content
searchPeerAndUpdate(peer)
//time.Sleep(1000 * time.Millisecond)
/*
updatePeersList(peer.Conn, msg.PeersList)
propagatePeersList(peer)
*/
printPeersList()
break
case "Block":
if !blockchain.blockExists(msg.Block) {
blockchain.addBlock(msg.Block)

BIN
peer/peer


+ 8
- 0
peer/peers.go

@ -35,6 +35,14 @@ func peerIsInPeersList(p Peer, pl []Peer) int {
}
return r
}
func deletePeerFromPeersList(p Peer, pl *PeersList) {
i := peerIsInPeersList(p, pl.Peers)
if i != -1 {
//delete peer from pl.Peers
pl.Peers = append(pl.Peers[:i], pl.Peers[i+1:]...)
}
}
func appendPeerIfNoExist(pl PeersList, p Peer) PeersList {
i := peerIsInPeersList(p, pl.Peers)
if i == -1 {

+ 7
- 6
peer/readConfig.go

@ -7,12 +7,13 @@ import (
//Config reads the config
type Config struct {
IP string `json:"ip"`
Port string `json:"port"`
RestIP string `json:"restip"`
RestPort string `json:"restport"`
ServerIP string `json:"serverip"`
ServerPort string `json:"serverport"`
IP string `json:"ip"`
Port string `json:"port"`
RestIP string `json:"restip"`
RESTPort string `json:"restport"`
ServerIP string `json:"serverip"`
ServerPort string `json:"serverport"`
ServerRESTPort string `json:"serverrestport"`
}
var config Config

+ 55
- 0
peer/restRoutes.go

@ -6,6 +6,7 @@ import (
"net/http"
"github.com/fatih/color"
"github.com/gorilla/mux"
)
type Routes []Route
@ -29,6 +30,24 @@ var routes = Routes{
"/register",
PostUser,
},
Route{
"GenesisBlock",
"GET",
"/blocks/genesis",
GenesisBlock,
},
Route{
"NextBlock",
"GET",
"/blocks/next/{blockhash}",
NextBlock,
},
Route{
"LastBlock",
"GET",
"/blocks/last",
LastBlock,
},
}
type Address struct {
@ -65,3 +84,39 @@ func PostUser(w http.ResponseWriter, r *http.Request) {
check(err)
fmt.Fprintln(w, string(jResp))
}
func GenesisBlock(w http.ResponseWriter, r *http.Request) {
var genesis Block
if len(blockchain.Blocks) >= 0 {
genesis = blockchain.Blocks[0]
}
jResp, err := json.Marshal(genesis)
check(err)
fmt.Fprintln(w, string(jResp))
}
func NextBlock(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
blockhash := vars["blockhash"]
currBlock, err := blockchain.getBlockByHash(blockhash)
check(err)
nextBlock, err := blockchain.getBlockByHash(currBlock.NextHash)
check(err)
jResp, err := json.Marshal(nextBlock)
check(err)
fmt.Fprintln(w, string(jResp))
}
func LastBlock(w http.ResponseWriter, r *http.Request) {
var genesis Block
if len(blockchain.Blocks) > 0 {
genesis = blockchain.Blocks[len(blockchain.Blocks)-1]
}
jResp, err := json.Marshal(genesis)
check(err)
fmt.Fprintln(w, string(jResp))
}

+ 2
- 2
peer/restServer.go

@ -11,10 +11,10 @@ func runRestServer() {
//run API
log.Println("server running")
log.Print("port: ")
log.Println(config.RestPort)
log.Println(config.RESTPort)
router := NewRouter()
headersOk := handlers.AllowedHeaders([]string{"X-Requested-With", "Access-Control-Allow-Origin"})
originsOk := handlers.AllowedOrigins([]string{"*"})
methodsOk := handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "OPTIONS"})
log.Fatal(http.ListenAndServe(":"+config.RestPort, handlers.CORS(originsOk, headersOk, methodsOk)(router)))
log.Fatal(http.ListenAndServe(":"+config.RESTPort, handlers.CORS(originsOk, headersOk, methodsOk)(router)))
}

Loading…
Cancel
Save