Skip to content

Commit

Permalink
DeleteWifi and Disconnectwifi (#190)
Browse files Browse the repository at this point in the history
* Added DHT Provide to Pull

After Pull the node announces that it can provide the link on dht

* Added method to store cid

* updated tests

* Added storeManifests and tests

StoreManifest first calls blockchain to get  the avaialble manifests and then fetch them and store them

* Added dht to store and get the number of repliactions

* corrected a go cehck

* Update blox.go

* Added Fetch available and Store to a time when blox starts

* Update example_test.go

* Update example_test.go

* Update example_test.go

* Adde check to make sure we are not storing an already stored link

* Added mechanism to make sure we do not get stuck on limit

* added deletewifi and disconnectwifi for mobile

* Disconnect hotspot if wifi and config exists

* Update example_test.go

* Update example_test.go
  • Loading branch information
ehsan6sha authored Dec 4, 2023
1 parent 69155ad commit 0c8943a
Show file tree
Hide file tree
Showing 8 changed files with 249 additions and 82 deletions.
53 changes: 52 additions & 1 deletion blockchain/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,12 @@ func (bl *FxBlockchain) serve(w http.ResponseWriter, r *http.Request) {
actionDeleteFulaConfig: func(from peer.ID, w http.ResponseWriter, r *http.Request) {
bl.handleDeleteFulaConfig(r.Context(), from, w, r)
},
actionDeleteWifi: func(from peer.ID, w http.ResponseWriter, r *http.Request) {
bl.handleDeleteWifi(r.Context(), from, w, r)
},
actionDisconnectWifi: func(from peer.ID, w http.ResponseWriter, r *http.Request) {
bl.handleDisconnectWifi(r.Context(), from, w, r)
},
}

// Look up the function in the map and call it
Expand Down Expand Up @@ -526,6 +532,51 @@ func (bl *FxBlockchain) handleDeleteFulaConfig(ctx context.Context, from peer.ID

}

func (bl *FxBlockchain) handleDeleteWifi(ctx context.Context, from peer.ID, w http.ResponseWriter, r *http.Request) {
log := log.With("action", actionDeleteWifi, "from", from)

// Parse the JSON body of the request into the DeleteWifiRequest struct
var req wifi.DeleteWifiRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
log.Error("failed to decode request: %v", err)
http.Error(w, "failed to decode request", http.StatusBadRequest)
return
}
log.Debugw("handleDeleteWifi received", "req", req)

out := wifi.DeleteWifi(ctx, req)

w.WriteHeader(http.StatusOK)
if err := json.NewEncoder(w).Encode(out); err != nil {
log.Error("failed to write response: %v", err)
http.Error(w, "failed to write response", http.StatusInternalServerError)
return
}

}
func (bl *FxBlockchain) handleDisconnectWifi(ctx context.Context, from peer.ID, w http.ResponseWriter, r *http.Request) {
log := log.With("action", actionDisconnectWifi, "from", from)

// Parse the JSON body of the request into the DeleteWifiRequest struct
var req wifi.DeleteWifiRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
log.Error("failed to decode request: %v", err)
http.Error(w, "failed to decode request", http.StatusBadRequest)
return
}
log.Debugw("handleDisconnectWifi received", "req", req)

out := wifi.DisconnectNamedWifi(ctx, req)

w.WriteHeader(http.StatusOK)
if err := json.NewEncoder(w).Encode(out); err != nil {
log.Error("failed to write response: %v", err)
http.Error(w, "failed to write response", http.StatusInternalServerError)
return
}

}

