Skip to content

Commit

Permalink
Merge branch 'master' into log_verb
Browse files Browse the repository at this point in the history
  • Loading branch information
MakisChristou authored Aug 19, 2024
2 parents 8edfdd1 + 8ba7f54 commit 0fda3ef
Show file tree
Hide file tree
Showing 16 changed files with 216 additions and 47 deletions.
23 changes: 23 additions & 0 deletions .github/ISSUE_TEMPLATE/feature-request.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: "💡 Feature Request"
description: Create a new issue for a feature request or enhancement.
title: "💡<feature | enhancement> | <domain> - <title>"
labels: [
"feature"
]
body:
- type: textarea
id: summary
attributes:
label: "Summary"
description: Provide a brief explanation of the feature.
placeholder: Describe the feature you would like to see implemented.
validations:
required: true
- type: textarea
id: motivation
attributes:
label: "Motivation"
description: Why do you need this feature?
placeholder: Explain why you need this feature.
validations:
required: true
1 change: 1 addition & 0 deletions .github/workflows/on-master-commit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ jobs:
tags: |
type=raw,value=master-${{ needs.generate-tags.outputs.tag_date }}-${{ needs.generate-tags.outputs.short_sha }}
type=raw,value=master-latest
trigger_internal_ci: true

notify-slack:
name: Notify Slack
Expand Down
23 changes: 22 additions & 1 deletion .github/workflows/publish-docker-images.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,18 @@ on:
type: string
required: true
description: 'The images to publish'
trigger_internal_ci:
description: 'Trigger the internal CI'
required: false
type: boolean
default: false
workflow_dispatch:
inputs:
trigger_internal_ci:
description: 'Trigger the internal CI'
required: true
type: boolean
default: false

jobs:
build-and-push-image:
Expand Down Expand Up @@ -66,7 +77,7 @@ jobs:
tags: ${{ inputs.tags || format('type=raw,value={0}-{1}', github.ref_name, github.sha) }}

- name: Push to Registry(s)
uses: docker/build-push-action@v5
uses: docker/build-push-action@v6
with:
context: .
platforms: ${{ github.event_name != 'pull_request' && 'linux/amd64,linux/arm64' || 'linux/amd64' }}
Expand All @@ -84,3 +95,13 @@ jobs:
annotations: true
severity: LOW
dockerfile: ./Dockerfile

- name: Internal CI
uses: peter-evans/repository-dispatch@v3
if: ${{ inputs.trigger_internal_ci }}
continue-on-error: true
with:
token: ${{ secrets.INTERNAL_CI_TOKEN }}
repository: vechain/thor-internal-ci
event-type: internal-thor-ci
client-payload: '{"thor_image": "${{ fromJSON(steps.build-and-push-image.outputs.meta.json).tags[0] }}"}'
2 changes: 1 addition & 1 deletion .github/workflows/test-e2e.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
with:
repository: vechain/thor-e2e-tests
# https://github.com/vechain/thor-e2e-tests/tree/00bd3f1b949b05da94e82686e0089a11a136c34c
ref: 4f984b8afd3bb21639f6838fd8c99bf64a9367f2
ref: 87aeb1747995e8b235a796303b0fc08ab16262c6

- name: Download artifact
uses: actions/download-artifact@v4
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Build thor in a stock Go builder container
FROM golang:1.22-alpine3.20 as builder
FROM golang:1.22-alpine3.20 AS builder

RUN apk add --no-cache make gcc musl-dev linux-headers git
WORKDIR /go/thor
Expand Down
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@

## Getting Started

VechainThor is the layer 1 blockchain, highly compatible with EVM<sup>*</sup>, which powers the vechain ecosystem.
VechainThor is a public blockchain that is designed for the mass adoption of blockchain technology by enterprise users
VeChainThor is the layer 1 blockchain, highly compatible with EVM<sup>*</sup>, which powers the VeChain ecosystem.
VeChainThor is a public blockchain that is designed for the mass adoption of blockchain technology by enterprise users
of all sizes and is intended to serve as a foundation for a sustainable and scalable enterprise blockchain ecosystem.

