Skip to content

Commit

Permalink
Integration tests for a PBFT cluster (#114)
Browse files Browse the repository at this point in the history
* Integration tests for a PBFT cluster

* Add node shutdown

* Revert previous change

* Shutdown head node last

* Fix race conditions

* Execute method acquires state lock

* Fix imports and go mod tidy

* Fix typos

* Gofmt

* Add go reportcard, license and release version badges
  • Loading branch information
Maelkum authored Sep 15, 2023
1 parent 6e8d5f0 commit bfc3669
Show file tree
Hide file tree
Showing 26 changed files with 378 additions and 120 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
![Coverage](https://img.shields.io/badge/Coverage-64.5%25-yellow)
[![Coverage](https://img.shields.io/badge/Coverage-64.5%25-yellow)](https://img.shields.io/badge/Coverage-64.5%25-yellow)
[![Go Report Card](https://goreportcard.com/badge/github.com/blocklessnetwork/b7s)](https://goreportcard.com/report/github.com/blocklessnetwork/b7s)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/blocklessnetwork/b7s/blob/main/LICENSE.md)
[![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/blocklessnetwork/b7s)](https://img.shields.io/github/v/release/blocklessnetwork/b7s)


# b7s daemon

Expand Down
2 changes: 1 addition & 1 deletion cmd/bootstrap-limiter/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func run() int {
return failure
}

// Chown directory to be owned by the original user runing sudo.
// Chown directory to be owned by the original user running sudo.
err = chownRecursive(target, int(id), -1)
if err != nil {
log.Printf("could not set owner for the cgroup: %s", err)
Expand Down
17 changes: 8 additions & 9 deletions cmd/keyforge/key_management.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ package main

import (
"encoding/base64"
"io/ioutil"
"log"
"os"
"path/filepath"

"github.com/libp2p/go-libp2p-core/crypto"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p/core/crypto"
"github.com/libp2p/go-libp2p/core/peer"
)

// LoadOrCreateKeys loads existing keys or creates new ones if not present
Expand All @@ -23,7 +22,7 @@ func LoadOrCreateKeys(privKeyFile string, outputDir string) (crypto.PrivKey, cry
return nil, nil, err
}
} else {
privBytes, err := ioutil.ReadFile(privKeyFile)
privBytes, err := os.ReadFile(privKeyFile)
if err != nil {
return nil, nil, err
}
Expand Down Expand Up @@ -51,33 +50,33 @@ func LoadOrCreateKeys(privKeyFile string, outputDir string) (crypto.PrivKey, cry
}

pubKeyFile := filepath.Join(outputDir, pubKeyName)
err = ioutil.WriteFile(pubKeyFile, pubPayload, pubKeyPermissions)
err = os.WriteFile(pubKeyFile, pubPayload, pubKeyPermissions)
if err != nil {
log.Fatalf("Could not write public key to file: %s", err)
}

pubKeyTextFile := filepath.Join(outputDir, pubKeyTxtName)
pubKeyBase64 := base64.StdEncoding.EncodeToString(pubPayload)
err = ioutil.WriteFile(pubKeyTextFile, []byte(pubKeyBase64), pubKeyPermissions)
err = os.WriteFile(pubKeyTextFile, []byte(pubKeyBase64), pubKeyPermissions)
if err != nil {
log.Fatalf("Could not write public key text to file: %s", err)
}

identityFile := filepath.Join(outputDir, identityName)
err = ioutil.WriteFile(identityFile, []byte(identity.Pretty()), pubKeyPermissions)
err = os.WriteFile(identityFile, []byte(identity.Pretty()), pubKeyPermissions)
if err != nil {
log.Fatalf("Could not write identity to file: %s", err)
}

privKeyFile = filepath.Join(outputDir, privKeyName)
err = ioutil.WriteFile(privKeyFile, privPayload, privKeyPermissions)
err = os.WriteFile(privKeyFile, privPayload, privKeyPermissions)
if err != nil {
log.Fatalf("Could not write private key to file: %s", err)
}

// Write peer ID to file
peerIDFile := filepath.Join(outputDir, peerIDFileName)
err = ioutil.WriteFile(peerIDFile, []byte(identity.Pretty()), pubKeyPermissions)
err = os.WriteFile(peerIDFile, []byte(identity.Pretty()), pubKeyPermissions)
if err != nil {
log.Fatalf("Could not write peer ID to file: %s", err)
}
Expand Down
3 changes: 1 addition & 2 deletions cmd/keyforge/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ const (
peerIDFileName = "peerid.txt"
privKeyPermissions = 0600
pubKeyPermissions = 0644

)

func main() {
Expand Down Expand Up @@ -60,7 +59,7 @@ func main() {
if flagPublicKey != "" && flagMessage != "" && flagSignature != "" {
VerifyGivenSignature(flagPublicKey, flagMessage, flagSignature)
}

if flagPeerID != "" && flagMessage != "" && flagSignature != "" {
VerifyGivenSignatureWithPeerID(flagPeerID, flagMessage, flagSignature)
}
Expand Down
6 changes: 3 additions & 3 deletions cmd/keyforge/sign_verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
"log"
"path/filepath"

"github.com/libp2p/go-libp2p-core/crypto"
"github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p/core/crypto"
"github.com/libp2p/go-libp2p/core/peer"
)

// HandleSignAndVerify performs the signing and verification based on the provided keys and flags
Expand Down Expand Up @@ -117,6 +117,6 @@ func VerifyGivenSignatureWithPeerID(peerIDStr string, message string, encodedSig
// This will give you a base64 string representation of the public key
pubKeyBase64 := base64.StdEncoding.EncodeToString(pubKeyBytes)
log.Printf("Extracted public key from PeerID (Base64): %s", pubKeyBase64)

VerifyGivenSignature(pubKeyBase64, message, encodedSignature)
}
132 changes: 66 additions & 66 deletions cmd/manager/bin.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,68 +15,68 @@ import (
)

func installBinary(url, folder string) {
usr, err := user.Current()
if err != nil {
log.Fatal(err)
}

targetPath := filepath.Join(usr.HomeDir, folder)
os.MkdirAll(targetPath, os.ModePerm)

resp, err := http.Get(url)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()

archiveData, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}

gzipReader, err := gzip.NewReader(bytes.NewReader(archiveData))
if err != nil {
log.Fatal(err)
}
defer gzipReader.Close()

tarReader := tar.NewReader(gzipReader)

for {
header, err := tarReader.Next()
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}

path := filepath.Join(targetPath, header.Name)
switch header.Typeflag {
case tar.TypeDir:
if err := os.MkdirAll(path, os.FileMode(header.Mode)); err != nil {
log.Fatal(err)
}

case tar.TypeReg:
outFile, err := os.Create(path)
if err != nil {
log.Fatal(err)
}

if _, err := io.Copy(outFile, tarReader); err != nil {
log.Fatal(err)
}

outFile.Close()

if err := os.Chmod(path, os.FileMode(header.Mode)); err != nil {
log.Fatal(err)
}

log.Printf("File %s installed in %s", header.Name, targetPath)
}
}
usr, err := user.Current()
if err != nil {
log.Fatal(err)
}

targetPath := filepath.Join(usr.HomeDir, folder)
os.MkdirAll(targetPath, os.ModePerm)

resp, err := http.Get(url)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()

archiveData, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}

gzipReader, err := gzip.NewReader(bytes.NewReader(archiveData))
if err != nil {
log.Fatal(err)
}
defer gzipReader.Close()

tarReader := tar.NewReader(gzipReader)

for {
header, err := tarReader.Next()
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}

path := filepath.Join(targetPath, header.Name)
switch header.Typeflag {
case tar.TypeDir:
if err := os.MkdirAll(path, os.FileMode(header.Mode)); err != nil {
log.Fatal(err)
}

case tar.TypeReg:
outFile, err := os.Create(path)
if err != nil {
log.Fatal(err)
}

if _, err := io.Copy(outFile, tarReader); err != nil {
log.Fatal(err)
}

outFile.Close()

if err := os.Chmod(path, os.FileMode(header.Mode)); err != nil {
log.Fatal(err)
}

log.Printf("File %s installed in %s", header.Name, targetPath)
}
}
}

func installB7s(baseURL, version string) {
Expand Down Expand Up @@ -105,18 +105,18 @@ func installRuntime(baseURL, version string) {
arch := runtime.GOARCH
platform := runtime.GOOS

if(platform == "darwin") {
if platform == "darwin" {
platform = "macos"
}

if(arch == "amd64") {
if arch == "amd64" {
arch = "x86_64"
}

if(arch == "arm64") {
if arch == "arm64" {
arch = "aarch64"
}

url := fmt.Sprintf("%s/%s/blockless-runtime.%s-latest.%s.tar.gz", baseURL, version, platform, arch)
installBinary(url, ".b7s/runtime")
}
}
21 changes: 9 additions & 12 deletions cmd/manager/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ func main() {
<-ctx.Done()
}


func makeBasicHost(listenPort int, insecure bool, privKeyPath string) (host.Host, error) {
priv, err := loadPrivateKey(privKeyPath)
if err != nil {
Expand All @@ -76,20 +75,18 @@ func makeBasicHost(listenPort int, insecure bool, privKeyPath string) (host.Host
return libp2p.New(opts...)
}



func loadPrivateKey(filePath string) (crypto.PrivKey, error) {
keyBytes, err := ioutil.ReadFile(filePath)
if err != nil {
return nil, err
}
keyBytes, err := ioutil.ReadFile(filePath)
if err != nil {
return nil, err
}

priv, err := crypto.UnmarshalPrivateKey(keyBytes)
if err != nil {
return nil, err
}
priv, err := crypto.UnmarshalPrivateKey(keyBytes)
if err != nil {
return nil, err
}

return priv, nil
return priv, nil
}

func getHostAddress(ha host.Host) string {
Expand Down
2 changes: 1 addition & 1 deletion cmd/manager/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,4 +178,4 @@ func removeMacOSService() {

func removeWindowsService() {
log.Fatal("Removing a service on Windows is not supported in this code.")
}
}
1 change: 1 addition & 0 deletions cmd/node/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ func run() int {
log.Error().Err(err).Str("key", cfg.Host.PrivateKey).Msg("could not create host")
return failure
}
defer host.Close()

log.Info().
Str("id", host.ID().String()).
Expand Down
4 changes: 4 additions & 0 deletions consensus/pbft/execute.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ import (
// Execute fullfils the consensus interface by inserting the request into the pipeline.
func (r *Replica) Execute(client peer.ID, requestID string, timestamp time.Time, req execute.Request) (codes.Code, execute.Result, error) {

// Modifying state, so acquire state lock now.
r.sl.Lock()
defer r.sl.Unlock()

request := Request{
ID: requestID,
Timestamp: timestamp,
Expand Down
2 changes: 1 addition & 1 deletion fstore/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ func (h *FStore) Sync(cid string) error {
}

// checkFunctionFiles checks if the files required by the function are found on local storage.
// It returns two booleans indicating presense of the archive file, the unpacked files, and a potential error.
// It returns two booleans indicating presence of the archive file, the unpacked files, and a potential error.
func (h *FStore) checkFunctionFiles(fn functionRecord) (bool, bool, error) {

// Check if the archive is found.
Expand Down
3 changes: 1 addition & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ require (
github.com/ipfs/boxo v0.12.0 // indirect
github.com/labstack/gommon v0.4.0 // indirect
github.com/libp2p/go-libp2p-consensus v0.0.1 // indirect
github.com/libp2p/go-libp2p-core v0.20.1 // indirect
github.com/libp2p/go-libp2p-gostream v0.6.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/onsi/ginkgo/v2 v2.12.0 // indirect
Expand Down Expand Up @@ -93,7 +92,7 @@ require (
github.com/google/gopacket v1.1.19 // indirect
github.com/google/uuid v1.3.1
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-multierror v1.1.1
github.com/hashicorp/golang-lru v1.0.2 // indirect
github.com/huin/goupnp v1.3.0 // indirect
github.com/ipfs/go-cid v0.4.1 // indirect
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -366,8 +366,6 @@ github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLE
github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w=
github.com/libp2p/go-libp2p-consensus v0.0.1 h1:jcVbHRZLwTXU9iT/mPi+Lx4/OrIzq3bU1TbZNhYFCV8=
github.com/libp2p/go-libp2p-consensus v0.0.1/go.mod h1:+9Wrfhc5QOqWB0gXI0m6ARlkHfdJpcFXmRU0WoHz4Mo=
github.com/libp2p/go-libp2p-core v0.20.1 h1:fQz4BJyIFmSZAiTbKV8qoYhEH5Dtv/cVhZbG3Ib/+Cw=
github.com/libp2p/go-libp2p-core v0.20.1/go.mod h1:6zR8H7CvQWgYLsbG4on6oLNSGcyKaYFSEYyDt51+bIY=
github.com/libp2p/go-libp2p-gostream v0.6.0 h1:QfAiWeQRce6pqnYfmIVWJFXNdDyfiR/qkCnjyaZUPYU=
github.com/libp2p/go-libp2p-gostream v0.6.0/go.mod h1:Nywu0gYZwfj7Jc91PQvbGU8dIpqbQQkjWgDuOrFaRdA=
github.com/libp2p/go-libp2p-kad-dht v0.25.0 h1:T2SXQ/VlXTQVLChWY/+OyOsmGMRJvB5kiR+eJt7jtvI=
Expand Down
2 changes: 1 addition & 1 deletion host/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func New(log zerolog.Logger, address string, port uint, options ...func(*Config)

if cfg.Websocket {

// If the TCP and websocket port are explicitely chosen and set to the same value, one of the two listens will silently fail.
// If the TCP and websocket port are explicitly chosen and set to the same value, one of the two listens will silently fail.
if port == cfg.WebsocketPort && cfg.WebsocketPort != 0 {
return nil, fmt.Errorf("TCP and websocket ports cannot be the same (TCP: %v, Websocket: %v)", port, cfg.WebsocketPort)
}
Expand Down
2 changes: 1 addition & 1 deletion models/execute/response.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type Cluster struct {
Peers []peer.ID `json:"peers,omitempty"`
}

// RuntimeOutput describes the output produced by the Blockless Runtime during exection.
// RuntimeOutput describes the output produced by the Blockless Runtime during execution.
type RuntimeOutput struct {
Stdout string `json:"stdout"`
Stderr string `json:"stderr"`
Expand Down
Loading

0 comments on commit bfc3669

Please sign in to comment.