mirror of
https://github.com/arnaucube/blockchainIDsystem.git
synced 2026-02-07 02:56:43 +01:00
reconstructBlockchainFromBlock, deletePeerFromPeersList when conn is closed, REST routes: GenesisBlock, NextBlock, LastBlock
This commit is contained in:
64
blockchainIDsystem.postman_collection.json
Normal file
64
blockchainIDsystem.postman_collection.json
Normal file
@@ -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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -64,8 +64,9 @@ Needs the config.json file:
|
|||||||
|
|
||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
- When a peer connects to the network, sends his last Block, and receives the new Blocks from this last Block
|
- 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
|
- Delete the peer from the peers list when the connection is closed --> DONE
|
||||||
- REST:
|
- REST:
|
||||||
- endpoint to get if the address is in the blockchain (to verify users)
|
- 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
|
- parameters Date or LastUpdate on the structs needs to be updated values
|
||||||
|
- implement rsa encryption between peers
|
||||||
|
|||||||
@@ -1,8 +1,14 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/fatih/color"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Block struct {
|
type Block struct {
|
||||||
@@ -57,7 +63,11 @@ func (bc *Blockchain) blockExists(block Block) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bc *Blockchain) addBlock(block Block) error {
|
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 {
|
if len(bc.Blocks) > 0 {
|
||||||
bc.Blocks[len(bc.Blocks)-1].NextHash = block.Hash
|
bc.Blocks[len(bc.Blocks)-1].NextHash = block.Hash
|
||||||
} else {
|
} else {
|
||||||
@@ -67,3 +77,48 @@ func (bc *Blockchain) addBlock(block Block) error {
|
|||||||
|
|
||||||
return nil
|
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("---")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,5 +4,6 @@
|
|||||||
"restip": "127.0.0.1",
|
"restip": "127.0.0.1",
|
||||||
"restport": "3002",
|
"restport": "3002",
|
||||||
"serverip": "127.0.0.1",
|
"serverip": "127.0.0.1",
|
||||||
"serverport": "3000"
|
"serverport": "3000",
|
||||||
|
"serverrestport": "3002"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,4 +88,7 @@ func handleConn(conn net.Conn, connPeer Peer) {
|
|||||||
log.Println("Peer: " + conn.RemoteAddr().String() + " connection closed")
|
log.Println("Peer: " + conn.RemoteAddr().String() + " connection closed")
|
||||||
conn.Close()
|
conn.Close()
|
||||||
//TODO delete the peer from the outcomingPeersList
|
//TODO delete the peer from the outcomingPeersList
|
||||||
|
deletePeerFromPeersList(connPeer, &outcomingPeersList)
|
||||||
|
color.Yellow("peer deleted, current peerList:")
|
||||||
|
printPeersList()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ type Peer struct {
|
|||||||
ID string `json:"id"` //in the future, this will be the peer hash
|
ID string `json:"id"` //in the future, this will be the peer hash
|
||||||
IP string `json:"ip"`
|
IP string `json:"ip"`
|
||||||
Port string `json:"port"`
|
Port string `json:"port"`
|
||||||
|
RESTPort string `json:"restport"`
|
||||||
Role string `json:"role"` //client or server
|
Role string `json:"role"` //client or server
|
||||||
Conn net.Conn `json:"conn"`
|
Conn net.Conn `json:"conn"`
|
||||||
}
|
}
|
||||||
@@ -34,6 +35,7 @@ func main() {
|
|||||||
//runningPeer.ID = strconv.Itoa(randInt(1, 1000)) //0 is reserved for server
|
//runningPeer.ID = strconv.Itoa(randInt(1, 1000)) //0 is reserved for server
|
||||||
runningPeer.IP = config.IP
|
runningPeer.IP = config.IP
|
||||||
runningPeer.Port = config.Port
|
runningPeer.Port = config.Port
|
||||||
|
runningPeer.RESTPort = config.RESTPort
|
||||||
runningPeer.ID = hashPeer(runningPeer)
|
runningPeer.ID = hashPeer(runningPeer)
|
||||||
runningPeer.Role = "client"
|
runningPeer.Role = "client"
|
||||||
|
|
||||||
@@ -66,6 +68,7 @@ func main() {
|
|||||||
serverPeer.ID = hashPeer(serverPeer)
|
serverPeer.ID = hashPeer(serverPeer)
|
||||||
serverPeer.Role = "server"
|
serverPeer.Role = "server"
|
||||||
connectToPeer(serverPeer)
|
connectToPeer(serverPeer)
|
||||||
|
reconstructBlockchainFromBlock("http://"+config.IP+":"+config.ServerRESTPort, blockchain.GenesisBlock)
|
||||||
go acceptPeers(runningPeer)
|
go acceptPeers(runningPeer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,20 +44,6 @@ func messageHandler(peer Peer, msg Msg) {
|
|||||||
updateNetworkPeersList(peer.Conn, msg.PeersList)
|
updateNetworkPeersList(peer.Conn, msg.PeersList)
|
||||||
printPeersList()
|
printPeersList()
|
||||||
break
|
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":
|
case "Block":
|
||||||
if !blockchain.blockExists(msg.Block) {
|
if !blockchain.blockExists(msg.Block) {
|
||||||
blockchain.addBlock(msg.Block)
|
blockchain.addBlock(msg.Block)
|
||||||
|
|||||||
@@ -35,6 +35,14 @@ func peerIsInPeersList(p Peer, pl []Peer) int {
|
|||||||
}
|
}
|
||||||
return r
|
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 {
|
func appendPeerIfNoExist(pl PeersList, p Peer) PeersList {
|
||||||
i := peerIsInPeersList(p, pl.Peers)
|
i := peerIsInPeersList(p, pl.Peers)
|
||||||
if i == -1 {
|
if i == -1 {
|
||||||
|
|||||||
@@ -10,9 +10,10 @@ type Config struct {
|
|||||||
IP string `json:"ip"`
|
IP string `json:"ip"`
|
||||||
Port string `json:"port"`
|
Port string `json:"port"`
|
||||||
RestIP string `json:"restip"`
|
RestIP string `json:"restip"`
|
||||||
RestPort string `json:"restport"`
|
RESTPort string `json:"restport"`
|
||||||
ServerIP string `json:"serverip"`
|
ServerIP string `json:"serverip"`
|
||||||
ServerPort string `json:"serverport"`
|
ServerPort string `json:"serverport"`
|
||||||
|
ServerRESTPort string `json:"serverrestport"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var config Config
|
var config Config
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
|
"github.com/gorilla/mux"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Routes []Route
|
type Routes []Route
|
||||||
@@ -29,6 +30,24 @@ var routes = Routes{
|
|||||||
"/register",
|
"/register",
|
||||||
PostUser,
|
PostUser,
|
||||||
},
|
},
|
||||||
|
Route{
|
||||||
|
"GenesisBlock",
|
||||||
|
"GET",
|
||||||
|
"/blocks/genesis",
|
||||||
|
GenesisBlock,
|
||||||
|
},
|
||||||
|
Route{
|
||||||
|
"NextBlock",
|
||||||
|
"GET",
|
||||||
|
"/blocks/next/{blockhash}",
|
||||||
|
NextBlock,
|
||||||
|
},
|
||||||
|
Route{
|
||||||
|
"LastBlock",
|
||||||
|
"GET",
|
||||||
|
"/blocks/last",
|
||||||
|
LastBlock,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
type Address struct {
|
type Address struct {
|
||||||
@@ -65,3 +84,39 @@ func PostUser(w http.ResponseWriter, r *http.Request) {
|
|||||||
check(err)
|
check(err)
|
||||||
fmt.Fprintln(w, string(jResp))
|
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))
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ func runRestServer() {
|
|||||||
//run API
|
//run API
|
||||||
log.Println("server running")
|
log.Println("server running")
|
||||||
log.Print("port: ")
|
log.Print("port: ")
|
||||||
log.Println(config.RestPort)
|
log.Println(config.RESTPort)
|
||||||
router := NewRouter()
|
router := NewRouter()
|
||||||
headersOk := handlers.AllowedHeaders([]string{"X-Requested-With", "Access-Control-Allow-Origin"})
|
headersOk := handlers.AllowedHeaders([]string{"X-Requested-With", "Access-Control-Allow-Origin"})
|
||||||
originsOk := handlers.AllowedOrigins([]string{"*"})
|
originsOk := handlers.AllowedOrigins([]string{"*"})
|
||||||
methodsOk := handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "OPTIONS"})
|
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)))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user