> VechainThor is currently up-to-date with the EVM's `paris` hard fork,
> VeChainThor is currently up-to-date with the EVM's `paris` hard fork,
> set [evmVersion](https://docs.soliditylang.org/en/latest/using-the-compiler.html#setting-the-evm-version-to-target)
> to `paris` if you are using solidity compiler version `0.8.20` or above.
___
Expand All @@ -47,17 +47,17 @@ ___
- [Build](./docs/build.md) - How to build the `thor` binary.
- [Usage](./docs/usage.md) - How to run thor with different configurations.
- [Hosting a Node](./docs/hosting-a-node.md) - Considerations and requirements for hosting a node.
- [Core Concepts](https://docs.vechain.org/core-concepts) - Core concepts of the VechainThor blockchain.
- [API Reference](https://mainnet.vechain.org) - The API reference for the VechainThor blockchain.
- [Core Concepts](https://docs.vechain.org/core-concepts) - Core concepts of the VeChainThor blockchain.
- [API Reference](https://mainnet.vechain.org) - The API reference for the VeChainThor blockchain.

---

## Community

The VechainThor community can be found on [Discourse](https://vechain.discourse.group/) where you can ask questions,
The VeChainThor community can be found on [Discourse](https://vechain.discourse.group/) where you can ask questions,
voice ideas, and share your projects with other people.

The Vechain Improvement Proposals (VIPs) repository can be found [here](https://github.com/vechain/VIPs).
The VeChain Improvement Proposals (VIPs) repository can be found [here](https://github.com/vechain/VIPs).

To chat with other community members you can join:

Expand All @@ -67,16 +67,16 @@ To chat with other community members you can join:
<a href="https://www.reddit.com/r/Vechain"><img src="https://img.shields.io/badge/Reddit-FF4500?style=for-the-badge&logo=reddit&logoColor=white"/></a>
</p>

Do note that our [Code of Conduct](./docs/CODE_OF_CONDUCT.md) applies to all vechain community channels. Users are
Do note that our [Code of Conduct](./docs/CODE_OF_CONDUCT.md) applies to all VeChain community channels. Users are
**highly encouraged** to read and adhere to them to avoid repercussions.

---

## Contributing

Contributions to VechainThor are welcome and highly appreciated. However, before you jump right into it, we would like
Contributions to VeChainThor are welcome and highly appreciated. However, before you jump right into it, we would like
you to review our [Contribution Guidelines](./docs/CONTRIBUTING.md) to make sure you have a smooth experience
contributing to VechainThor.
contributing to VeChainThor.

---

Expand All @@ -102,6 +102,6 @@ A special shout out to following projects:

## License

Vechain Thor is licensed under the [GNU Lesser General Public License v3.0](https://www.gnu.org/licenses/lgpl-3.0.html),
VeChainThor is licensed under the [GNU Lesser General Public License v3.0](https://www.gnu.org/licenses/lgpl-3.0.html),
also included in *LICENSE* file in repository.

11 changes: 11 additions & 0 deletions api/debug/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ import (
"github.com/vechain/thor/v2/xenv"
)

const defaultMaxStorageResult = 1000

var devNetGenesisID = genesis.NewDevnet().ID()

type Debug struct {
Expand Down Expand Up @@ -296,6 +298,15 @@ func (d *Debug) handleDebugStorage(w http.ResponseWriter, req *http.Request) err
if err := utils.ParseJSON(req.Body, &opt); err != nil {
return utils.BadRequest(errors.WithMessage(err, "body"))
}

if opt.MaxResult > defaultMaxStorageResult {
return utils.BadRequest(errors.Errorf("maxResult: exceeds limit of %d", defaultMaxStorageResult))
}

if opt.MaxResult == 0 {
opt.MaxResult = defaultMaxStorageResult
}

blockID, txIndex, clauseIndex, err := d.parseTarget(opt.Target)
if err != nil {
return err
Expand Down
57 changes: 55 additions & 2 deletions api/debug/debug_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/gorilla/mux"
"github.com/stretchr/testify/assert"
"github.com/vechain/thor/v2/block"
"github.com/vechain/thor/v2/builtin"
"github.com/vechain/thor/v2/chain"
"github.com/vechain/thor/v2/cmd/thor/solo"
"github.com/vechain/thor/v2/genesis"
Expand Down Expand Up @@ -84,8 +85,9 @@ func TestDebug(t *testing.T) {

// /storage/range endpoint
for name, tt := range map[string]func(*testing.T){
"testStorageRangeWithError": testStorageRangeWithError,
"testStorageRange": testStorageRange,
"testStorageRangeWithError": testStorageRangeWithError,
"testStorageRange": testStorageRange,
"testStorageRangeDefaultOption": testStorageRangeDefaultOption,
} {
t.Run(name, tt)
}
Expand Down Expand Up @@ -121,6 +123,39 @@ func TestStorageRangeFunc(t *testing.T) {
assert.Equal(t, 1, len(storage))
}

func TestStorageRangeMaxResult(t *testing.T) {
db := muxdb.NewMem()
state := state.New(db, thor.Bytes32{}, 0, 0, 0)

addr := thor.BytesToAddress([]byte("account1"))
for i := 0; i < 1001; i++ {
key := thor.BytesToBytes32([]byte(fmt.Sprintf("key%d", i)))
value := thor.BytesToBytes32([]byte(fmt.Sprintf("value%d", i)))
state.SetRawStorage(addr, key, value[:])
}

trie, err := state.BuildStorageTrie(addr)
if err != nil {
t.Fatal(err)
}
start, err := hexutil.Decode("0x00")
if err != nil {
t.Fatal(err)
}

storageRangeRes, err := storageRangeAt(trie, start, 1001)
assert.NoError(t, err)
assert.Equal(t, 1001, len(storageRangeRes.Storage))

storageRangeRes, err = storageRangeAt(trie, start, 1000)
assert.NoError(t, err)
assert.Equal(t, 1000, len(storageRangeRes.Storage))

storageRangeRes, err = storageRangeAt(trie, start, 10)
assert.NoError(t, err)
assert.Equal(t, 10, len(storageRangeRes.Storage))
}

func testTraceClauseWithEmptyTracerTarget(t *testing.T) {
res := httpPostAndCheckResponseStatus(t, ts.URL+"/debug/tracers", &TraceClauseOption{}, 400)
assert.Equal(t, "target: unsupported", strings.TrimSpace(res))
Expand Down Expand Up @@ -418,6 +453,9 @@ func testStorageRangeWithError(t *testing.T) {
// Error case 2: bad StorageRangeOption
badBodyRequest := 123
httpPostAndCheckResponseStatus(t, ts.URL+"/debug/storage-range", badBodyRequest, 400)

badMaxResult := &StorageRangeOption{MaxResult: 1001}
httpPostAndCheckResponseStatus(t, ts.URL+"/debug/storage-range", badMaxResult, 400)
}

func testStorageRange(t *testing.T) {
Expand All @@ -441,6 +479,21 @@ func testStorageRange(t *testing.T) {
assert.Equal(t, expectedStorageRangeResult, parsedExecutionRes)
}

func testStorageRangeDefaultOption(t *testing.T) {
opt := StorageRangeOption{
Address: builtin.Energy.Address,
Target: fmt.Sprintf("%s/%s/0", blk.Header().ID(), transaction.ID()),
}

res := httpPostAndCheckResponseStatus(t, ts.URL+"/debug/storage-range", &opt, 200)

var storageRangeRes *StorageRangeResult
if err := json.Unmarshal([]byte(res), &storageRangeRes); err != nil {
t.Fatal(err)
}
assert.NotZero(t, len(storageRangeRes.Storage))
}

func initDebugServer(t *testing.T) {
db := muxdb.NewMem()
stater := state.NewStater(db)
Expand Down
10 changes: 5 additions & 5 deletions api/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ import (
)

var (
metricHttpReqCounter = metrics.LazyLoadCounterVec("api_request_count", []string{"name", "code", "method"})
metricHttpReqDuration = metrics.LazyLoadHistogramVec("api_duration_ms", []string{"name", "code", "method"}, metrics.BucketHTTPReqs)
metricsActiveWebsocketCount = metrics.LazyLoadGaugeVec("api_active_websocket_count", []string{"subject"})
metricHttpReqCounter = metrics.LazyLoadCounterVec("api_request_count", []string{"name", "code", "method"})
metricHttpReqDuration = metrics.LazyLoadHistogramVec("api_duration_ms", []string{"name", "code", "method"}, metrics.BucketHTTPReqs)
metricActiveWebsocketCount = metrics.LazyLoadGaugeVec("api_active_websocket_count", []string{"subject"})
)

// metricsResponseWriter is a wrapper around http.ResponseWriter that captures the status code.
Expand Down Expand Up @@ -81,13 +81,13 @@ func metricsMiddleware(next http.Handler) http.Handler {
now := time.Now()
mrw := newMetricsResponseWriter(w)
if subscription != "" {
metricsActiveWebsocketCount().AddWithLabel(1, map[string]string{"subject": subscription})
metricActiveWebsocketCount().AddWithLabel(1, map[string]string{"subject": subscription})
}

next.ServeHTTP(mrw, r)

if subscription != "" {
metricsActiveWebsocketCount().AddWithLabel(-1, map[string]string{"subject": subscription})
metricActiveWebsocketCount().AddWithLabel(-1, map[string]string{"subject": subscription})
} else if enabled {
metricHttpReqCounter().AddWithLabel(1, map[string]string{"name": name, "code": strconv.Itoa(mrw.statusCode), "method": r.Method})
metricHttpReqDuration().ObserveWithLabels(time.Since(now).Milliseconds(), map[string]string{"name": name, "code": strconv.Itoa(mrw.statusCode), "method": r.Method})
Expand Down
27 changes: 8 additions & 19 deletions api/metrics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
"net/url"
"strings"
"testing"
"time"

"github.com/gorilla/mux"
"github.com/gorilla/websocket"
Expand Down Expand Up @@ -129,8 +128,9 @@ func TestWebsocketMetrics(t *testing.T) {

// initiate 1 beat subscription, active websocket should be 1
u := url.URL{Scheme: "ws", Host: strings.TrimPrefix(ts.URL, "http://"), Path: "/subscriptions/beat"}
conn, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
conn1, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
assert.Nil(t, err)
defer conn1.Close()

body, _ := httpGet(t, ts.URL+"/metrics")
parser := expfmt.TextParser{}
Expand All @@ -146,8 +146,9 @@ func TestWebsocketMetrics(t *testing.T) {
assert.Equal(t, "beat", labels[0].GetValue())

// initiate 1 beat subscription, active websocket should be 2
_, _, err = websocket.DefaultDialer.Dial(u.String(), nil)
conn2, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
assert.Nil(t, err)
defer conn2.Close()

body, _ = httpGet(t, ts.URL+"/metrics")
metrics, err = parser.TextToMetricFamilies(bytes.NewReader(body))
Expand All @@ -157,23 +158,11 @@ func TestWebsocketMetrics(t *testing.T) {
assert.Equal(t, 1, len(m), "should be 1 metric entries")
assert.Equal(t, float64(2), m[0].GetGauge().GetValue())

// close 1 beat subscription, active websocket should be 1
conn.Close()
// ensure close is done
<-time.After(100 * time.Millisecond)

body, _ = httpGet(t, ts.URL+"/metrics")
metrics, err = parser.TextToMetricFamilies(bytes.NewReader(body))
assert.Nil(t, err)

m = metrics["thor_metrics_api_active_websocket_count"].GetMetric()
assert.Equal(t, 1, len(m), "should be 1 metric entries")
assert.Equal(t, float64(1), m[0].GetGauge().GetValue())

// initiate 1 block subscription, active websocket should be 2
// initiate 1 block subscription, active websocket should be 3
u = url.URL{Scheme: "ws", Host: strings.TrimPrefix(ts.URL, "http://"), Path: "/subscriptions/block"}
_, _, err = websocket.DefaultDialer.Dial(u.String(), nil)
conn3, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
assert.Nil(t, err)
defer conn3.Close()

body, _ = httpGet(t, ts.URL+"/metrics")
metrics, err = parser.TextToMetricFamilies(bytes.NewReader(body))
Expand All @@ -182,7 +171,7 @@ func TestWebsocketMetrics(t *testing.T) {
m = metrics["thor_metrics_api_active_websocket_count"].GetMetric()
assert.Equal(t, 2, len(m), "should be 2 metric entries")
// both m[0] and m[1] should have the value of 1
assert.Equal(t, float64(1), m[0].GetGauge().GetValue())
assert.Equal(t, float64(2), m[0].GetGauge().GetValue())
assert.Equal(t, float64(1), m[1].GetGauge().GetValue())

// m[1] should have the subject of block
Expand Down
2 changes: 1 addition & 1 deletion cmd/thor/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.1.3
2.2.0
Loading

0 comments on commit 0fda3ef

Please sign in to comment.