Skip to content
Merged
Show file tree
Hide file tree
Changes from 44 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
52254a4
new opcode
shiqizng Jul 7, 2021
1f5f64e
Merge remote-tracking branch 'upstream/master' into opcode/log
shiqizng Jul 8, 2021
dc2ee1b
adding log
shiqizng Jul 12, 2021
a8fab5b
Merge branch 'master' of https://github.com/algorand/go-algorand into…
shiqizng Jul 12, 2021
3196118
added unit tests
shiqizng Jul 12, 2021
7f261cc
more tests
shiqizng Jul 13, 2021
1e427c1
update evalDelta test in app
shiqizng Jul 13, 2021
47a9b74
fmt updates
shiqizng Jul 13, 2021
0806abb
addressing pr feedback
shiqizng Jul 13, 2021
366d0a8
update var names
shiqizng Jul 13, 2021
68ca45c
update log call limit to 32
shiqizng Jul 13, 2021
5a595a5
doc error fix
shiqizng Jul 13, 2021
f9e61e2
fix msgp error
shiqizng Jul 13, 2021
341858b
run make in logic
shiqizng Jul 13, 2021
fc7ce6d
move MaxLogCalls to config
shiqizng Jul 14, 2021
fadac7d
changes as per review feedback
shiqizng Jul 14, 2021
ef0b8b5
fix test error
shiqizng Jul 14, 2021
8a17098
resolve merge conflicts
shiqizng Jul 14, 2021
40aa921
addressing pr comments
shiqizng Jul 16, 2021
d9ac639
api updates
shiqizng Jul 19, 2021
7df07f6
test and gomod updates
shiqizng Jul 19, 2021
0ef27a6
resolve conflicts
shiqizng Jul 19, 2021
467b0c7
addressing change requests
shiqizng Jul 19, 2021
18a4351
debugging
shiqizng Jul 20, 2021
fb9ec97
update logs to [appid,msg]
shiqizng Jul 20, 2021
034386a
update logs data structure
shiqizng Jul 22, 2021
3eb6259
resolve merge conflict
shiqizng Jul 23, 2021
15bbe45
fix type errors
shiqizng Jul 23, 2021
e40a33a
increate wait for txn timeout
shiqizng Jul 23, 2021
2dcb4a5
changes as per review
shiqizng Jul 25, 2021
f618c22
Merge remote-tracking branch 'upstream/master' into opcode/log
shiqizng Jul 25, 2021
198b1dd
remove unused code
shiqizng Jul 25, 2021
ad49cab
merge master
shiqizng Aug 3, 2021
1085f4f
address pr reviews
shiqizng Aug 3, 2021
79b870b
update log allocbound and hanlder error message
shiqizng Aug 3, 2021
b18e435
addressed pr reviews
shiqizng Aug 5, 2021
1e8ef62
changes as per review
shiqizng Aug 9, 2021
7c286bc
resolve merge conflicts
shiqizng Aug 9, 2021
c88dfae
update maxlogcalls val
shiqizng Aug 9, 2021
4fb6e4e
fix failing tests
shiqizng Aug 9, 2021
eb3ace4
remove getLogs()
shiqizng Aug 9, 2021
023c440
remove getLogs
shiqizng Aug 9, 2021
bb65c70
fix failing tests
shiqizng Aug 9, 2021
c9504e1
changes as per review
shiqizng Aug 9, 2021
a86db27
fix failing tests and resolve reviewdog warnings
shiqizng Aug 10, 2021
f375213
fix failing tests
shiqizng Aug 10, 2021
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
4 changes: 4 additions & 0 deletions config/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,10 @@ var MaxEvalDeltaAccounts int
// in a StateDelta, used for decoding purposes.
var MaxStateDeltaKeys int

// MaxLogCalls is the highest allowable log messages that may appear in
// any version, used for decoding purposes. Never decrease this value.
const MaxLogCalls = 32
Comment on lines +425 to +427

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
// MaxLogCalls is the highest allowable log messages that may appear in
// any version, used for decoding purposes. Never decrease this value.
const MaxLogCalls = 32
// MaxLogCalls is the highest allowable log messages that may appear in
// any version, used for decoding purposes. Never decrease this value.
const MaxEncodedLogCalls = 32


