Skip to content
Open
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
25 changes: 12 additions & 13 deletions api/accounts/accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/pkg/errors"
"github.com/vechain/thor/v2/api/utils"
"github.com/vechain/thor/v2/bft"
"github.com/vechain/thor/v2/block"
"github.com/vechain/thor/v2/chain"
"github.com/vechain/thor/v2/runtime"
"github.com/vechain/thor/v2/state"
Expand Down Expand Up @@ -65,7 +66,7 @@ func (a *Accounts) handleGetCode(w http.ResponseWriter, req *http.Request) error
if err != nil {
return utils.BadRequest(errors.WithMessage(err, "address"))
}
revision, err := utils.ParseRevision(req.URL.Query().Get("revision"))
revision, err := utils.ParseRevision(req.URL.Query().Get("revision"), false)
if err != nil {
return utils.BadRequest(errors.WithMessage(err, "revision"))
}
Expand Down Expand Up @@ -121,7 +122,7 @@ func (a *Accounts) handleGetAccount(w http.ResponseWriter, req *http.Request) er
if err != nil {
return utils.BadRequest(errors.WithMessage(err, "address"))
}
revision, err := utils.ParseRevision(req.URL.Query().Get("revision"))
revision, err := utils.ParseRevision(req.URL.Query().Get("revision"), false)
if err != nil {
return utils.BadRequest(errors.WithMessage(err, "revision"))
}
Expand All @@ -148,7 +149,7 @@ func (a *Accounts) handleGetStorage(w http.ResponseWriter, req *http.Request) er
if err != nil {
return utils.BadRequest(errors.WithMessage(err, "key"))
}
revision, err := utils.ParseRevision(req.URL.Query().Get("revision"))
revision, err := utils.ParseRevision(req.URL.Query().Get("revision"), false)
if err != nil {
return utils.BadRequest(errors.WithMessage(err, "revision"))
}
Expand All @@ -171,11 +172,11 @@ func (a *Accounts) handleCallContract(w http.ResponseWriter, req *http.Request)
if err := utils.ParseJSON(req.Body, &callData); err != nil {
return utils.BadRequest(errors.WithMessage(err, "body"))
}
revision, err := utils.ParseRevision(req.URL.Query().Get("revision"))
revision, err := utils.ParseRevision(req.URL.Query().Get("revision"), true)
if err != nil {
return utils.BadRequest(errors.WithMessage(err, "revision"))
}
summary, err := utils.GetSummary(revision, a.repo, a.bft)
header, st, err := utils.GetHeaderAndState(revision, a.repo, a.bft, a.stater)
if err != nil {
if a.repo.IsNotFound(err) {
return utils.BadRequest(errors.WithMessage(err, "revision"))
Expand All @@ -202,7 +203,7 @@ func (a *Accounts) handleCallContract(w http.ResponseWriter, req *http.Request)
GasPrice: callData.GasPrice,
Caller: callData.Caller,
}
results, err := a.batchCall(req.Context(), batchCallData, summary)
results, err := a.batchCall(req.Context(), batchCallData, header, st)
if err != nil {
return err
}
Expand All @@ -214,34 +215,32 @@ func (a *Accounts) handleCallBatchCode(w http.ResponseWriter, req *http.Request)
if err := utils.ParseJSON(req.Body, &batchCallData); err != nil {
return utils.BadRequest(errors.WithMessage(err, "body"))
}
revision, err := utils.ParseRevision(req.URL.Query().Get("revision"))
revision, err := utils.ParseRevision(req.URL.Query().Get("revision"), true)
if err != nil {
return utils.BadRequest(errors.WithMessage(err, "revision"))
}
summary, err := utils.GetSummary(revision, a.repo, a.bft)
header, st, err := utils.GetHeaderAndState(revision, a.repo, a.bft, a.stater)
if err != nil {
if a.repo.IsNotFound(err) {
return utils.BadRequest(errors.WithMessage(err, "revision"))
}
return err
}
results, err := a.batchCall(req.Context(), batchCallData, summary)
results, err := a.batchCall(req.Context(), batchCallData, header, st)
if err != nil {
return err
}
return utils.WriteJSON(w, results)
}

