Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pedro/merge/feat/db #914

Merged
merged 17 commits into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/test-e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ jobs:
uses: actions/checkout@v4
with:
repository: vechain/thor-e2e-tests
# https://github.com/vechain/thor-e2e-tests/tree/209f6ea9a81a98dc2d5e42bf036d2878c5837036
ref: 209f6ea9a81a98dc2d5e42bf036d2878c5837036
# https://github.com/vechain/thor-e2e-tests/tree/8b72bedff11c9e8873d88b6e2dba356d43b56779
ref: 8b72bedff11c9e8873d88b6e2dba356d43b56779

- name: Download artifact
uses: actions/download-artifact@v4
Expand Down
16 changes: 11 additions & 5 deletions api/accounts/accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@ import (
)

type Accounts struct {
repo *chain.Repository
stater *state.Stater
callGasLimit uint64
forkConfig thor.ForkConfig
bft bft.Committer
repo *chain.Repository
stater *state.Stater
callGasLimit uint64
forkConfig thor.ForkConfig
bft bft.Committer
enabledDeprecated bool
}

func New(
Expand All @@ -40,13 +41,15 @@ func New(
callGasLimit uint64,
forkConfig thor.ForkConfig,
bft bft.Committer,
enabledDeprecated bool,
) *Accounts {
return &Accounts{
repo,
stater,
callGasLimit,
forkConfig,
bft,
enabledDeprecated,
}
}

Expand Down Expand Up @@ -168,6 +171,9 @@ func (a *Accounts) handleGetStorage(w http.ResponseWriter, req *http.Request) er
}

