Skip to content

Commit

Permalink
Merge pull request #17 from Lumerin-protocol/main
Browse files Browse the repository at this point in the history
Main
  • Loading branch information
rcondron authored Jun 12, 2024
2 parents 9830e1c + 1a712b6 commit 2a58e01
Show file tree
Hide file tree
Showing 86 changed files with 4,615 additions and 1,199 deletions.
10 changes: 6 additions & 4 deletions proxy-router/.env.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
DIAMOND_CONTRACT_ADDRESS=0x70768f0fF919e194E11aBFC3a2eDF43213359dc1
ENVIRONMENT=development
ETH_NODE_ADDRESS=https://arbitrum-sepolia.blockpi.network/v1/rpc/public
ETH_NODE_LEGACY_TX=false
EXPLORER_API_URL="https://api-sepolia.arbiscan.io/api"
LOG_COLOR=true
Expand All @@ -10,7 +9,7 @@ LOG_LEVEL_CONNECTION=info
LOG_LEVEL_PROXY=info
LOG_LEVEL_SCHEDULER=info
MOR_TOKEN_ADDRESS=0xc1664f994fd3991f98ae944bc16b9aed673ef5fd
OPENAI_BASE_URL=http://localhost:11434/v1
OPENAI_BASE_URL=http://localhost:8080/v1
PROXY_ADDRESS=0.0.0.0:3333
SYS_ENABLE=false
SYS_LOCAL_PORT_RANGE=1024 65535
Expand All @@ -19,6 +18,9 @@ SYS_RLIMIT_HARD=524288
SYS_RLIMIT_SOFT=524288
SYS_SOMAXCONN=100000
SYS_TCP_MAX_SYN_BACKLOG=100000
WALLET_PRIVATE_KEY=
WEB_ADDRESS=0.0.0.0:8080
WEB_ADDRESS=0.0.0.0:8082
WEB_PUBLIC_URL=

# Recommend using your own private ETH Node Address for better performance (via Alchemy or Infura)
ETH_NODE_ADDRESS=https://arbitrum-sepolia.blockpi.network/v1/rpc/public
# Private Key from your Wallet as Consumer or Provider (needed for the proxy-router to sign transactions)
1 change: 1 addition & 0 deletions proxy-router/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ logs
dist
bin

data
6 changes: 2 additions & 4 deletions proxy-router/.gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,8 @@ bedrock-04-PRD-rawimage:
.update_raw_task_definition: &update_raw_task_definition |
echo "**************************"
echo "*** Update Validator Task Definition"
echo "*** Unique elements that should be set in calling module are Wallet Private Key, Pool Address, Web_public_url, "
echo "*** CI_WALLET_PRIVATE_KEY, CI_POOL_ADDRESS, CI_WEB_PUBLIC_URL"
echo "*** Unique elements that should be set in calling module are Pool Address, Web_public_url, "
echo "*** CI_POOL_ADDRESS, CI_WEB_PUBLIC_URL"
echo "**************************"
aws ecs describe-task-definition --region $AWS_DEFAULT_REGION --task-definition tsk-$CI_AWS_TASK > output.json
echo "**************************"
Expand All @@ -195,8 +195,6 @@ bedrock-04-PRD-rawimage:
{ "name": "HASHRATE_ERROR_THRESHOLD", "value": "'"$HASHRATE_ERROR_THRESHOLD"'" },
{ "name": "HASHRATE_ERROR_TIMEOUT", "value": "'"$HASHRATE_ERROR_TIMEOUT"'" },
{ "name": "CLONE_FACTORY_ADDRESS", "value": "'"$CLONE_FACTORY_ADDRESS"'" },
{ "name": "CONTRACT_MNEMONIC", "value": "'"$CONTRACT_MNEMONIC"'" },
{ "name": "WALLET_PRIVATE_KEY", "value": "'"$CI_WALLET_PRIVATE_KEY"'" },
{ "name": "MINER_VETTING_DURATION", "value": "'"$MINER_VETTING_DURATION"'" },
{ "name": "MINER_SHARE_TIMEOUT", "value": "'"$MINER_SHARE_TIMEOUT"'" },
{ "name": "LOG_COLOR", "value": "'"$LOG_COLOR"'" },
Expand Down
2 changes: 1 addition & 1 deletion proxy-router/.goreleaser-internal.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ builds:
no_unique_dist_dir: true
binary: "{{ .ProjectName }}_{{ .Tag }}_{{ .Os }}_{{ .Arch }}"
ldflags:
- -s -w -X main.version={{.Version}} -X github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/internal/config.Commit={{.Commit}} -X main.date={{.Date}} -X 'github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/internal/config.BuildVersion={{.Version}}'
- -s -w -X main.version={{.Version}} -X github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/config.Commit={{.Commit}} -X main.date={{.Date}} -X 'github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/config.BuildVersion={{.Version}}'