// MaxLogicSigMaxSize is the largest logical signature appear in any of the supported
// protocols, used for decoding purposes.
var MaxLogicSigMaxSize int
Expand Down
31 changes: 31 additions & 0 deletions daemon/algod/api/algod.oas2.json
Original file line number Diff line number Diff line change
Expand Up @@ -1744,6 +1744,12 @@
"items": {
"$ref": "#/definitions/AccountStateDelta"
}
},
"logs": {
"type": "array",
"items": {
"$ref": "#/definitions/LogItem"
}
}
}
},
Expand Down Expand Up @@ -1910,6 +1916,24 @@
"format": "int64"
}
}
},
"LogItem": {
"description": "Application Log",
"type": "object",
"required": [
"id",
"value"
],
"properties": {
"id": {
"description": "unique application identifier",
"type": "integer"
},
"value": {
"description": " base64 encoded log message",
"type": "string"
}
}
}
},
"parameters": {
Expand Down Expand Up @@ -2307,6 +2331,13 @@
"description": "\\[gd\\] Global state key/value changes for the application being executed by this transaction.",
"$ref": "#/definitions/StateDelta"
},
"logs": {
"description": "\\[lg\\] Logs for the application being executed by this transaction.",
"type": "array",
"items": {
"$ref": "#/definitions/LogItem"
}
},
"txn": {
"description": "The raw signed transaction.",
"type": "object",
Expand Down
45 changes: 45 additions & 0 deletions daemon/algod/api/algod.oas3.yml
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,13 @@
},
"type": "array"
},
"logs": {
"description": "\\[lg\\] Logs for the application being executed by this transaction.",
"items": {
"$ref": "#/components/schemas/LogItem"
},
"type": "array"
},
"pool-error": {
"description": "Indicates that the transaction was kicked out of this node's transaction pool (and specifies why that happened). An empty string indicates the transaction wasn't kicked out of this node's txpool due to an error.\n",
"type": "string"
Expand Down Expand Up @@ -1267,6 +1274,12 @@
"$ref": "#/components/schemas/DryrunState"
},
"type": "array"
},
"logs": {
"items": {
"$ref": "#/components/schemas/LogItem"
},
"type": "array"
}
},
"required": [
Expand Down Expand Up @@ -1327,6 +1340,24 @@
],
"type": "object"
},
"LogItem": {
"description": "Application Log",
"properties": {
"id": {
"description": "unique application identifier",
"type": "integer"
},
"value": {
"description": " base64 encoded log message",
"type": "string"
}
},
"required": [
"id",
"value"
],
"type": "object"
},
"StateDelta": {
"description": "Application state delta.",
"items": {
Expand Down Expand Up @@ -3340,6 +3371,13 @@
},
"type": "array"
},
"logs": {
"description": "\\[lg\\] Logs for the application being executed by this transaction.",
"items": {
"$ref": "#/components/schemas/LogItem"
},
"type": "array"
},
"pool-error": {
"description": "Indicates that the transaction was kicked out of this node's transaction pool (and specifies why that happened). An empty string indicates the transaction wasn't kicked out of this node's txpool due to an error.\n",
"type": "string"
Expand Down Expand Up @@ -3404,6 +3442,13 @@
},
"type": "array"
},
"logs": {
"description": "\\[lg\\] Logs for the application being executed by this transaction.",
"items": {
"$ref": "#/components/schemas/LogItem"
},
"type": "array"
},
"pool-error": {
"description": "Indicates that the transaction was kicked out of this node's transaction pool (and specifies why that happened). An empty string indicates the transaction wasn't kicked out of this node's txpool due to an error.\n",
"type": "string"
Expand Down
4 changes: 2 additions & 2 deletions daemon/algod/api/client/restClient.go
Original file line number Diff line number Diff line change
Expand Up @@ -434,8 +434,8 @@ func (client RestClient) PendingTransactionInformation(transactionID string) (re
return
}

// PendingTransactionInformationV2 gets information about a recently issued
// transaction. See PendingTransactionInformation for more details.
// PendingTransactionInformationV2 gets information about a recently issued transaction.
// See PendingTransactionInformation for more details.
func (client RestClient) PendingTransactionInformationV2(transactionID string) (response generatedV2.PendingTransactionResponse, err error) {
transactionID = stripTransaction(transactionID)
err = client.get(&response, fmt.Sprintf("/v2/transactions/pending/%s", transactionID), nil)
Expand Down
23 changes: 23 additions & 0 deletions daemon/algod/api/server/v2/dryrun.go
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,13 @@ func doDryrunRequest(dr *DryrunRequest, response *generated.DryrunResponse) {
}
result.LocalDeltas = &localDeltas
}

var err3 error
result.Logs, err3 = DeltaLogToLog(delta.Logs, appIdx)
if err3 != nil {
messages = append(messages, err3.Error())
}

if pass {
messages = append(messages, "PASS")
} else {
Expand Down Expand Up @@ -563,6 +570,22 @@ func StateDeltaToStateDelta(sd basics.StateDelta) *generated.StateDelta {
return &gsd
}

// DeltaLogToLog EvalDelta.Logs to generated.LogItem
func DeltaLogToLog(logs []basics.LogItem, appIdx basics.AppIndex) (*[]generated.LogItem, error) {
if len(logs) == 0 {
return nil, nil
}
encodedLogs := make([]generated.LogItem, 0, len(logs))
for _, log := range logs {
if log.ID != 0 {
return nil, fmt.Errorf("logging for a foreign app is not supported")
}
msg := base64.StdEncoding.EncodeToString([]byte(log.Message))
encodedLogs = append(encodedLogs, generated.LogItem{Id: uint64(appIdx), Value: msg})
}
return &encodedLogs, nil
}

// MergeAppParams merges values, existing in "base" take priority over new in "update"
func MergeAppParams(base *basics.AppParams, update *basics.AppParams) {
if len(base.ApprovalProgram) == 0 && len(update.ApprovalProgram) > 0 {
Expand Down
112 changes: 111 additions & 1 deletion daemon/algod/api/server/v2/dryrun_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ func init() {

// legder requires proto string and proto params set
var proto config.ConsensusParams
proto.LogicSigVersion = 4
proto.LogicSigVersion = 5
proto.LogicSigMaxCost = 20000
proto.MaxAppProgramCost = 700
proto.MaxAppKeyLen = 64
Expand Down Expand Up @@ -1091,3 +1091,113 @@ int 1`)
logResponse(t, &response)
}
}

func TestDryrunLogs(t *testing.T) {
Comment thread
jasonpaulos marked this conversation as resolved.
t.Parallel()

ops, err := logic.AssembleString(`
#pragma version 5
byte "A"
loop:
int 0
dup2
getbyte
int 1
+
dup
int 97 //ascii code of last char
<=
bz end
setbyte
dup
log
b loop
end:
int 1
return
`)

require.NoError(t, err)
approval := ops.Program
ops, err = logic.AssembleString("int 1")
clst := ops.Program
ops, err = logic.AssembleString("#pragma version 5 \nint 1")
Comment thread
algorandskiy marked this conversation as resolved.
approv := ops.Program
require.NoError(t, err)

var appIdx basics.AppIndex = 1
creator := randomAddress()
sender := randomAddress()
dr := DryrunRequest{
Txns: []transactions.SignedTxn{
{
Txn: transactions.Transaction{
Header: transactions.Header{Sender: sender},
Type: protocol.ApplicationCallTx,
ApplicationCallTxnFields: transactions.ApplicationCallTxnFields{
ApplicationID: appIdx,
OnCompletion: transactions.OptInOC,
},
},
},
{
Txn: transactions.Transaction{
Header: transactions.Header{Sender: sender},
Type: protocol.ApplicationCallTx,
ApplicationCallTxnFields: transactions.ApplicationCallTxnFields{
ApplicationID: appIdx + 1,
OnCompletion: transactions.OptInOC,
},
},
},
},
Apps: []generated.Application{
{
Id: uint64(appIdx),
Params: generated.ApplicationParams{
Creator: creator.String(),
ApprovalProgram: approval,
ClearStateProgram: clst,
LocalStateSchema: &generated.ApplicationStateSchema{NumByteSlice: 1},
},
},
{
Id: uint64(appIdx + 1),
Params: generated.ApplicationParams{
Creator: creator.String(),
ApprovalProgram: approv,
ClearStateProgram: clst,
LocalStateSchema: &generated.ApplicationStateSchema{NumByteSlice: 1},
},
},
},
Accounts: []generated.Account{
{
Address: sender.String(),
Status: "Online",
Amount: 10000000,
},
},
}
dr.ProtocolVersion = string(dryrunProtoVersion)

var response generated.DryrunResponse
doDryrunRequest(&dr, &response)
require.NoError(t, err)
checkAppCallPass(t, &response)
if t.Failed() {
logResponse(t, &response)
}
logs := *response.Txns[0].Logs
assert.Equal(t, 32, len(logs))
for i, m := range logs {
assert.Equal(t, base64.StdEncoding.EncodeToString([]byte(string(rune('B'+i)))), m.Value)
}
Comment on lines +1182 to +1195

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Calculating values looks more maintainable, check below:

Suggested change
for i, m := range logs {
if i == 0 {
assert.Equal(t, base64.StdEncoding.EncodeToString([]byte("a")), m.Value)
} else if i == 1 {
assert.Equal(t, base64.StdEncoding.EncodeToString([]byte("b")), m.Value)
} else if i == 2 {
assert.Equal(t, base64.StdEncoding.EncodeToString([]byte("c")), m.Value)
}
}
for i, m := range logs {
assert.Equal(t, base64.StdEncoding.EncodeToString([]byte(string(rune('a' + i)))), m.Value)
}

If logs are not sorted, use sort.Slice. If logs is map (not sure) then flatten it:

	type flog struct {
		idx int,
		li LogItem
	}
	for k, v := range logs {
		flatlog = append(flatlog, flog{i, v})
	}
	sort.Slice(flatlog, func(i, j int) {return flatlog[i].idx < flatlog[j].idx})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The order of logs matter, so they should not be sorted before comparison

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

well ok, then assert.Equal(t, base64.StdEncoding.EncodeToString([]byte(string(rune('a' + i)))), m.Value) will work just fine

encoded := string(protocol.EncodeJSON(response.Txns[0]))
assert.Contains(t, encoded, "logs")

assert.Empty(t, response.Txns[1].Logs)
encoded = string(protocol.EncodeJSON(response.Txns[1]))
assert.NotContains(t, encoded, "logs")

}
Loading