diff --git a/README.md b/README.md index 61ccd280..0edb9bf2 100644 --- a/README.md +++ b/README.md @@ -1,54 +1,43 @@ -![Coverage](https://img.shields.io/badge/Coverage-48.1%25-yellow) +![Coverage](https://img.shields.io/badge/Coverage-0.0%25-red) # b7s daemon -`blockless` the peer to peer networking daemon for the blockless network. +b7s is a peer-to-peer networking daemon for the blockless network. It is supported on Windows, Linux, and MacOS platforms for both x64 and arm64 architectures. -Supported Platforms +## Installation -| OS | arm64 | x64 | -| ------- | ----- | --- | -| Windows | | x | -| Linux | x | x | -| MacOS | x | x | - -Using **curl**: +You can install b7s using either curl or wget: ```bash +# using curl sudo sh -c "curl https://raw.githubusercontent.com/blocklessnetwork/b7s/main/download.sh | bash" -``` -Using **wget**: - -```bash +# using wget sudo sh -c "wget https://raw.githubusercontent.com/blocklessnetwork/b7s/main/download.sh -v -O download.sh; chmod +x download.sh; ./download.sh; rm -rf download.sh" ``` -Use `docker` see docker [docs](docker/README.md) +You can also use Docker to install b7s. See the [Docker documentation](https://chat.openai.com/chat/docker/README.md) for more information. -## usage +Usage +b7s can be run with a number of commands and flags: -commands -`b7s [command]` +Commands: -- `help` display help menu -- `keygen` generate identity keys for the node +- `help`: display the help menu +- `keygen`: generate identity keys for the node + Flags: -flags -`b7s --flag value` +- `config`: path to the configuration file +- `out`: style of logging used in the daemon (rich, text, or json) + For example: -- `config` path to the configuration file -- `out` style of logging used in the daemon (rich|text|json) - -```bash -b7s --config=../configs/head-config.yaml --out=json -``` +## Dependencies -## depends on +b7s depends on the following repositories: -- [blocklessnetwork/runtime](https://github.com/blocklessnetwork/runtime) -- [blocklessnetwork/orchestration-chain](https://github.com/blocklessnetwork/orchestration-chain) +- blocklessnetwork/runtime +- blocklessnetwork/orchestration-chain -## contributing +## Contributing -see [src/readme](src/README.md) +See src/README for information on contributing to the b7s project. diff --git a/configs/head-config.yaml b/configs/head-config.yaml index 238d3e7a..9a71278e 100644 --- a/configs/head-config.yaml +++ b/configs/head-config.yaml @@ -2,7 +2,7 @@ node: name: head#1 ip: 0.0.0.0 port: 9527 - key_path: /Users/derekanderson/Projects/blockless/net2/configs/testkeys/priv.bin + key_path: /Users/derekanderson/Projects/blockless/net2/configs/testkeys/ident1/priv.bin use_static_keys: true workspace_root: /tmp/head runtime_path: /tmp/runtime diff --git a/configs/testkeys/identity b/configs/testkeys/ident1/identity similarity index 100% rename from configs/testkeys/identity rename to configs/testkeys/ident1/identity diff --git a/configs/testkeys/priv.bin b/configs/testkeys/ident1/priv.bin similarity index 100% rename from configs/testkeys/priv.bin rename to configs/testkeys/ident1/priv.bin diff --git a/configs/testkeys/pub.bin b/configs/testkeys/ident1/pub.bin similarity index 100% rename from configs/testkeys/pub.bin rename to configs/testkeys/ident1/pub.bin diff --git a/configs/testkeys/ident2/identity b/configs/testkeys/ident2/identity new file mode 100644 index 00000000..570f85da --- /dev/null +++ b/configs/testkeys/ident2/identity @@ -0,0 +1 @@ +12D3KooWQrN5U3BApv4JYjE5HyKXFKkRF2U8c5FgK3zMPjzkZTpQ \ No newline at end of file diff --git a/configs/testkeys/ident2/priv.bin b/configs/testkeys/ident2/priv.bin new file mode 100644 index 00000000..17a09c62 --- /dev/null +++ b/configs/testkeys/ident2/priv.bin @@ -0,0 +1,2 @@ +@!Y Fgob\Mɏdn +o}mVz wC5 \ No newline at end of file diff --git a/configs/testkeys/ident2/pub.bin b/configs/testkeys/ident2/pub.bin new file mode 100644 index 00000000..de24a2ae --- /dev/null +++ b/configs/testkeys/ident2/pub.bin @@ -0,0 +1,2 @@ + b\Mɏdn +o}mVz wC5 \ No newline at end of file diff --git a/configs/worker-config.yaml b/configs/worker-config.yaml index 1c228df9..ea93c47c 100644 --- a/configs/worker-config.yaml +++ b/configs/worker-config.yaml @@ -3,9 +3,9 @@ node: ip: 0.0.0.0 # 0 means random port port: 0 - # join the blockless network by boot strapping to one of our worker nodes + key_path: /Users/derekanderson/Projects/blockless/net2/configs/testkeys/ident2/priv.bin boot_nodes: - - /ip4/147.75.84.103/tcp/32536/p2p/12D3KooWDCELEqCuHGqqRiMwSjPFLAKnVjL6mGVpSHASmmxTqovc + - /ip4/0.0.0.0/tcp/9527/p2p/12D3KooWH9GerdSEroL2nqjpd2GuE5dwmqNi7uHX7FoywBdKcP4q workspace_root: /tmp/worker runtime_path: /tmp/runtime rest: diff --git a/src/12D3KooWQrN5U3BApv4JYjE5HyKXFKkRF2U8c5FgK3zMPjzkZTpQ_appDb/OPTIONS-000003 b/src/12D3KooWQrN5U3BApv4JYjE5HyKXFKkRF2U8c5FgK3zMPjzkZTpQ_appDb/OPTIONS-000003 new file mode 100644 index 00000000..1dd3648f --- /dev/null +++ b/src/12D3KooWQrN5U3BApv4JYjE5HyKXFKkRF2U8c5FgK3zMPjzkZTpQ_appDb/OPTIONS-000003 @@ -0,0 +1,45 @@ +[Version] + pebble_version=0.1 + +[Options] + bytes_per_sync=524288 + cache_size=8388608 + cleaner=delete + compaction_debt_concurrency=1073741824 + comparer=leveldb.BytewiseComparator + disable_wal=false + flush_delay_delete_range=0s + flush_delay_range_key=0s + flush_split_bytes=4194304 + format_major_version=1 + l0_compaction_concurrency=10 + l0_compaction_file_threshold=500 + l0_compaction_threshold=4 + l0_stop_writes_threshold=12 + lbase_max_bytes=67108864 + max_concurrent_compactions=1 + max_manifest_file_size=134217728 + max_open_files=1000 + mem_table_size=4194304 + mem_table_stop_writes_threshold=2 + min_deletion_rate=0 + merger=pebble.concatenate + read_compaction_rate=16000 + read_sampling_multiplier=16 + strict_wal_tail=true + table_cache_shards=8 + table_property_collectors=[] + validate_on_ingest=false + wal_dir= + wal_bytes_per_sync=0 + max_writer_concurrency=0 + force_writer_parallelism=false + +[Level "0"] + block_restart_interval=16 + block_size=4096 + compression=Snappy + filter_policy=none + filter_type=table + index_block_size=4096 + target_file_size=2097152 diff --git a/src/controller/controller.go b/src/controller/controller.go index 5579ca87..1103f4eb 100644 --- a/src/controller/controller.go +++ b/src/controller/controller.go @@ -11,14 +11,12 @@ import ( "github.com/blocklessnetworking/b7s/src/messaging" "github.com/blocklessnetworking/b7s/src/models" "github.com/blocklessnetworking/b7s/src/repository" - "github.com/cockroachdb/pebble" pubsub "github.com/libp2p/go-libp2p-pubsub" log "github.com/sirupsen/logrus" ) func IsFunctionInstalled(ctx context.Context, functionId string) (models.FunctionManifest, error) { - appDb := ctx.Value("appDb").(*pebble.DB) - functionManifestString, err := db.Value(appDb, functionId) + functionManifestString, err := db.GetString(ctx, functionId) functionManifest := models.FunctionManifest{} json.Unmarshal([]byte(functionManifestString), &functionManifest) @@ -64,7 +62,7 @@ func MsgInstallFunction(ctx context.Context, installRequest models.RequestFuncti ManifestUrl: manifestPath, } - log.Debug("request to message peer for install function") + log.Info("request to message peer for install function ", msg.ManifestUrl) messaging.PublishMessage(ctx, ctx.Value("topic").(*pubsub.Topic), msg) } diff --git a/src/daemon/daemon.go b/src/daemon/daemon.go index c6288d62..ed30566d 100644 --- a/src/daemon/daemon.go +++ b/src/daemon/daemon.go @@ -26,6 +26,8 @@ import ( func Run(cmd *cobra.Command, args []string, configPath string) { topicName := "blockless/b7s/general" ctx := context.Background() + ctx = context.WithValue(ctx, "topicName", topicName) + ex, err := os.Executable() if err != nil { log.Warn(err) @@ -53,13 +55,19 @@ func Run(cmd *cobra.Command, args []string, configPath string) { ctx = setupChannels(ctx) // create a new libp2p host - host := host.NewHost(ctx, port, config.C.Node.IP) - ctx = context.WithValue(ctx, "host", host) + h := host.NewHost(ctx, port, config.C.Node.IP) + ctx = context.WithValue(ctx, "host", h) // set appdb config - appDb := db.Get(exPath + "/" + host.ID().Pretty() + "_appDb") + appDb := db.GetDb(exPath + "/" + h.ID().Pretty() + "_appDb") ctx = context.WithValue(ctx, "appDb", appDb) + n := &host.ConnectedNotifee{ + Ctx: ctx, + } + + h.Network().Notify(n) + // response memstore // todo flush memstore occasionally executionResponseMemStore := memstore.NewReqRespStore() @@ -70,7 +78,7 @@ func Run(cmd *cobra.Command, args []string, configPath string) { go listenToChannels(ctx) // pubsub topics from p2p - topic := messaging.Subscribe(ctx, host, topicName) + topic := messaging.Subscribe(ctx, h, topicName) ctx = context.WithValue(ctx, "topic", topic) // start health monitoring @@ -86,7 +94,7 @@ func Run(cmd *cobra.Command, args []string, configPath string) { defer ticker.Stop() // discover peers - go dht.DiscoverPeers(ctx, host, topicName) + go dht.DiscoverPeers(ctx, h) // daemon is running // waiting for ctrl-c to exit diff --git a/src/db/db.go b/src/db/db.go index ad858c61..d4578e11 100644 --- a/src/db/db.go +++ b/src/db/db.go @@ -1,15 +1,16 @@ package db import ( + "context" + log "github.com/sirupsen/logrus" "github.com/cockroachdb/pebble" ) -func Get(DatabaseId string) *pebble.DB { - +func GetDb(DatabaseId string) *pebble.DB { dbPath := DatabaseId - log.Info("Opening database: ", dbPath) + log.Info("opening database: ", dbPath) db, err := pebble.Open(dbPath, &pebble.Options{}) if err != nil { log.Warn(err) @@ -17,7 +18,8 @@ func Get(DatabaseId string) *pebble.DB { return db } -func Set(db *pebble.DB, key string, value string) error { +func Set(ctx context.Context, key string, value string) error { + db := ctx.Value("appDb").(*pebble.DB) if err := db.Set([]byte(key), []byte(value), pebble.Sync); err != nil { log.Warn(err) return err @@ -25,7 +27,18 @@ func Set(db *pebble.DB, key string, value string) error { return nil } -func Value(db *pebble.DB, key string) (string, error) { +func Get(ctx context.Context, key string) ([]byte, error) { + db := ctx.Value("appDb").(*pebble.DB) + value, closer, err := db.Get([]byte(key)) + if err != nil { + return nil, err + } + defer closer.Close() + return value, nil +} + +func GetString(ctx context.Context, key string) (string, error) { + db := ctx.Value("appDb").(*pebble.DB) value, closer, err := db.Get([]byte(key)) if err != nil { return "", err diff --git a/src/dht/dht.go b/src/dht/dht.go index c0014fcb..99cf709b 100644 --- a/src/dht/dht.go +++ b/src/dht/dht.go @@ -2,9 +2,12 @@ package dht import ( "context" + "encoding/json" + "fmt" + "strings" "sync" - "github.com/blocklessnetworking/b7s/src/db" + db "github.com/blocklessnetworking/b7s/src/db" "github.com/blocklessnetworking/b7s/src/models" "github.com/libp2p/go-libp2p-core/peer" dht "github.com/libp2p/go-libp2p-kad-dht" @@ -16,63 +19,96 @@ import ( ) func InitDHT(ctx context.Context, h host.Host) *dht.IpfsDHT { - // Start a DHT, for use in peer discovery. We can't just make a new DHT - // client because we want each peer to maintain its own local copy of the - // DHT, so that the bootstrapping node of the DHT can go down without - // inhibiting future peer discovery. + // Start a DHT, for use in peer discovery. kademliaDHT, err := dht.New(ctx, h) + if err != nil { + log.Fatal(err) + } - // all nodes should respond to queries + // Set the DHT to server mode. dht.Mode(dht.ModeServer) + // Bootstrap the DHT. + if err = kademliaDHT.Bootstrap(ctx); err != nil { + log.Fatal(err) + } + + // Get the list of bootstrap nodes from the configuration. + cfg := ctx.Value("config").(models.Config) + bootNodes := cfg.Node.BootNodes + + // Get the list of dial-back peers from the database. + var dialBackPeers []models.Peer + peersRecordString, err := db.Get(ctx, "peers") if err != nil { - panic(err) + peersRecordString = []byte("[]") } - if err = kademliaDHT.Bootstrap(ctx); err != nil { - panic(err) + if err = json.Unmarshal(peersRecordString, &dialBackPeers); err != nil { + log.WithError(err).Info("Error unmarshalling peers record") } - var wg sync.WaitGroup - bootNodes := []multiaddr.Multiaddr{} + //log the length of dialBackPeers + log.WithField("dialBackPeers", len(dialBackPeers)).Info("dialBackPeers") - cfg := ctx.Value("config").(models.Config) - for _, bootNode := range cfg.Node.BootNodes { - bootNodes = append(bootNodes, multiaddr.StringCast(bootNode)) + // Convert the dial-back peers to multiaddrs and add them to the list of bootstrap nodes if they do not already exist. + // likely good to limit the number of dial-back peers to a small number. + // and we need to limit to workers + for _, peer := range dialBackPeers { + peerMultiAddr := fmt.Sprintf("%s/p2p/%s", peer.MultiAddr, peer.Id.Pretty()) + peerMultiAddr = strings.Replace(peerMultiAddr, "127.0.0.1", "0.0.0.0", 1) + //log peer add + log.WithField("peerMultiAddr", peerMultiAddr).Info("peerMultiAddr") + peerExists := false + for _, bootNode := range bootNodes { + if bootNode == peerMultiAddr { + peerExists = true + break + } + } + if !peerExists { + bootNodes = append(bootNodes, peerMultiAddr) + } } - for _, peerAddr := range bootNodes { - peerinfo, _ := peer.AddrInfoFromP2pAddr(peerAddr) + // Connect to the bootstrap nodes. + var wg sync.WaitGroup + for _, bootNode := range bootNodes { + peerAddr, err := peer.AddrInfoFromP2pAddr(multiaddr.StringCast(bootNode)) + log.Info("booting from: ", peerAddr) + if err != nil { + log.WithFields(log.Fields{ + "bootNode": bootNode, + "error": err, + }).Warn("Invalid bootstrap node address") + continue + } wg.Add(1) go func() { defer wg.Done() - if err := h.Connect(ctx, *peerinfo); err != nil { - // todo figure out what we want to do with no good addresses - // no reason to panic here get's noisy with discovery + if err := h.Connect(ctx, *peerAddr); err != nil { if err.Error() != "no good addresses" { log.WithFields(log.Fields{ "localMultiAddr": h.Addrs(), "peerID": h.ID(), "err": err, - }).Warn("bootstrap warn") + }).Warn("Error connecting to bootstrap node") } } }() } - wg.Wait() - return kademliaDHT } -func DiscoverPeers(ctx context.Context, h host.Host, topicName string) { +func DiscoverPeers(ctx context.Context, h host.Host) { + topicName := ctx.Value("topicName").(string) kademliaDHT := InitDHT(ctx, h) routingDiscovery := drouting.NewRoutingDiscovery(kademliaDHT) dutil.Advertise(ctx, routingDiscovery, topicName) log.Info("starting peer discovery") // Look for others who have announced and attempt to connect to them - anyConnected := false - for !anyConnected { - + numConnected := 0 + for numConnected < 20 { peerChan, err := routingDiscovery.FindPeers(ctx, topicName) if err != nil { panic(err) @@ -86,12 +122,13 @@ func DiscoverPeers(ctx context.Context, h host.Host, topicName string) { // this can be quite noisy with discovery // fmt.Println("Failed connecting to ", peer.ID.Pretty(), ", error:", err) } else { - pebble := db.Get(peer.ID.Pretty()) - db.Set(pebble, "peerID", peer.ID.Pretty()) log.WithFields(log.Fields{ "peerID": peer.ID.Pretty(), - }).Info("connected to peer") - anyConnected = true + }).Info("connected to a peer") + numConnected++ + if numConnected >= 20 { + break + } } } } diff --git a/src/host/host.go b/src/host/host.go index 316c90ea..d7a0fd6f 100644 --- a/src/host/host.go +++ b/src/host/host.go @@ -3,7 +3,6 @@ package host import ( "context" "io/ioutil" - "strconv" "github.com/blocklessnetworking/b7s/src/messaging" @@ -14,10 +13,11 @@ import ( log "github.com/sirupsen/logrus" ) +// NewHost creates a new libp2p host func NewHost(ctx context.Context, port int, address string) host.Host { - - // see if we have a private key to load var privKey crypto.PrivKey + + // Read the private key file if it exists keyPath := ctx.Value("config").(models.Config).Node.KeyPath if keyPath != "" { log.Println("loading private key from: ", keyPath) @@ -42,21 +42,20 @@ func NewHost(ctx context.Context, port int, address string) host.Host { libp2p.NATPortMap(), } - // load private key if we have one - // otherwise we will just generate an identity when we start the host + // Use the private key if it exists, otherwise generate an identity when starting the host if privKey != nil { opts = append(opts, libp2p.Identity(privKey)) } - host, err := libp2p.New(opts...) + h, err := libp2p.New(opts...) if err != nil { panic(err) } - log.Info("host: ", hostAddress+"/p2p/"+host.ID().Pretty()) + log.Info("host: ", hostAddress+"/p2p/"+h.ID().Pretty()) - // set a stream handler on the worker to listen for incoming streams - messaging.ListenMessages(ctx, host) + // Set a stream handler to listen for incoming streams + messaging.ListenMessages(ctx, h) - return host + return h } diff --git a/src/host/notifee.go b/src/host/notifee.go new file mode 100644 index 00000000..dc27129f --- /dev/null +++ b/src/host/notifee.go @@ -0,0 +1,113 @@ +package host + +import ( + "context" + "encoding/json" + + db "github.com/blocklessnetworking/b7s/src/db" + "github.com/blocklessnetworking/b7s/src/models" + "github.com/libp2p/go-libp2p/core/network" + ma "github.com/multiformats/go-multiaddr" + log "github.com/sirupsen/logrus" +) + +// ConnectedNotifee is a struct that implements the Notifee interface +type ConnectedNotifee struct { + Ctx context.Context +} + +func (n *ConnectedNotifee) Connected(network network.Network, connection network.Conn) { + + // get the peer id and multiaddr. + peerID := connection.RemotePeer() + + // this address doesn't give us the in bound port for a dialback + multiAddr := connection.RemoteMultiaddr() + + // Get the peer record from the database. + peerRecord, err := db.Get(n.Ctx, peerID.Pretty()) + if err != nil { + log.WithError(err).Info("Error getting peer record from database") + } + + // Get the list of peers from the database. + peersRecordString, err := db.Get(n.Ctx, "peers") + if err != nil { + peersRecordString = []byte("[]") + } + + var peers []models.Peer + if err = json.Unmarshal(peersRecordString, &peers); err != nil { + log.WithError(err).Info("Error unmarshalling peers record") + } + + // Create a new peer info struct. + peerInfo := models.Peer{ + Type: "peer", + Id: peerID, + MultiAddr: multiAddr.String(), + AddrInfo: network.Peerstore().PeerInfo(peerID), + } + + // Check if the peer is already in the list. + peerExists := false + for _, peer := range peers { + if peer.Id == peerInfo.Id { + peerExists = true + break + } + } + + // If the peer is not in the list, add it. + if !peerExists { + peers = append(peers, peerInfo) + } + + // Marshal the peer info struct to JSON. + peerJSON, err := json.Marshal(peerInfo) + if err != nil { + log.WithError(err).Info("Error marshalling peer info") + return + } + + // Marshal the list of peers to JSON. + peersJSON, err := json.Marshal(peers) + if err != nil { + log.WithError(err).Info("Error marshalling peers record") + } + + //log the peerInfo + log.WithFields(log.Fields{ + "peerInfo": peerInfo, + }).Info("Peer Info Stored") + + // If the peer record does not exist in the database, set it. + if peerRecord == nil { + if err := db.Set(n.Ctx, peerID.Pretty(), string(peerJSON)); err != nil { + log.WithError(err).Info("Error setting peer record in database") + } + } + + // Set the list of peers in the database. + if err := db.Set(n.Ctx, "peers", string(peersJSON)); err != nil { + log.WithError(err).Info("Error setting peers record in database") + } +} + +// Disconnected is called when a connection is closed +func (n *ConnectedNotifee) Disconnected(network network.Network, connection network.Conn) { + // A peer has been disconnected + // Do something with the disconnected peer +} + +// Listen is called when a new stream is opened +func (n *ConnectedNotifee) Listen(network.Network, ma.Multiaddr) { + // A new stream has been opened + // Do something with the stream +} + +// ListenClose is called when a stream is closed +func (n *ConnectedNotifee) ListenClose(network.Network, ma.Multiaddr) { + // A stream has been closed + // Do something with the closed stream +} diff --git a/src/models/db.go b/src/models/db.go new file mode 100644 index 00000000..cf1a597c --- /dev/null +++ b/src/models/db.go @@ -0,0 +1,12 @@ +package models + +import ( + "github.com/libp2p/go-libp2p/core/peer" +) + +type Peer struct { + Type string `json:"type,omitempty"` + Id peer.ID `json:"id,omitempty"` + MultiAddr string `json:"multiaddress,omitempty"` + AddrInfo peer.AddrInfo `json:"addrinfo,omitempty"` +} diff --git a/src/repository/controller_test.go b/src/repository/controller_test.go deleted file mode 100644 index 787ffc3a..00000000 --- a/src/repository/controller_test.go +++ /dev/null @@ -1,32 +0,0 @@ -package repository - -import ( - "context" - "testing" - - "github.com/blocklessnetworking/b7s/src/db" - "github.com/blocklessnetworking/b7s/src/models" - "github.com/stretchr/testify/assert" -) - -func TestGetPackage(t *testing.T) { - ctx := context.Background() - assert := assert.New(t) - // set test context and test appdb - config := models.Config{} - config.Node.WorkspaceRoot = "/tmp/b7s_test" - ctx = context.WithValue(ctx, "config", config) - appDb := db.Get("/tmp/b7s_test/controller_testdb") - ctx = context.WithValue(ctx, "appDb", appDb) - - // file uri reference manifest - manifest := GetPackage(ctx, "https://bafybeiawxwfxlqvuefqzk6efhbmuax6kzzut3d7tkhh3ekyzshba4cpwka.ipfs.w3s.link/manifest.json") - - assert.Equal(manifest.Function.ID, "org.blockless.functions.myfunction", "manifest with known function id returned") - - // ask for the file again, should be cached - manifest = GetPackage(ctx, "https://bafybeiawxwfxlqvuefqzk6efhbmuax6kzzut3d7tkhh3ekyzshba4cpwka.ipfs.w3s.link/manifest.json") - assert.Equal(manifest.Cached, true, "manifest is marked as cached") - - db.Close(appDb) -} diff --git a/src/repository/repository.go b/src/repository/repository.go index 8b8b2ab7..329d2523 100644 --- a/src/repository/repository.go +++ b/src/repository/repository.go @@ -15,7 +15,6 @@ import ( "github.com/blocklessnetworking/b7s/src/db" "github.com/blocklessnetworking/b7s/src/http" "github.com/blocklessnetworking/b7s/src/models" - "github.com/cockroachdb/pebble" log "github.com/sirupsen/logrus" ) @@ -49,8 +48,7 @@ func (r JSONRepository) Get(ctx context.Context, manifestPath string) models.Fun functionManifest.Function.ID = strings.Split(u.Hostname(), ".")[0] } - appDb := ctx.Value("appDb").(*pebble.DB) - cachedFunction, err := db.Value(appDb, functionManifest.Function.ID) + cachedFunction, err := db.GetString(ctx, functionManifest.Function.ID) WorkSpaceDirectory := WorkSpaceRoot + "/" + functionManifest.Function.ID if err != nil { @@ -79,7 +77,7 @@ func (r JSONRepository) Get(ctx context.Context, manifestPath string) models.Fun log.Warn(error) } - db.Set(appDb, functionManifest.Function.ID, string(functionManifestJson)) + db.Set(ctx, functionManifest.Function.ID, string(functionManifestJson)) log.WithFields(log.Fields{ "uri": functionManifest.Deployment.Uri, diff --git a/src/restapi/api_test.go b/src/restapi/api_test.go deleted file mode 100644 index 00a8c7bc..00000000 --- a/src/restapi/api_test.go +++ /dev/null @@ -1,65 +0,0 @@ -package restapi - -import ( - "context" - "encoding/json" - "io" - "net/http" - "net/http/httptest" - "strings" - "testing" - - "github.com/blocklessnetworking/b7s/src/db" - "github.com/blocklessnetworking/b7s/src/enums" - "github.com/blocklessnetworking/b7s/src/models" -) - -func TestHandleInstallFunction(t *testing.T) { - ctx := context.Background() - // Create a request to pass to our handler. We don't have any query parameters for now, so we'll - // pass 'nil' as the third parameter. - req, err := http.NewRequest("GET", "/install", nil) - - // set test context and test appdb - config := models.Config{} - config.Node.WorkspaceRoot = "/tmp/b7s_test" - ctx = context.WithValue(ctx, "config", config) - appDb := db.Get("/tmp/b7s_test/api_testdb") - ctx = context.WithValue(ctx, "appDb", appDb) - - req = req.WithContext(ctx) - if err != nil { - t.Fatal(err) - } - - installFunctionReq := models.RequestFunctionInstall{ - Uri: "https://bafybeiawxwfxlqvuefqzk6efhbmuax6kzzut3d7tkhh3ekyzshba4cpwka.ipfs.w3s.link/manifest.json", - } - - data, _ := json.Marshal(installFunctionReq) - stringReader := strings.NewReader(string(data)) - stringReadCloser := io.NopCloser(stringReader) - - req.Body = stringReadCloser - - // We create a ResponseRecorder (which satisfies http.ResponseWriter) to record the response. - rr := httptest.NewRecorder() - handler := http.HandlerFunc(handleInstallFunction) - // Our handlers satisfy http.Handler, so we can call their ServeHTTP method - // directly and pass in our Request and ResponseRecorder. - handler.ServeHTTP(rr, req) - // Check the status code is what we expect. - if status := rr.Code; status != http.StatusOK { - t.Errorf("handler returned wrong status code: got %v want %v", - status, http.StatusOK) - } - // Check the response body is what we expect. - returned := models.ResponseInstall{} - json.Unmarshal(rr.Body.Bytes(), &returned) - - db.Close(appDb) - if returned.Code != enums.ResponseCodeOk { - t.Errorf("handler returned unexpected body: got %v want %v", - returned.Code, enums.ResponseCodeOk) - } -}