archives:
- format: binary
Expand Down
2 changes: 1 addition & 1 deletion proxy-router/.goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ builds:
no_unique_dist_dir: true
binary: "{{ .ProjectName }}_{{ .Tag }}_{{ .Os }}_{{ .Arch }}"
ldflags:
- -s -w -X main.version={{.Version}} -X github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/internal/config.Commit={{.Commit}} -X main.date={{.Date}} -X 'github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/internal/config.BuildVersion={{.Version}}'
- -s -w -X main.version={{.Version}} -X github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/config.Commit={{.Commit}} -X main.date={{.Date}} -X 'github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/config.BuildVersion={{.Version}}'

archives:
- format: binary
Expand Down
5 changes: 4 additions & 1 deletion proxy-router/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,7 @@ test-unit:
go test -v -p 1 $$(go list ./... | grep -v /test)

test-integration:
go test -v ./test/...
go test -v ./test/...

swagger:
swag init -g ./internal/handlers/httphandlers/http.go
273 changes: 273 additions & 0 deletions proxy-router/api_test/httphandlers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
package httphandlers_test

import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"math/big"
"net/http"
"net/http/httptest"
"net/url"
"testing"
"time"

"github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/aiengine"
"github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/apibus"
"github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/config"
"github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/handlers/httphandlers"
"github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/interfaces"
"github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/lib"
"github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/proxyapi"
"github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/repositories/wallet"
"github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/rpcproxy"
"github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/storages"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"

"github.com/stretchr/testify/require"
)

var WALLET_PRIVATE_KEY = "" // Set this to a valid private key to run the test.

var DIAMOND_CONTRACT_ADDR = "0x70768f0ff919e194e11abfc3a2edf43213359dc1"
var MOR_CONTRACT_ADDR = "0xc1664f994fd3991f98ae944bc16b9aed673ef5fd"
var EXPLORER_API_URL = "https://api-sepolia.arbiscan.io/api"
var ETH_LEGACY_TX = false
var ETH_NODE_ADDRESS = "wss://arb-sepolia.g.alchemy.com/v2/UPDATE_HERE"

var PROVIDER_ADDR = "0x65bBb982d9B0AfE9AED13E999B79c56dDF9e04fC"
var PROVIDER_URL = "thehulk1.stg.lumerin.io:3333"
var BID_ID = "0xa0d6ea9ce7183510e16cbfd207b9e381a91c20ee75d5db483b5758ddf22a27b1"
var SESSION_DURATION = new(big.Int).SetInt64(5 * 60) // 5 minutes in seconds

