diff --git a/daemon/algod/api/server/v2/dryrun.go b/daemon/algod/api/server/v2/dryrun.go index 7ce7c6abbf..9c3355cd10 100644 --- a/daemon/algod/api/server/v2/dryrun.go +++ b/daemon/algod/api/server/v2/dryrun.go @@ -89,7 +89,12 @@ func (dr *DryrunRequest) ExpandSources() error { for i, s := range dr.Sources { ops, err := logic.AssembleString(s.Source) if err != nil { - return fmt.Errorf("dryrun Source[%d]: %v", i, err) + if len(ops.Errors) <= 1 { + return fmt.Errorf("dryrun Source[%d]: %w", i, err) + } + var sb strings.Builder + ops.ReportMultipleErrors("", &sb) + return fmt.Errorf("dryrun Source[%d]: %d errors\n%s", i, len(ops.Errors), sb.String()) } switch s.FieldName { case "lsig": diff --git a/daemon/algod/api/server/v2/dryrun_test.go b/daemon/algod/api/server/v2/dryrun_test.go index ad0592f5fd..93177e488b 100644 --- a/daemon/algod/api/server/v2/dryrun_test.go +++ b/daemon/algod/api/server/v2/dryrun_test.go @@ -132,6 +132,48 @@ func logResponse(t *testing.T, response *model.DryrunResponse) { var dryrunProtoVersion protocol.ConsensusVersion = protocol.ConsensusFuture var dryrunMakeLedgerProto protocol.ConsensusVersion = "dryrunMakeLedgerProto" +func TestDryrunSources(t *testing.T) { + partitiontest.PartitionTest(t) + t.Parallel() + + goodSource := model.DryrunSource{ + AppIndex: 1007, + FieldName: "approv", + Source: `#pragma version 10 +int 1`, + } + badSource := model.DryrunSource{ + AppIndex: 1007, + FieldName: "approv", + Source: `#pragma version 10 +int 1 +pop +fake_opcode +int not_an_int`, + } + + dr := DryrunRequest{ + Sources: []model.DryrunSource{ + goodSource, + }, + Apps: []model.Application{ + { + Id: 1007, + }, + }, + } + var response model.DryrunResponse + + doDryrunRequest(&dr, &response) + require.Empty(t, response.Error) + + dr.Sources[0] = badSource + doDryrunRequest(&dr, &response) + require.Contains(t, response.Error, "dryrun Source[0]: 2 errors") + require.Contains(t, response.Error, "4: unknown opcode: fake_opcode") + require.Contains(t, response.Error, "5:4: unable to parse \"not_an_int\" as integer") +} + func TestDryrunLogicSig(t *testing.T) { partitiontest.PartitionTest(t) // {"txns":[{"lsig":{"l":"AiABASI="},"txn":{}}]}