func (bl *FxBlockchain) SetAuth(ctx context.Context, on peer.ID, subject peer.ID, allow bool) error {
// Check if auth is for local host; if so, handle it locally.
if on == bl.h.ID() {
Expand Down Expand Up @@ -572,7 +623,7 @@ func (bl *FxBlockchain) authorized(pid peer.ID, action string) bool {
return true
}
switch action {
case actionBloxFreeSpace, actionWifiRemoveall, actionReboot, actionPartition, actionDeleteFulaConfig, actionSeeded, actionAccountExists, actionPoolCreate, actionPoolJoin, actionPoolCancelJoin, actionPoolRequests, actionPoolList, actionPoolVote, actionPoolLeave, actionManifestUpload, actionManifestStore, actionManifestAvailable, actionManifestRemove, actionManifestRemoveStorer, actionManifestRemoveStored:
case actionBloxFreeSpace, actionWifiRemoveall, actionReboot, actionPartition, actionDeleteWifi, actionDisconnectWifi, actionDeleteFulaConfig, actionSeeded, actionAccountExists, actionPoolCreate, actionPoolJoin, actionPoolCancelJoin, actionPoolRequests, actionPoolList, actionPoolVote, actionPoolLeave, actionManifestUpload, actionManifestStore, actionManifestAvailable, actionManifestRemove, actionManifestRemoveStorer, actionManifestRemoveStored:
bl.authorizedPeersLock.RLock()
_, ok := bl.authorizedPeers[pid]
bl.authorizedPeersLock.RUnlock()
Expand Down
77 changes: 77 additions & 0 deletions blockchain/blox.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package blockchain

import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"

"github.com/functionland/go-fula/wap/pkg/wifi"
"github.com/libp2p/go-libp2p/core/network"
"github.com/libp2p/go-libp2p/core/peer"
)
Expand Down Expand Up @@ -151,3 +154,77 @@ func (bl *FxBlockchain) DeleteFulaConfig(ctx context.Context, to peer.ID) ([]byt
}

}

func (bl *FxBlockchain) DeleteWifi(ctx context.Context, to peer.ID, r wifi.DeleteWifiRequest) ([]byte, error) {

if bl.allowTransientConnection {
ctx = network.WithUseTransient(ctx, "fx.blockchain")
}

var buf bytes.Buffer
if err := json.NewEncoder(&buf).Encode(r); err != nil {
return nil, err
}

req, err := http.NewRequestWithContext(ctx, http.MethodGet, "http://"+to.String()+".invalid/"+actionDeleteWifi, &buf)
if err != nil {
return nil, err
}
resp, err := bl.c.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
b, err := io.ReadAll(resp.Body)
switch {
case err != nil:
return nil, err
case resp.StatusCode != http.StatusAccepted:
// Attempt to parse the body as JSON.
if jsonErr := json.Unmarshal(b, &apiError); jsonErr != nil {
// If we can't parse the JSON, return the original body in the error.
return nil, fmt.Errorf("unexpected response: %d %s", resp.StatusCode, string(b))
}
// Return the parsed error message and description.
return nil, fmt.Errorf("unexpected response: %d %s - %s", resp.StatusCode, apiError.Message, apiError.Description)
default:
return b, nil
}
}

func (bl *FxBlockchain) DisconnectWifi(ctx context.Context, to peer.ID, r wifi.DeleteWifiRequest) ([]byte, error) {

if bl.allowTransientConnection {
ctx = network.WithUseTransient(ctx, "fx.blockchain")
}

var buf bytes.Buffer
if err := json.NewEncoder(&buf).Encode(r); err != nil {
return nil, err
}

req, err := http.NewRequestWithContext(ctx, http.MethodGet, "http://"+to.String()+".invalid/"+actionDisconnectWifi, &buf)
if err != nil {
return nil, err
}
resp, err := bl.c.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
b, err := io.ReadAll(resp.Body)
switch {
case err != nil:
return nil, err
case resp.StatusCode != http.StatusAccepted:
// Attempt to parse the body as JSON.
if jsonErr := json.Unmarshal(b, &apiError); jsonErr != nil {
// If we can't parse the JSON, return the original body in the error.
return nil, fmt.Errorf("unexpected response: %d %s", resp.StatusCode, string(b))
}
// Return the parsed error message and description.
return nil, fmt.Errorf("unexpected response: %d %s - %s", resp.StatusCode, apiError.Message, apiError.Description)
default:
return b, nil
}
}
8 changes: 8 additions & 0 deletions blockchain/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ const (
actionReboot = "reboot"
actionPartition = "partition"
actionDeleteFulaConfig = "delete-fula-config"
actionDeleteWifi = "delete-wifi"
actionDisconnectWifi = "disconnect-wifi"
)

type LinkWithLimit struct {
Expand Down Expand Up @@ -310,6 +312,8 @@ type Blockchain interface {
BloxFreeSpace(context.Context, peer.ID) ([]byte, error)
WifiRemoveall(context.Context, peer.ID) ([]byte, error)
Reboot(context.Context, peer.ID) ([]byte, error)
DeleteWifi(context.Context, peer.ID, wifi.DeleteWifiRequest) ([]byte, error)
DisconnectWifi(context.Context, peer.ID, wifi.DeleteWifiRequest) ([]byte, error)
Partition(context.Context, peer.ID) ([]byte, error)
DeleteFulaConfig(context.Context, peer.ID) ([]byte, error)
}
Expand Down Expand Up @@ -341,6 +345,8 @@ var requestTypes = map[string]reflect.Type{
actionReboot: reflect.TypeOf(wifi.RebootRequest{}),
actionPartition: reflect.TypeOf(wifi.PartitionRequest{}),
actionDeleteFulaConfig: reflect.TypeOf(wifi.DeleteFulaConfigRequest{}),
actionDeleteWifi: reflect.TypeOf(wifi.DeleteWifiRequest{}),
actionDisconnectWifi: reflect.TypeOf(wifi.DeleteWifiRequest{}),
}

var responseTypes = map[string]reflect.Type{
Expand Down Expand Up @@ -370,4 +376,6 @@ var responseTypes = map[string]reflect.Type{
actionReboot: reflect.TypeOf(wifi.RebootResponse{}),
actionPartition: reflect.TypeOf(wifi.PartitionResponse{}),
actionDeleteFulaConfig: reflect.TypeOf(wifi.DeleteFulaConfigResponse{}),
actionDeleteWifi: reflect.TypeOf(wifi.DeleteWifiResponse{}),
actionDisconnectWifi: reflect.TypeOf(wifi.DeleteWifiResponse{}),
}
65 changes: 19 additions & 46 deletions blox/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1123,7 +1123,7 @@ func Example_blserver() {
panic(err)
}
defer n1.Shutdown(ctx)
fmt.Printf("n1 Instantiated node in pool %s with ID: %s\n", poolName, h1.ID().String())
log.Debugf("n1 Instantiated node in pool %s with ID: %s\n", poolName, h1.ID().String())

// Instantiate the second node in the pool
pid2, _, err := crypto.GenerateECDSAKeyPair(rng)
Expand Down Expand Up @@ -1153,7 +1153,7 @@ func Example_blserver() {
panic(err)
}
defer n2.Shutdown(ctx)
fmt.Printf("n2 Instantiated node in pool %s with ID: %s\n", poolName, h2.ID().String())
log.Debugf("n2 Instantiated node in pool %s with ID: %s\n", poolName, h2.ID().String())

// Instantiate the third node in the pool
pid3, _, err := crypto.GenerateECDSAKeyPair(rng)
Expand Down Expand Up @@ -1183,7 +1183,7 @@ func Example_blserver() {
panic(err)
}
defer n3.Shutdown(ctx)
fmt.Printf("n3 Instantiated node in pool %s with ID: %s\n", poolName, h3.ID().String())
log.Debugf("n3 Instantiated node in pool %s with ID: %s\n", poolName, h3.ID().String())

if err = h1.Connect(ctx, peer.AddrInfo{ID: h2.ID(), Addrs: h2.Addrs()}); err != nil {
panic(err)
Expand All @@ -1194,12 +1194,13 @@ func Example_blserver() {

// Wait until the nodes discover each other
for {
if len(h1.Peerstore().Peers()) == 4 &&
len(h2.Peerstore().Peers()) == 4 &&
len(h3.Peerstore().Peers()) == 4 {
if len(h1.Peerstore().Peers()) >= 3 &&
len(h2.Peerstore().Peers()) >= 3 &&
len(h3.Peerstore().Peers()) >= 3 {
break
} else {
fmt.Printf("n1 Finally %s peerstore contains %d nodes:\n", h1.ID(), len(h1.Peerstore().Peers()))
h1Peers := h1.Peerstore().Peers()
log.Debugf("n1 Only %s peerstore contains %d nodes:\n", h1.ID(), len(h1Peers))
}
select {
case <-ctx.Done():
Expand All @@ -1210,21 +1211,21 @@ func Example_blserver() {
}

h1Peers := h1.Peerstore().Peers()
fmt.Printf("n1 Finally %s peerstore contains %d nodes:\n", h1.ID(), len(h1Peers))
log.Debugf("n1 Finally %s peerstore contains %d nodes:\n", h1.ID(), len(h1Peers))
for _, id := range h1Peers {
fmt.Printf("- %s\n", id)
log.Debugf("- %s\n", id)
}

h2Peers := h2.Peerstore().Peers()
fmt.Printf("n2 Finally %s peerstore contains %d nodes:\n", h2.ID(), len(h2Peers))
log.Debugf("n2 Finally %s peerstore contains %d nodes:\n", h2.ID(), len(h2Peers))
for _, id := range h2Peers {
fmt.Printf("- %s\n", id)
log.Debugf("- %s\n", id)
}

h3Peers := h3.Peerstore().Peers()
fmt.Printf("n3 Finally %s peerstore contains %d nodes:\n", h3.ID(), len(h3Peers))
log.Debugf("n3 Finally %s peerstore contains %d nodes:\n", h3.ID(), len(h3Peers))
for _, id := range h3Peers {
fmt.Printf("- %s\n", id)
log.Debugf("- %s\n", id)
}

// Instantiate the fourth node not in the pool
Expand Down Expand Up @@ -1262,7 +1263,7 @@ func Example_blserver() {
panic(err)
}
defer n4.Shutdown(ctx)
fmt.Printf("n4 Instantiated node in pool %s with ID: %s\n", poolName, h4.ID().String())
log.Debugf("n4 Instantiated node in pool %s with ID: %s\n", poolName, h4.ID().String())

n4.AnnounceJoinPoolRequestPeriodically(ctx)

Expand All @@ -1282,12 +1283,12 @@ func Example_blserver() {

for id, status := range members {
memberInfo := fmt.Sprintf("Member ID: %s, Status: %v", id.String(), status)
fmt.Println(memberInfo)
log.Debugln(memberInfo)
}
if len(members) >= 2 {
break
} else {
fmt.Println(members)
log.Debugln(members)
}
select {
case <-ctx.Done():
Expand All @@ -1298,9 +1299,9 @@ func Example_blserver() {
}

h4Peers := h4.Peerstore().Peers()
fmt.Printf("n4 Finally %s peerstore contains %d nodes:\n", h4.ID(), len(h4Peers))
log.Debugf("n4 Finally %s peerstore contains %d nodes:\n", h4.ID(), len(h4Peers))
for _, id := range h4Peers {
fmt.Printf("- %s\n", id)
log.Debugf("- %s\n", id)
}

//wait for 60 seconds
Expand All @@ -1319,34 +1320,6 @@ func Example_blserver() {
}

// Unordered output:
// n1 Instantiated node in pool 1 with ID: QmaUMRTBMoANXqpUbfARnXkw9esfz9LP2AjXRRr7YknDAT
// n2 Instantiated node in pool 1 with ID: QmPNZMi2LAhczsN2FoXXQng6YFYbSHApuP6RpKuHbBH9eF
// n3 Instantiated node in pool 1 with ID: QmYMEnv3GUKPNr34gePX2qQmBH4YEQcuGhQHafuKuujvMA
// n1 Finally QmaUMRTBMoANXqpUbfARnXkw9esfz9LP2AjXRRr7YknDAT peerstore contains 4 nodes:
// - QmaUMRTBMoANXqpUbfARnXkw9esfz9LP2AjXRRr7YknDAT
// - QmPNZMi2LAhczsN2FoXXQng6YFYbSHApuP6RpKuHbBH9eF
// - QmUg1bGBZ1rSNt3LZR7kKf9RDy3JtJLZZDZGKrzSP36TMe
// - QmYMEnv3GUKPNr34gePX2qQmBH4YEQcuGhQHafuKuujvMA
// n2 Finally QmPNZMi2LAhczsN2FoXXQng6YFYbSHApuP6RpKuHbBH9eF peerstore contains 4 nodes:
// - QmaUMRTBMoANXqpUbfARnXkw9esfz9LP2AjXRRr7YknDAT
// - QmPNZMi2LAhczsN2FoXXQng6YFYbSHApuP6RpKuHbBH9eF
// - QmUg1bGBZ1rSNt3LZR7kKf9RDy3JtJLZZDZGKrzSP36TMe
// - QmYMEnv3GUKPNr34gePX2qQmBH4YEQcuGhQHafuKuujvMA
// n3 Finally QmYMEnv3GUKPNr34gePX2qQmBH4YEQcuGhQHafuKuujvMA peerstore contains 4 nodes:
// - QmaUMRTBMoANXqpUbfARnXkw9esfz9LP2AjXRRr7YknDAT
// - QmPNZMi2LAhczsN2FoXXQng6YFYbSHApuP6RpKuHbBH9eF
// - QmUg1bGBZ1rSNt3LZR7kKf9RDy3JtJLZZDZGKrzSP36TMe
// - QmYMEnv3GUKPNr34gePX2qQmBH4YEQcuGhQHafuKuujvMA
// n4 Instantiated node in pool 1 with ID: QmUg1bGBZ1rSNt3LZR7kKf9RDy3JtJLZZDZGKrzSP36TMe
// n4 Finally QmUg1bGBZ1rSNt3LZR7kKf9RDy3JtJLZZDZGKrzSP36TMe peerstore contains 4 nodes:
// - QmYMEnv3GUKPNr34gePX2qQmBH4YEQcuGhQHafuKuujvMA
// - QmUg1bGBZ1rSNt3LZR7kKf9RDy3JtJLZZDZGKrzSP36TMe
// - QmaUMRTBMoANXqpUbfARnXkw9esfz9LP2AjXRRr7YknDAT
// - QmPNZMi2LAhczsN2FoXXQng6YFYbSHApuP6RpKuHbBH9eF
// Member ID: QmUg1bGBZ1rSNt3LZR7kKf9RDy3JtJLZZDZGKrzSP36TMe, Status: 1
// Member ID: QmYMEnv3GUKPNr34gePX2qQmBH4YEQcuGhQHafuKuujvMA, Status: 2
// Member ID: QmaUMRTBMoANXqpUbfARnXkw9esfz9LP2AjXRRr7YknDAT, Status: 2
// Member ID: QmPNZMi2LAhczsN2FoXXQng6YFYbSHApuP6RpKuHbBH9eF, Status: 2
// Voted on QmUg1bGBZ1rSNt3LZR7kKf9RDy3JtJLZZDZGKrzSP36TMe {"pool_id":1,"account":"QmUg1bGBZ1rSNt3LZR7kKf9RDy3JtJLZZDZGKrzSP36TMe","vote_value":true}
// Voted on QmUg1bGBZ1rSNt3LZR7kKf9RDy3JtJLZZDZGKrzSP36TMe {"pool_id":1,"account":"QmUg1bGBZ1rSNt3LZR7kKf9RDy3JtJLZZDZGKrzSP36TMe","vote_value":true}
// Voted on QmUg1bGBZ1rSNt3LZR7kKf9RDy3JtJLZZDZGKrzSP36TMe {"pool_id":1,"account":"QmUg1bGBZ1rSNt3LZR7kKf9RDy3JtJLZZDZGKrzSP36TMe","vote_value":true}
Expand Down
Loading

0 comments on commit 0c8943a

Please sign in to comment.