func TestNewHTTPHandlerIntegration(t *testing.T) {
apiBus := InitializeApiBus(t)

walletAddr, err := lib.PrivKeyStringToAddr(WALLET_PRIVATE_KEY)
if err != nil {
t.Fatalf("failed to get wallet address: %s", err)
return
}

// Create a new instance of the HTTPHandler.
handler := httphandlers.NewHTTPHandler(apiBus)

server := httptest.NewServer(handler)
defer server.Close()

// Make a request to get the token supply.
supply := GetTokenSupply(t, server)

// Make a request to get today's budget.
budget := GetTodaysBudget(t, server)

// Make a request to get the provider's bids.
bid := FindBid(t, server)

// Calculate the stake.
pricePerSecond := new(big.Float).SetFloat64(bid["PricePerSecond"].(float64))
pricePerSecondInt := new(big.Int)
pricePerSecondInt, _ = pricePerSecondInt.SetString(pricePerSecond.Text('f', 0), 10)

totalCost := SESSION_DURATION.Mul(pricePerSecondInt, SESSION_DURATION)
stake := totalCost.Div(totalCost.Mul(supply, totalCost), budget)

// Make a request to initiate a session.
initiateSessionResponse := InitiateSession(t, server, walletAddr, stake)
approval := initiateSessionResponse.Response.Result.Approval
approvalSig := initiateSessionResponse.Response.Result.ApprovalSig
providerPubKey := initiateSessionResponse.Response.Result.Message

// Make a request to open a session.
sessionId := OpenSession(t, server, approval, approvalSig, stake)

// Make a request to send a prompt.
promptRequestBody := map[string]interface{}{
"providerPublicKey": providerPubKey,
"prompt": map[string]interface{}{
"model": "llama2",
"stream": true,
"messages": []map[string]string{
{
"role": "user",
"content": "Why sky is blue?",
},
},
},
"providerUrl": PROVIDER_URL,
}

promptBody, err := json.Marshal(promptRequestBody)
require.NoError(t, err)

sendPromptURL := server.URL + fmt.Sprintf("/proxy/sessions/%s/prompt", sessionId)
sendPromptResp, err := http.Post(sendPromptURL, "application/json", bytes.NewReader(promptBody))
require.NoError(t, err)

// Make a request to close a session.
closeSessionURL := server.URL + fmt.Sprintf("/blockchain/sessions/%s/close", sessionId)
closeSessionResp, err := http.Post(closeSessionURL, "application/json", nil)
require.NoError(t, err)
require.Equal(t, http.StatusOK, closeSessionResp.StatusCode)

require.Equal(t, http.StatusOK, sendPromptResp.StatusCode)
}

func GetTokenSupply(t *testing.T, server *httptest.Server) *big.Int {
getTokenSupplyURL := server.URL + "/blockchain/token/supply"
getTokenSupplyResp, err := http.Get(getTokenSupplyURL)
require.NoError(t, err)
require.Equal(t, http.StatusOK, getTokenSupplyResp.StatusCode)

bodyBytes, err := io.ReadAll(getTokenSupplyResp.Body)
require.NoError(t, err)

var data map[string]string
err = json.Unmarshal(bodyBytes, &data)
require.NoError(t, err)

supply, ok := new(big.Int).SetString(data["supply"], 10)
require.True(t, ok)
return supply
}

func GetTodaysBudget(t *testing.T, server *httptest.Server) *big.Int {
getTodaysBudgetURL := server.URL + "/blockchain/sessions/budget"
getTodaysBudgetResp, err := http.Get(getTodaysBudgetURL)
require.NoError(t, err)
require.Equal(t, http.StatusOK, getTodaysBudgetResp.StatusCode)

bodyBytes, err := io.ReadAll(getTodaysBudgetResp.Body)
require.NoError(t, err)

var data map[string]string
err = json.Unmarshal(bodyBytes, &data)
require.NoError(t, err)

budget, ok := new(big.Int).SetString(data["budget"], 10)
require.True(t, ok)
return budget
}

func FindBid(t *testing.T, server *httptest.Server) map[string]interface{} {
getBidsUrl := server.URL + fmt.Sprintf("/blockchain/providers/%s/bids", PROVIDER_ADDR)
getBidResp, err := http.Get(getBidsUrl)
require.NoError(t, err)
require.Equal(t, http.StatusOK, getBidResp.StatusCode)

bodyBytes, err := io.ReadAll(getBidResp.Body)
require.NoError(t, err)
var data map[string][]interface{}

err = json.Unmarshal(bodyBytes, &data)
require.NoError(t, err)

var bid map[string]interface{}
for _, v := range data["bids"] {
b := v.(map[string]interface{})
if b["Id"] == BID_ID {
bid = b
break
}
}
require.NotNil(t, bid)
return bid
}

type InitiateSessionData struct {
Approval string `json:"approval"`
ApprovalSig string `json:"approvalSig"`
Message string `json:"message"`
}

type InitiateSessionResult struct {
Result InitiateSessionData `json:"result"`
}

