Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into dnsaddr-add-del
Browse files Browse the repository at this point in the history
  • Loading branch information
Eric-Warehime committed Aug 2, 2023
2 parents 887c4b0 + ea9efcd commit 60c402b
Show file tree
Hide file tree
Showing 49 changed files with 337 additions and 692 deletions.
3 changes: 0 additions & 3 deletions .github/workflows/tools.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ on:
- 'tools/block-generator/**'
- 'tools/x-repo-types/**'
pull_request:
paths:
- 'tools/block-generator/**'
- 'tools/x-repo-types/**'

jobs:
tools_test:
Expand Down
5 changes: 2 additions & 3 deletions cmd/algons/dnsaddrCmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ var dnsaddrTreeCmd = &cobra.Command{
}
},
}

var dnsaddrTreeDeleteCmd = &cobra.Command{
Use: "delete",
Short: "Recursively resolves and deletes the dnsaddr entries of the given domain",
Expand All @@ -97,8 +96,8 @@ var dnsaddrTreeDeleteCmd = &cobra.Command{
}
cloudflareDNS := cloudflare.NewDNS(cfZoneID, cfToken)
var recordsToDelete []cloudflare.DNSRecordResponseEntry
err = dnsaddr.Iterate(addr, controller, func(dnsaddr multiaddr.Multiaddr, entries []multiaddr.Multiaddr) error {
domain, _ := dnsaddr.ValueForProtocol(multiaddr.P_DNSADDR)
err = dnsaddr.Iterate(addr, controller, func(entryFrom multiaddr.Multiaddr, entries []multiaddr.Multiaddr) error {
domain, _ := entryFrom.ValueForProtocol(multiaddr.P_DNSADDR)
name := fmt.Sprintf("_dnsaddr.%s", domain)
fmt.Printf("listing records for %s\n", name)
records, err := cloudflareDNS.ListDNSRecord(context.Background(), "TXT", name, "", "", "", "")
Expand Down
4 changes: 0 additions & 4 deletions cmd/tealdbg/localLedger.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,10 +281,6 @@ func (l *localLedger) BlockHdr(basics.Round) (bookkeeping.BlockHeader, error) {
return bookkeeping.BlockHeader{}, nil
}

func (l *localLedger) BlockHdrCached(basics.Round) (bookkeeping.BlockHeader, error) {
return bookkeeping.BlockHeader{}, nil
}

func (l *localLedger) GetStateProofVerificationContext(_ basics.Round) (*ledgercore.StateProofVerificationContext, error) {
return nil, fmt.Errorf("localLedger: GetStateProofVerificationContext, needed for state proof verification, is not implemented in debugger")
}
Expand Down
5 changes: 3 additions & 2 deletions daemon/algod/api/algod.oas2.json
Original file line number Diff line number Diff line change
Expand Up @@ -1111,7 +1111,7 @@
"public",
"nonparticipating"
],
"description": "Waits for a block to appear after round {round} and returns the node's status at the time.",
"description": "Waits for a block to appear after round {round} and returns the node's status at the time. There is a 1 minute timeout, when reached the current status is returned regardless of whether or not it is the round after the given round.",
"produces": [
"application/json"
],
Expand All @@ -1132,10 +1132,11 @@
],
"responses": {
"200": {
"description": "The round after the given round, or the current round if a timeout occurs.",
"$ref": "#/responses/NodeStatusResponse"
},
"400": {
"description": "Bad Request -- number must be non-negative integer ",
"description": "Bad Request -- number must be non-negative integer",
"schema": {
"$ref": "#/definitions/ErrorResponse"
}
Expand Down
4 changes: 2 additions & 2 deletions daemon/algod/api/algod.oas3.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5499,7 +5499,7 @@
},
"/v2/status/wait-for-block-after/{round}": {
"get": {
"description": "Waits for a block to appear after round {round} and returns the node's status at the time.",
"description": "Waits for a block to appear after round {round} and returns the node's status at the time. There is a 1 minute timeout, when reached the current status is returned regardless of whether or not it is the round after the given round.",
"operationId": "WaitForBlock",
"parameters": [
{
Expand Down Expand Up @@ -5648,7 +5648,7 @@
}
}
},
"description": "Bad Request -- number must be non-negative integer "
"description": "Bad Request -- number must be non-negative integer"
},
"401": {
"content": {
Expand Down
4 changes: 0 additions & 4 deletions daemon/algod/api/server/v2/dryrun.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,10 +241,6 @@ func (dl *dryrunLedger) BlockHdr(basics.Round) (bookkeeping.BlockHeader, error)
return bookkeeping.BlockHeader{}, nil
}

func (dl *dryrunLedger) BlockHdrCached(basics.Round) (bookkeeping.BlockHeader, error) {
return bookkeeping.BlockHeader{}, nil
}

func (dl *dryrunLedger) CheckDup(config.ConsensusParams, basics.Round, basics.Round, basics.Round, transactions.Txid, ledgercore.Txlease) error {
return nil
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion daemon/algod/api/server/v2/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ const MaxTealSourceBytes = 200_000
// become quite large, so we allow up to 1MB
const MaxTealDryrunBytes = 1_000_000

// WaitForBlockTimeout is the timeout for the WaitForBlock endpoint.
var WaitForBlockTimeout = 1 * time.Minute

// Handlers is an implementation to the V2 route handler interface defined by the generated code.
type Handlers struct {
Node NodeInterface
Expand Down Expand Up @@ -863,7 +866,7 @@ func (v2 *Handlers) WaitForBlock(ctx echo.Context, round uint64) error {
select {
case <-v2.Shutdown:
return internalError(ctx, err, errServiceShuttingDown, v2.Log)
case <-time.After(1 * time.Minute):
case <-time.After(WaitForBlockTimeout):
case <-ledger.Wait(basics.Round(round + 1)):
}

Expand Down
75 changes: 71 additions & 4 deletions daemon/algod/api/server/v2/test/handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,19 @@ import (
const stateProofInterval = uint64(256)

func setupMockNodeForMethodGet(t *testing.T, status node.StatusReport, devmode bool) (v2.Handlers, echo.Context, *httptest.ResponseRecorder, []account.Root, []transactions.SignedTxn, func()) {
return setupMockNodeForMethodGetWithShutdown(t, status, devmode, make(chan struct{}))
}

func setupMockNodeForMethodGetWithShutdown(t *testing.T, status node.StatusReport, devmode bool, shutdown chan struct{}) (v2.Handlers, echo.Context, *httptest.ResponseRecorder, []account.Root, []transactions.SignedTxn, func()) {
numAccounts := 1
numTransactions := 1
offlineAccounts := true
mockLedger, rootkeys, _, stxns, releasefunc := testingenv(t, numAccounts, numTransactions, offlineAccounts)
mockNode := makeMockNode(mockLedger, t.Name(), nil, status, devmode)
dummyShutdownChan := make(chan struct{})
handler := v2.Handlers{
Node: mockNode,
Log: logging.Base(),
Shutdown: dummyShutdownChan,
Shutdown: shutdown,
}
e := echo.New()
req := httptest.NewRequest(http.MethodGet, "/", nil)
Expand Down Expand Up @@ -585,9 +588,73 @@ func TestGetStatusAfterBlock(t *testing.T) {
defer releasefunc()
err := handler.WaitForBlock(c, 0)
require.NoError(t, err)
// Expect 400 - the test ledger will always cause "errRequestedRoundInUnsupportedRound",
// as it has not participated in agreement to build blockheaders

require.Equal(t, 400, rec.Code)
msg, err := io.ReadAll(rec.Body)
require.NoError(t, err)
require.Contains(t, string(msg), "requested round would reach only after the protocol upgrade which isn't supported")
}

func TestGetStatusAfterBlockShutdown(t *testing.T) {
partitiontest.PartitionTest(t)
t.Parallel()

catchup := cannedStatusReportGolden
catchup.StoppedAtUnsupportedRound = false
shutdownChan := make(chan struct{})
handler, c, rec, _, _, releasefunc := setupMockNodeForMethodGetWithShutdown(t, catchup, false, shutdownChan)
defer releasefunc()

close(shutdownChan)
err := handler.WaitForBlock(c, 0)
require.NoError(t, err)

require.Equal(t, 500, rec.Code)
msg, err := io.ReadAll(rec.Body)
require.NoError(t, err)
require.Contains(t, string(msg), "operation aborted as server is shutting down")
}

func TestGetStatusAfterBlockDuringCatchup(t *testing.T) {
partitiontest.PartitionTest(t)
t.Parallel()

catchup := cannedStatusReportGolden
catchup.StoppedAtUnsupportedRound = false
catchup.Catchpoint = "catchpoint"
handler, c, rec, _, _, releasefunc := setupTestForMethodGet(t, catchup)
defer releasefunc()

err := handler.WaitForBlock(c, 0)
require.NoError(t, err)

require.Equal(t, 503, rec.Code)
msg, err := io.ReadAll(rec.Body)
require.NoError(t, err)
require.Contains(t, string(msg), "operation not available during catchup")
}

func TestGetStatusAfterBlockTimeout(t *testing.T) {
partitiontest.PartitionTest(t)
t.Parallel()

supported := cannedStatusReportGolden
supported.StoppedAtUnsupportedRound = false
handler, c, rec, _, _, releasefunc := setupTestForMethodGet(t, supported)
defer releasefunc()

before := v2.WaitForBlockTimeout
defer func() { v2.WaitForBlockTimeout = before }()
v2.WaitForBlockTimeout = 1 * time.Millisecond
err := handler.WaitForBlock(c, 1000)
require.NoError(t, err)

require.Equal(t, 200, rec.Code)
dec := json.NewDecoder(rec.Body)
var resp model.NodeStatusResponse
err = dec.Decode(&resp)
require.NoError(t, err)
require.Equal(t, uint64(1), resp.LastRound)
}

func TestGetTransactionParams(t *testing.T) {
Expand Down
27 changes: 18 additions & 9 deletions data/ledger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -366,9 +366,11 @@ func TestConsensusVersion(t *testing.T) {
require.NotNil(t, &l)

blk := genesisInitState.Block
flushOffset := uint64(129) // pendingDeltasFlushThreshold = 128 will flush every 128 rounds (RewardsPool acct)
// txTailRetainSize = MaxTxnLife + DeeperBlockHeaderHistory = 1000 + 1

// add 5 blocks.
for rnd := basics.Round(1); rnd < basics.Round(consensusParams.MaxTxnLife+5); rnd++ {
// add some blocks.
for rnd := basics.Round(1); rnd < basics.Round(consensusParams.MaxTxnLife+flushOffset); rnd++ {
blk.BlockHeader.Round++
blk.BlockHeader.Seed[0] = byte(uint64(rnd))
blk.BlockHeader.Seed[1] = byte(uint64(rnd) / 256)
Expand All @@ -378,31 +380,38 @@ func TestConsensusVersion(t *testing.T) {
require.NoError(t, l.AddBlock(blk, agreement.Certificate{}))
l.WaitForCommit(rnd)
}
// ensure that all the first 5 has the expected version.
for rnd := basics.Round(consensusParams.MaxTxnLife); rnd < basics.Round(consensusParams.MaxTxnLife+5); rnd++ {
// ensure that all the first flushOffset have the expected version.
for rnd := basics.Round(consensusParams.MaxTxnLife); rnd < basics.Round(consensusParams.MaxTxnLife+flushOffset); rnd++ {
ver, err := l.ConsensusVersion(rnd)
require.NoError(t, err)
require.Equal(t, previousProtocol, ver)
}
// the next UpgradeVoteRounds can also be known to have the previous version.
for rnd := basics.Round(consensusParams.MaxTxnLife + 5); rnd < basics.Round(consensusParams.MaxTxnLife+5+consensusParams.UpgradeVoteRounds); rnd++ {
for rnd := basics.Round(consensusParams.MaxTxnLife + flushOffset); rnd < basics.Round(consensusParams.MaxTxnLife+
flushOffset+consensusParams.UpgradeVoteRounds); rnd++ {
ver, err := l.ConsensusVersion(rnd)
require.NoError(t, err)
require.Equal(t, previousProtocol, ver)
}

// but two rounds ahead is not known.
ver, err := l.ConsensusVersion(basics.Round(consensusParams.MaxTxnLife + 6 + consensusParams.UpgradeVoteRounds))
ver, err := l.ConsensusVersion(basics.Round(consensusParams.MaxTxnLife + flushOffset + 1 + consensusParams.UpgradeVoteRounds))
require.Equal(t, protocol.ConsensusVersion(""), ver)
require.Equal(t, ledgercore.ErrNoEntry{Round: basics.Round(consensusParams.MaxTxnLife + 6 + consensusParams.UpgradeVoteRounds), Latest: basics.Round(consensusParams.MaxTxnLife + 4), Committed: basics.Round(consensusParams.MaxTxnLife + 4)}, err)
require.Equal(t, ledgercore.ErrNoEntry{
Round: basics.Round(consensusParams.MaxTxnLife + flushOffset + 1 + consensusParams.UpgradeVoteRounds),
Latest: basics.Round(consensusParams.MaxTxnLife + flushOffset - 1),
Committed: basics.Round(consensusParams.MaxTxnLife + flushOffset - 1)}, err)

// check round #1 which was already dropped.
ver, err = l.ConsensusVersion(basics.Round(1))
require.Equal(t, protocol.ConsensusVersion(""), ver)
require.Equal(t, ledgercore.ErrNoEntry{Round: basics.Round(1), Latest: basics.Round(consensusParams.MaxTxnLife + 4), Committed: basics.Round(consensusParams.MaxTxnLife + 4)}, err)
require.Equal(t, ledgercore.ErrNoEntry{
Round: basics.Round(1),
Latest: basics.Round(consensusParams.MaxTxnLife + flushOffset - 1),
Committed: basics.Round(consensusParams.MaxTxnLife + flushOffset - 1)}, err)

// add another round, with upgrade
rnd := basics.Round(consensusParams.MaxTxnLife + 5)
rnd := basics.Round(consensusParams.MaxTxnLife + flushOffset)
blk.BlockHeader.Round++
blk.BlockHeader.Seed[0] = byte(uint64(rnd))
blk.BlockHeader.Seed[1] = byte(uint64(rnd) / 256)
Expand Down
11 changes: 5 additions & 6 deletions data/transactions/logic/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,16 +205,16 @@ func computeMinAvmVersion(group []transactions.SignedTxnWithAD) uint64 {
// only exposes things that consensus has already agreed upon, so it is
// "stateless" for signature purposes.
type LedgerForSignature interface {
BlockHdrCached(basics.Round) (bookkeeping.BlockHeader, error)
BlockHdr(basics.Round) (bookkeeping.BlockHeader, error)
}

// NoHeaderLedger is intended for debugging situations in which it is reasonable
// to preclude the use of `block` and `txn LastValidTime`
type NoHeaderLedger struct {
}

// BlockHdrCached always errors
func (NoHeaderLedger) BlockHdrCached(basics.Round) (bookkeeping.BlockHeader, error) {
// BlockHdr always errors
func (NoHeaderLedger) BlockHdr(basics.Round) (bookkeeping.BlockHeader, error) {
return bookkeeping.BlockHeader{}, fmt.Errorf("no block header access")
}

Expand All @@ -224,7 +224,6 @@ type LedgerForLogic interface {
Authorizer(addr basics.Address) (basics.Address, error)
Round() basics.Round
PrevTimestamp() int64
BlockHdrCached(basics.Round) (bookkeeping.BlockHeader, error)

AssetHolding(addr basics.Address, assetIdx basics.AssetIndex) (basics.AssetHolding, error)
AssetParams(aidx basics.AssetIndex) (basics.AssetParams, basics.Address, error)
Expand Down Expand Up @@ -2949,7 +2948,7 @@ func (cx *EvalContext) txnFieldToStack(stxn *transactions.SignedTxnWithAD, fs *t
if err != nil {
return sv, err
}
hdr, err := cx.SigLedger.BlockHdrCached(rnd)
hdr, err := cx.SigLedger.BlockHdr(rnd)
if err != nil {
return sv, err
}
Expand Down Expand Up @@ -5827,7 +5826,7 @@ func opBlock(cx *EvalContext) error {
return fmt.Errorf("invalid block field %s", f)
}

hdr, err := cx.SigLedger.BlockHdrCached(round)
hdr, err := cx.SigLedger.BlockHdr(round)
if err != nil {
return err
}
Expand Down
14 changes: 12 additions & 2 deletions data/transactions/logic/eval_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,9 @@ func defaultAppParamsWithVersion(version uint64, txns ...transactions.SignedTxn)
ep := NewAppEvalParams(transactions.WrapSignedTxnsWithAD(txns), makeTestProtoV(version), &transactions.SpecialAddresses{})
if ep != nil { // If supplied no apps, ep is nil.
ep.Trace = &strings.Builder{}
ep.Ledger = NewLedger(nil)
ep.SigLedger = ep.Ledger
ledger := NewLedger(nil)
ep.Ledger = ledger
ep.SigLedger = ledger
}
return ep
}
Expand Down Expand Up @@ -6011,3 +6012,12 @@ pop
int 1
`, 8)
}

func TestNoHeaderLedger(t *testing.T) {
partitiontest.PartitionTest(t)

nhl := NoHeaderLedger{}
_, err := nhl.BlockHdr(1)
require.Error(t, err)
require.Equal(t, err, fmt.Errorf("no block header access"))
}
Loading

0 comments on commit 60c402b

Please sign in to comment.