func (a *Accounts) handleCallContract(w http.ResponseWriter, req *http.Request) error {
if !a.enabledDeprecated {
return utils.HTTPError(nil, http.StatusGone)
}
callData := &CallData{}
if err := utils.ParseJSON(req.Body, &callData); err != nil {
return utils.BadRequest(errors.WithMessage(err, "body"))
Expand Down
21 changes: 18 additions & 3 deletions api/accounts/accounts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ var (
)

func TestAccount(t *testing.T) {
initAccountServer(t)
initAccountServer(t, true)
defer ts.Close()

tclient = thorclient.New(ts.URL)
Expand All @@ -126,6 +126,21 @@ func TestAccount(t *testing.T) {
}
}

func TestDeprecated(t *testing.T) {
initAccountServer(t, false)
defer ts.Close()

tclient = thorclient.New(ts.URL)

body := &accounts.CallData{}

_, statusCode, _ := tclient.RawHTTPClient().RawHTTPPost("/accounts", body)
assert.Equal(t, http.StatusGone, statusCode, "invalid address")

_, statusCode, _ = tclient.RawHTTPClient().RawHTTPPost("/accounts/"+contractAddr.String(), body)
assert.Equal(t, http.StatusGone, statusCode, "invalid address")
}

func getAccount(t *testing.T) {
_, statusCode, err := tclient.RawHTTPClient().RawHTTPGet("/accounts/" + invalidAddr)
require.NoError(t, err)
Expand Down Expand Up @@ -264,7 +279,7 @@ func getStorageWithNonExistingRevision(t *testing.T) {
assert.Equal(t, "revision: leveldb: not found\n", string(res), "revision not found")
}

func initAccountServer(t *testing.T) {
func initAccountServer(t *testing.T, enabledDeprecated bool) {
thorChain, err := testchain.NewIntegrationTestChain()
require.NoError(t, err)

Expand All @@ -291,7 +306,7 @@ func initAccountServer(t *testing.T) {
)

router := mux.NewRouter()
accounts.New(thorChain.Repo(), thorChain.Stater(), uint64(gasLimit), thor.NoFork, thorChain.Engine()).
accounts.New(thorChain.Repo(), thorChain.Stater(), uint64(gasLimit), thor.NoFork, thorChain.Engine(), enabledDeprecated).
Mount(router, "/accounts")

ts = httptest.NewServer(router)
Expand Down
62 changes: 0 additions & 62 deletions api/admin.go

This file was deleted.

32 changes: 32 additions & 0 deletions api/admin/admin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) 2024 The VeChainThor developers

// Distributed under the GNU Lesser General Public License v3.0 software license, see the accompanying
// file LICENSE or <https://www.gnu.org/licenses/lgpl-3.0.html>

package admin

import (
"log/slog"
"net/http"
"sync/atomic"

"github.com/gorilla/handlers"
"github.com/gorilla/mux"
"github.com/vechain/thor/v2/api/admin/apilogs"
"github.com/vechain/thor/v2/api/admin/loglevel"

healthAPI "github.com/vechain/thor/v2/api/admin/health"
)

func New(logLevel *slog.LevelVar, health *healthAPI.Health, apiLogsToggle *atomic.Bool) http.HandlerFunc {
router := mux.NewRouter()
subRouter := router.PathPrefix("/admin").Subrouter()

loglevel.New(logLevel).Mount(subRouter, "/loglevel")
healthAPI.NewAPI(health).Mount(subRouter, "/health")
apilogs.New(apiLogsToggle).Mount(subRouter, "/apilogs")

handler := handlers.CompressHandler(router)

return handler.ServeHTTP
}
70 changes: 70 additions & 0 deletions api/admin/apilogs/api_logs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright (c) 2024 The VeChainThor developers
//
// Distributed under the GNU Lesser General Public License v3.0 software license, see the accompanying
// file LICENSE or <https://www.gnu.org/licenses/lgpl-3.0.html>

package apilogs

import (
"net/http"
"sync"
"sync/atomic"

"github.com/gorilla/mux"
"github.com/vechain/thor/v2/api/utils"
"github.com/vechain/thor/v2/log"
)

type APILogs struct {
enabled *atomic.Bool
mu sync.Mutex
}

type Status struct {
Enabled bool `json:"enabled"`
}

func New(enabled *atomic.Bool) *APILogs {
return &APILogs{
enabled: enabled,
}
}

func (a *APILogs) Mount(root *mux.Router, pathPrefix string) {
sub := root.PathPrefix(pathPrefix).Subrouter()
sub.Path("").
Methods(http.MethodGet).
Name("get-api-logs-enabled").
HandlerFunc(utils.WrapHandlerFunc(a.areAPILogsEnabled))

sub.Path("").
Methods(http.MethodPost).
Name("post-api-logs-enabled").
HandlerFunc(utils.WrapHandlerFunc(a.setAPILogsEnabled))
}

func (a *APILogs) areAPILogsEnabled(w http.ResponseWriter, _ *http.Request) error {
a.mu.Lock()
defer a.mu.Unlock()

return utils.WriteJSON(w, Status{
Enabled: a.enabled.Load(),
})
}

func (a *APILogs) setAPILogsEnabled(w http.ResponseWriter, r *http.Request) error {
a.mu.Lock()
defer a.mu.Unlock()

var req Status
if err := utils.ParseJSON(r.Body, &req); err != nil {
return utils.BadRequest(err)
}
a.enabled.Store(req.Enabled)

log.Info("api logs updated", "pkg", "apilogs", "enabled", req.Enabled)

return utils.WriteJSON(w, Status{
Enabled: a.enabled.Load(),
})
}
91 changes: 91 additions & 0 deletions api/admin/apilogs/api_logs_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// Copyright (c) 2024 The VeChainThor developers
//
// Distributed under the GNU Lesser General Public License v3.0 software license, see the accompanying
// file LICENSE or <https://www.gnu.org/licenses/lgpl-3.0.html>

package apilogs

import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"sync/atomic"
"testing"

"github.com/gorilla/mux"
"github.com/stretchr/testify/assert"
)

type TestCase struct {
name string
method string
expectedHTTP int
startValue bool
expectedEndValue bool
requestBody bool
}

func marshalBody(tt TestCase, t *testing.T) []byte {
var reqBody []byte
var err error
if tt.method == "POST" {
reqBody, err = json.Marshal(Status{Enabled: tt.requestBody})
if err != nil {
t.Fatalf("could not marshal request body: %v", err)
}
}
return reqBody
}

func TestLogLevelHandler(t *testing.T) {
tests := []TestCase{
{
name: "Valid POST input - set logs to enabled",
method: "POST",
expectedHTTP: http.StatusOK,
startValue: false,
requestBody: true,
expectedEndValue: true,
},
{
name: "Valid POST input - set logs to disabled",
method: "POST",
expectedHTTP: http.StatusOK,
startValue: true,
requestBody: false,
expectedEndValue: false,
},
{
name: "GET request - get current level INFO",
method: "GET",
expectedHTTP: http.StatusOK,
startValue: true,
expectedEndValue: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
logLevel := atomic.Bool{}
logLevel.Store(tt.startValue)

reqBodyBytes := marshalBody(tt, t)

req, err := http.NewRequest(tt.method, "/admin/apilogs", bytes.NewBuffer(reqBodyBytes))
if err != nil {
t.Fatal(err)
}

rr := httptest.NewRecorder()
router := mux.NewRouter()
New(&logLevel).Mount(router, "/admin/apilogs")
router.ServeHTTP(rr, req)

assert.Equal(t, tt.expectedHTTP, rr.Code)
responseBody := Status{}
assert.NoError(t, json.Unmarshal(rr.Body.Bytes(), &responseBody))
assert.Equal(t, tt.expectedEndValue, responseBody.Enabled)
})
}
}
Loading
Loading