Browse Source

:x: Allow to delete data from blockchain storage

Ettore Di Giacinto 3 years ago
parent
commit
d53d396f24
5 changed files with 120 additions and 12 deletions
  1. 30 0
      README.md
  2. 40 7
      api/api.go
  3. 5 2
      cmd/api.go
  4. 6 3
      cmd/join.go
  5. 39 0
      pkg/blockchain/ledger.go

+ 30 - 0
README.md

@@ -141,6 +141,8 @@ By default edgevpn will listen on the `8080` port. See `edgevpn api --help` for
 
 ## :mag: API endpoint
 
+### GET
+
 #### `/api/users`
 
 Returns the users connected to services in the blockchain
@@ -157,6 +159,34 @@ Returns the machines connected to the VPN
 
 Returns the latest available blockchain
 
+#### `/api/ledger`
+
+Returns the current data in the ledger
+
+#### `/api/ledger/:bucket`
+
+Returns the current data in the ledger inside the `:bucket`
+
+#### `/api/ledger/:bucket/:key`
+
+Returns the current data in the ledger inside the `:bucket` at given `:key`
+
+### PUT
+
+#### `/api/ledger/:bucket/:key/:value`
+
+Puts `:value` in the ledger inside the `:bucket` at given `:key`
+
+### DELETE
+
+#### `/api/ledger/:bucket/:key`
+
+Deletes the `:key` into `:bucket` inside the ledger
+
+#### `/api/ledger/:bucket`
+
+Deletes the `:bucket` from the ledger
+
 ## :mailbox: Sending and receiving files
 
 ### :outbox_tray: Sending

+ 40 - 7
api/api.go