func (a *Accounts) batchCall(ctx context.Context, batchCallData *BatchCallData, summary *chain.BlockSummary) (results BatchCallResults, err error) {
func (a *Accounts) batchCall(ctx context.Context, batchCallData *BatchCallData, header *block.Header, st *state.State) (results BatchCallResults, err error) {
txCtx, gas, clauses, err := a.handleBatchCallData(batchCallData)
if err != nil {
return nil, err
}
header := summary.Header
state := a.stater.NewState(header.StateRoot(), header.Number(), summary.Conflicts, summary.SteadyNum)

signer, _ := header.Signer()
rt := runtime.New(a.repo.NewChain(header.ParentID()), state,
rt := runtime.New(a.repo.NewChain(header.ParentID()), st,
&xenv.BlockContext{
Beneficiary: header.Beneficiary(),
Signer: signer,
Expand Down
11 changes: 11 additions & 0 deletions api/accounts/accounts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,13 @@ func callContract(t *testing.T) {
reqBody := &accounts.CallData{
Data: hexutil.Encode(input),
}

// next revisoun should be valid
_, statusCode = httpPost(t, ts.URL+"/accounts/"+contractAddr.String()+"?revision=next", reqBody)
assert.Equal(t, http.StatusOK, statusCode, "next revision should be okay")
_, statusCode = httpPost(t, ts.URL+"/accounts?revision=next", reqBody)
assert.Equal(t, http.StatusOK, statusCode, "next revision should be okay")

Comment on lines +378 to +384
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typographical issue and potential misunderstanding in parameter name

The parameter revisioun should be corrected to revision in the HTTP request URLs. This typographical error could lead to potential bugs or misunderstandings when interfacing with the API.

- httpPost(t, ts.URL+"/accounts?revisioun=next", reqBody)
+ httpPost(t, ts.URL+"/accounts?revision=next", reqBody)
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// next revisoun should be valid
_, statusCode = httpPost(t, ts.URL+"/accounts/"+contractAddr.String()+"?revision=next", reqBody)
assert.Equal(t, http.StatusOK, statusCode, "next revision should be okay")
_, statusCode = httpPost(t, ts.URL+"/accounts?revisioun=next", reqBody)
assert.Equal(t, http.StatusOK, statusCode, "next revision should be okay")
// next revisoun should be valid
_, statusCode = httpPost(t, ts.URL+"/accounts/"+contractAddr.String()+"?revision=next", reqBody)
assert.Equal(t, http.StatusOK, statusCode, "next revision should be okay")
_, statusCode = httpPost(t, ts.URL+"/accounts?revision=next", reqBody)
assert.Equal(t, http.StatusOK, statusCode, "next revision should be okay")

res, statusCode := httpPost(t, ts.URL+"/accounts/"+contractAddr.String(), reqBody)
var output *accounts.CallResult
if err = json.Unmarshal(res, &output); err != nil {
Expand Down Expand Up @@ -464,6 +471,10 @@ func batchCall(t *testing.T) {
}},
}

// 'next' revisoun should be valid
_, statusCode = httpPost(t, ts.URL+"/accounts/*?revision=next", reqBody)
assert.Equal(t, http.StatusOK, statusCode, "next revision should be okay")

res, statusCode := httpPost(t, ts.URL+"/accounts/*", reqBody)
var results accounts.BatchCallResults
if err = json.Unmarshal(res, &results); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion api/blocks/blocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func New(repo *chain.Repository, bft bft.Finalizer) *Blocks {
}

func (b *Blocks) handleGetBlock(w http.ResponseWriter, req *http.Request) error {
revision, err := utils.ParseRevision(mux.Vars(req)["revision"])
revision, err := utils.ParseRevision(mux.Vars(req)["revision"], false)
if err != nil {
return utils.BadRequest(errors.WithMessage(err, "revision"))
}
Expand Down
22 changes: 11 additions & 11 deletions api/debug/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/pkg/errors"
"github.com/vechain/thor/v2/api/utils"
"github.com/vechain/thor/v2/bft"
"github.com/vechain/thor/v2/block"
"github.com/vechain/thor/v2/chain"
"github.com/vechain/thor/v2/consensus"
"github.com/vechain/thor/v2/genesis"
Expand Down Expand Up @@ -177,11 +178,11 @@ func (d *Debug) handleTraceCall(w http.ResponseWriter, req *http.Request) error
if err := utils.ParseJSON(req.Body, &opt); err != nil {
return utils.BadRequest(errors.WithMessage(err, "body"))
}
revision, err := utils.ParseRevision(req.URL.Query().Get("revision"))
revision, err := utils.ParseRevision(req.URL.Query().Get("revision"), true)
if err != nil {
return utils.BadRequest(errors.WithMessage(err, "revision"))
}
summary, err := utils.GetSummary(revision, d.repo, d.bft)
header, st, err := utils.GetHeaderAndState(revision, d.repo, d.bft, d.stater)
if err != nil {
if d.repo.IsNotFound(err) {
return utils.BadRequest(errors.WithMessage(err, "revision"))
Expand All @@ -199,7 +200,7 @@ func (d *Debug) handleTraceCall(w http.ResponseWriter, req *http.Request) error
return err
}

res, err := d.traceCall(req.Context(), tracer, summary, txCtx, gas, clause)
res, err := d.traceCall(req.Context(), tracer, header, st, txCtx, gas, clause)
if err != nil {
return err
}
Expand All @@ -214,13 +215,12 @@ func (d *Debug) createTracer(name string, config json.RawMessage) (tracers.Trace
return tracers.DefaultDirectory.New(name, config, d.allowCustomTracer)
}

func (d *Debug) traceCall(ctx context.Context, tracer tracers.Tracer, summary *chain.BlockSummary, txCtx *xenv.TransactionContext, gas uint64, clause *tx.Clause) (interface{}, error) {
header := summary.Header
state := d.stater.NewState(header.StateRoot(), header.Number(), summary.Conflicts, summary.SteadyNum)
func (d *Debug) traceCall(ctx context.Context, tracer tracers.Tracer, header *block.Header, st *state.State, txCtx *xenv.TransactionContext, gas uint64, clause *tx.Clause) (interface{}, error) {
signer, _ := header.Signer()

rt := runtime.New(
d.repo.NewChain(header.ID()),
state,
d.repo.NewChain(header.ParentID()),
st,
&xenv.BlockContext{
Beneficiary: header.Beneficiary(),
Signer: signer,
Expand All @@ -232,9 +232,9 @@ func (d *Debug) traceCall(ctx context.Context, tracer tracers.Tracer, summary *c
d.forkConfig)

tracer.SetContext(&tracers.Context{
BlockID: summary.Header.ID(),
BlockTime: summary.Header.Timestamp(),
State: state,
BlockID: header.ID(),
BlockTime: header.Timestamp(),
State: st,
})
rt.SetVMConfig(vm.Config{Tracer: tracer})

Expand Down
6 changes: 6 additions & 0 deletions api/debug/debug_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ func TestDebug(t *testing.T) {
testHandleTraceCallWithMalformedBodyRequest(t)
testHandleTraceCallWithEmptyTraceCallOption(t)
testHandleTraceCall(t)
testTraceCallNextBlock(t)
testHandleTraceCallWithValidRevisions(t)
testHandleTraceCallWithRevisionAsNonExistingHeight(t)
testHandleTraceCallWithRevisionAsNonExistingId(t)
Expand Down Expand Up @@ -250,6 +251,11 @@ func testHandleTraceCallWithEmptyTraceCallOption(t *testing.T) {
assert.Equal(t, expectedExecutionResult, parsedExecutionRes)
}

func testTraceCallNextBlock(t *testing.T) {
traceCallOption := &TraceCallOption{}
httpPostAndCheckResponseStatus(t, ts.URL+"/debug/tracers/call?revision=next", traceCallOption, 200)
}

func testHandleTraceCall(t *testing.T) {
addr := randAddress()
provedWork := math.HexOrDecimal256(*big.NewInt(1000))
Expand Down
34 changes: 24 additions & 10 deletions api/doc/thor.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ info:
license:
name: LGPL 3.0
url: https://www.gnu.org/licenses/lgpl-3.0.en.html
version: 2.1.2
version: 2.1.3
servers:
- url: /
description: Current Node
Expand Down Expand Up @@ -70,7 +70,7 @@ paths:
/accounts/*:
post:
parameters:
- $ref: '#/components/parameters/RevisionInQuery'
- $ref: '#/components/parameters/CallCodeRevisionInQuery'
tags:
- Accounts
summary: Inspect clauses
Expand All @@ -90,7 +90,7 @@ paths:
content:
application/json:
schema:
$ref : '#/components/schemas/ExecuteCodesRequest'
$ref: '#/components/schemas/ExecuteCodesRequest'
responses:
'200':
description: OK
Expand Down Expand Up @@ -693,7 +693,7 @@ paths:

You can customize the tracer using various options to suit your debugging requirements.
parameters:
- $ref: '#/components/parameters/RevisionInQuery'
- $ref: '#/components/parameters/CallCodeRevisionInQuery'
requestBody:
required: true
content:
Expand Down Expand Up @@ -817,13 +817,13 @@ components:
- "0x000000000000000000000000435933c8064b4ae76be665428e0307ef2ccfbd68"
- "0x0000000000000000000000000f872421dc479f3c11edd89512731814d0598db5"
data: "0x0000000000000000000000000000000000000000000000013f306a2409fc0000"
transfers: []
transfers: [ ]
gasUsed: 13326
reverted: false
vmError: ""
# VET Transfer
- data: "0x"
events: []
events: [ ]
transfers:
- sender: "0x435933c8064b4ae76be665428e0307ef2ccfbd68"
recipient: "0xf077b491b355e64048ce21e3a6fc4751eeea77fa"
Expand All @@ -838,7 +838,7 @@ components:
topics:
- "0xb35bf4274d4295009f1ec66ed3f579db287889444366c03d3a695539372e8951"
data: "0x000000000000000000000000435933c8064b4ae76be665428e0307ef2ccfbd68"
transfers: []
transfers: [ ]
gasUsed: 31881
reverted: false
vmError: ""
Expand Down Expand Up @@ -1184,7 +1184,7 @@ components:
example:
target: '0x010709463c1f0c9aa66a31182fb36d1977d99bfb6526bae0564a0eac4006c31a/0/0'
name: "prestate"
config: {}
config: { }

PostDebugTracerCallRequest:
title: PostDebugTracerCallRequest
Expand Down Expand Up @@ -2132,11 +2132,11 @@ components:
type: object
description: |
The configuration of the tracer. It is specific to the `name`
example: {}
example: { }
nullable: true
example:
name: "prestate"
config: {}
config: { }

StorageRangeOption:
type: object
Expand Down Expand Up @@ -2253,6 +2253,20 @@ components:
schema:
type: string

CallCodeRevisionInQuery:
name: revision
in: query
description: |
Specify either `best`,`next`, `finalized`, a block number or block ID. If omitted, the `best` block is assumed.

If the `next` block is specified, the call code will be executed on the next block, with the following:
- The block number is the `best` block number plus one.
- The timestamp is the `best` block timestamp plus the block interval.
- Total score, gas limit and beneficiary are the same as the `best` block.
- The signer will be the zero address
schema:
type: string

RevisionInPath:
name: revision
in: path
Expand Down
Loading