type InitiateSessionResponse struct {
Response InitiateSessionResult `json:"response"`
}

func InitiateSession(t *testing.T, server *httptest.Server, walletAddr common.Address, stake *big.Int) InitiateSessionResponse {
initiateSessionURL := server.URL + "/proxy/sessions/initiate"

var body map[string]interface{} = make(map[string]interface{})
body["user"] = walletAddr
body["provider"] = PROVIDER_ADDR
body["spend"] = stake
body["bidId"] = BID_ID
body["providerUrl"] = PROVIDER_URL
initiateSessionBody, err := json.Marshal(body)
require.NoError(t, err)

initiateSessionResp, err := http.Post(initiateSessionURL, "application/json", bytes.NewReader(initiateSessionBody))
require.NoError(t, err)
require.Equal(t, http.StatusOK, initiateSessionResp.StatusCode)

bodyBytes, err := io.ReadAll(initiateSessionResp.Body)
require.NoError(t, err)

fmt.Println(string(bodyBytes))

var response InitiateSessionResponse
err = json.Unmarshal(bodyBytes, &response)
require.NoError(t, err)

return response
}

func OpenSession(t *testing.T, server *httptest.Server, approval string, approvalSig string, stake *big.Int) string {
var openBody map[string]interface{} = make(map[string]interface{})
openBody["approval"] = approval
openBody["approvalSig"] = approvalSig
openBody["stake"] = stake.String()
openSessionBody, err := json.Marshal(openBody)
require.NoError(t, err)

openSessionURL := server.URL + "/blockchain/sessions"
openSessionResp, err := http.Post(openSessionURL, "application/json", bytes.NewReader(openSessionBody))
require.NoError(t, err)
require.Equal(t, http.StatusOK, openSessionResp.StatusCode)

bodyBytes, err := io.ReadAll(openSessionResp.Body)
fmt.Println(string(bodyBytes))
require.NoError(t, err)

var data map[string]interface{}
err = json.Unmarshal(bodyBytes, &data)
require.NoError(t, err)

sessionId := data["sessionId"]
return sessionId.(string)
}

func InitializeApiBus(t *testing.T) *apibus.ApiBus {
log, err := lib.NewLogger("debug", true, false, false, "")
if err != nil {
t.Fatalf("failed to create logger: %s", err)
return nil
}

ethClient, err := ethclient.DialContext(context.Background(), ETH_NODE_ADDRESS)
if err != nil {
t.Fatalf("failed to connect to the Ethereum node: %s", err)
return nil
}

derived := new(config.DerivedConfig)
contractLogStorage := lib.NewCollection[*interfaces.LogStorage]()

diamondContractAddr := common.HexToAddress(DIAMOND_CONTRACT_ADDR)
morContractAddr := common.HexToAddress(MOR_CONTRACT_ADDR)

sessionStorage := storages.NewSessionStorage(log)

wlt := wallet.NewEnvWallet(WALLET_PRIVATE_KEY)
rpcProxy := rpcproxy.NewRpcProxy(ethClient, diamondContractAddr, morContractAddr, EXPLORER_API_URL, wlt, sessionStorage, log, ETH_LEGACY_TX)
proxyRouterApi := proxyapi.NewProxyRouterApi(nil, &url.URL{}, wlt, nil, derived, time.Now(), contractLogStorage, sessionStorage, log)

apiBus := apibus.NewApiBus(rpcProxy, aiengine.NewAiEngine(), proxyRouterApi, wlt)
return apiBus
}
6 changes: 3 additions & 3 deletions proxy-router/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ echo COMMIT=$COMMIT

go build \
-ldflags="-s -w \
-X 'github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/internal/config.BuildVersion=$VERSION' \
-X 'github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/internal/config.Commit=$COMMIT' \
-X 'github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/config.BuildVersion=$VERSION' \
-X 'github.com/MorpheusAIs/Morpheus-Lumerin-Node/proxy-router/internal/config.Commit=$COMMIT' \
" \
-o bin/proxy-router cmd/main.go
-o bin/proxy-router cmd/main.go
Loading

0 comments on commit 2a58e01

Please sign in to comment.