@@ -29,6 +29,7 @@ func API(l string, ledger *blockchain.Ledger) error {
 	ec := echo.New()
 	assetHandler := http.FileServer(getFileSystem())
 
+	// Get data from ledger
 	ec.GET("/api/files", func(c echo.Context) error {
 		list := []*types.File{}
 		for _, v := range ledger.CurrentData()[edgevpn.FilesLedgerKey] {
@@ -84,7 +85,6 @@ func API(l string, ledger *blockchain.Ledger) error {
 	ec.GET("/*", echo.WrapHandler(http.StripPrefix("/", assetHandler)))
 
 	ec.GET("/api/blockchain", func(c echo.Context) error {
-		//		c.SetHandler()
 		return c.JSON(http.StatusOK, ledger.BlockChain())
 	})
 
@@ -95,16 +95,17 @@ func API(l string, ledger *blockchain.Ledger) error {
 	ec.GET("/api/ledger/:bucket/:key", func(c echo.Context) error {
 		bucket := c.Param("bucket")
 		key := c.Param("key")
-		//		c.SetHandler()
 		return c.JSON(http.StatusOK, ledger.CurrentData()[bucket][key])
 	})
 
 	ec.GET("/api/ledger/:bucket", func(c echo.Context) error {
 		bucket := c.Param("bucket")
-		//		c.SetHandler()
 		return c.JSON(http.StatusOK, ledger.CurrentData()[bucket])
 	})
 
+	announcing := struct{ State string }{"Announcing"}
+
+	// Store arbitrary data
 	ec.PUT("/api/ledger/:bucket/:key/:value", func(c echo.Context) error {
 		bucket := c.Param("bucket")
 		key := c.Param("key")
@@ -113,15 +114,47 @@ func API(l string, ledger *blockchain.Ledger) error {
 		put, cancel := context.WithCancel(context.Background())
 		ledger.Announce(put, 5*time.Second, func() {
 			v, exists := ledger.CurrentData()[bucket][key]
-			if !exists || string(v) != value {
+			switch {
+			case !exists || string(v) != value:
 				ledger.Add(bucket, map[string]interface{}{key: value})
+			case exists && string(v) == value:
+				cancel()
+			}
+		})
+		return c.JSON(http.StatusOK, announcing)
+	})
+
+	// Delete data from ledger
+	ec.DELETE("/api/ledger/:bucket", func(c echo.Context) error {
+		bucket := c.Param("bucket")
+
+		put, cancel := context.WithCancel(context.Background())
+		ledger.Announce(put, 5*time.Second, func() {
+			_, exists := ledger.CurrentData()[bucket]
+			if exists {
+				ledger.DeleteBucket(bucket)
+			} else {
+				cancel()
 			}
-			if exists && string(v) == value {
+		})
+		return c.JSON(http.StatusOK, announcing)
+	})
+
+	ec.DELETE("/api/ledger/:bucket/:key", func(c echo.Context) error {
+		bucket := c.Param("bucket")
+		key := c.Param("key")
+
+		put, cancel := context.WithCancel(context.Background())
+		ledger.Announce(put, 5*time.Second, func() {
+			_, exists := ledger.CurrentData()[bucket][key]
+			if exists {
+				ledger.Delete(bucket, key)
+			} else {
 				cancel()
 			}
 		})
-		//		c.SetHandler()
-		return c.JSON(http.StatusOK, "Announcing")
+		return c.JSON(http.StatusOK, announcing)
 	})
+
 	return ec.Start(l)
 }

+ 5 - 2
cmd/api.go

@@ -9,8 +9,11 @@ import (
 
 func API() cli.Command {
 	return cli.Command{
-		Name:        "api",
-		Description: "api starts an http server to display network informations",
+		Name:  "api",
+		Usage: "Starts an http server to display network informations",
+		Description: `Start listening locally, providing an API for the network.
+A simple UI interface is available to display network data.`,
+		UsageText: "edgevpn api",
 		Flags: append(CommonFlags,
 			&cli.StringFlag{
 				Name:  "listen",

+ 6 - 3
cmd/join.go

@@ -8,9 +8,12 @@ import (
 
 func Join() cli.Command {
 	return cli.Command{
-		Name:        "join",
-		Description: "join the network without activating any interface",
-		Flags:       CommonFlags,
+		Name:  "join",
+		Usage: "Join the network without activating any interface",
+		Description: `Connect over the p2p network without establishing a VPN.
+Useful for setting up relays or hop nodes to improve the network connectivity.`,
+		UsageText: "edgevpn join",
+		Flags:     CommonFlags,
 		Action: func(c *cli.Context) error {
 			e := edgevpn.New(cliToOpts(c)...)
 

+ 39 - 0
pkg/blockchain/ledger.go

@@ -172,6 +172,45 @@ func (l *Ledger) Add(b string, s map[string]interface{}) {
 	l.writeData(current)
 }
 
+// Deletes data from the blockchain
+func (l *Ledger) Delete(b string, k string) {
+	l.Lock()
+	new := make(map[string]map[string]Data)
+	for bb, kk := range l.lastBlock().Storage {
+		if _, exists := new[bb]; !exists {
+			new[bb] = make(map[string]Data)
+		}
+		// Copy all keys/v except b/k
+		for kkk, v := range kk {
+			if !(bb == b && kkk == k) {
+				new[bb][kkk] = v
+			}
+		}
+	}
+	l.Unlock()
+	l.writeData(new)
+}
+
+// Deletes data from the blockchain
+func (l *Ledger) DeleteBucket(b string) {
+	l.Lock()
+	new := make(map[string]map[string]Data)
+	for bb, kk := range l.lastBlock().Storage {
+		// Copy all except the specified bucket
+		if bb == b {
+			continue
+		}
+		if _, exists := new[bb]; !exists {
+			new[bb] = make(map[string]Data)
+		}
+		for kkk, v := range kk {
+			new[bb][kkk] = v
+		}
+	}
+	l.Unlock()
+	l.writeData(new)
+}
+
 func (l *Ledger) writeData(s map[string]map[string]Data) {
 	newBlock := l.lastBlock().NewBlock(s)