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

algod:Stateproof server api #3888

Merged
merged 19 commits into from
May 2, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
adding range of possible rounds to look for state-proofs.
  • Loading branch information
algonathan committed Apr 14, 2022
commit e29ee82eb0c33a1e6b04ec18ba8f1226abe107b7
31 changes: 26 additions & 5 deletions daemon/algod/api/server/v2/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -1172,10 +1172,17 @@ func (v2 *Handlers) StateProof(ctx echo.Context, round uint64) error {
return notFound(ctx, err, fmt.Sprintf("could not retrieve consensus information for round (%d)", round), v2.Log)
}

// as a start we presume the rounds given are only from current rounds
// assuming i'm starting from rounds where a compcert are valid.
for current := round; current > round-consensus.CompactCertRounds && current > 0; current-- {
block, err := ledger.Block(basics.Round(current))
rounds := PossibleRoundsContainingStateProofs(basics.Round(round), consensus)

// cutting rounds that are above the latest round from our search.
latest := ledger.Latest()
if latest-rounds[0]+1 < basics.Round(len(rounds)) {
rounds = rounds[:latest-rounds[0]+1]
}

// TODO: what happens if we are stuck in creating a state-proof? are the rounds im looking through enough?.
for _, rnd := range rounds {
block, err := ledger.Block(rnd)
if err != nil {
return internalError(ctx, err, "couldn't retrieve block, and locate state-proof", v2.Log)
}
Expand All @@ -1191,7 +1198,21 @@ func (v2 *Handlers) StateProof(ctx echo.Context, round uint64) error {
}
return ctx.JSON(http.StatusOK, response)
}
return notFound(ctx, errNoStateProofInRange, fmt.Sprintf("could not find state-proof for round (%d)", round), v2.Log)
return notFound(ctx, errNoStateProofInRange, fmt.Sprintf("could not find state-proof for round (%d), please re-attempt later", round), v2.Log)
}

// PossibleRoundsContainingStateProofs returns a sorted array representing the rounds that should contain the wanted state proof.
func PossibleRoundsContainingStateProofs(wantedRound basics.Round, consensus config.ConsensusParams) []basics.Round {
rnd := uint64(wantedRound)
// where does the range sit?
//N+R
// find the first N that im above of.
compcertLocation := rnd - (rnd % consensus.CompactCertRounds) + consensus.CompactCertRounds
roundRange := make([]basics.Round, 0, consensus.CompactCertRounds)
for i := wantedRound; i <= basics.Round(compcertLocation); i++ {
roundRange = append(roundRange, i)
}
return roundRange
}

func searchForCompactCert(block bookkeeping.Block) *transactions.Transaction {
Expand Down
27 changes: 27 additions & 0 deletions daemon/algod/api/server/v2/test/handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"bytes"
"encoding/json"
"errors"
"github.com/algorand/go-algorand/config"
"io"
"net/http"
"net/http/httptest"
Expand Down Expand Up @@ -868,3 +869,29 @@ func TestStateProof404(t *testing.T) {
a.NoError(handler.StateProof(ctx, 2))
algonathan marked this conversation as resolved.
Show resolved Hide resolved
a.Equal(404, responseRecorder.Code)
}

func TestRangeFinder(t *testing.T) {
consensusCopy := config.Consensus[protocol.ConsensusCurrentVersion]
consensusCopy.CompactCertRounds = 128
// middle of the range
rng := v2.PossibleRoundsContainingStateProofs(312, consensusCopy)
a := require.New(t)
a.True(inrange(312, 384, rng))

// beginning of the range.
rng = v2.PossibleRoundsContainingStateProofs(256, consensusCopy)
a.True(inrange(256, 384, rng))

// end of the range.
rng = v2.PossibleRoundsContainingStateProofs(383, consensusCopy)
a.True(inrange(383, 512, rng))
}

func inrange(min, max basics.Round, arr []basics.Round) bool {
for _, round := range arr {
if round < min || round > max {
return false
}
}
return true
}