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

feat: Oracle packages and Github verification realm #1568

Merged
merged 53 commits into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
0a688e6
agent wip
deelawn Dec 17, 2023
9523aa4
reworked task agent
deelawn Jan 9, 2024
2f5d997
reorg and more features
deelawn Jan 9, 2024
b6f99b0
added github contract that uses the oracle
deelawn Jan 9, 2024
43c1130
moved files to examples for creation at genesis
deelawn Jan 10, 2024
a95f0ec
docs
deelawn Jan 10, 2024
c9f6b51
oracle package bug fixes
deelawn Jan 11, 2024
6f0c7ce
prototype new version of the oracle package
deelawn Jan 17, 2024
393d418
more work on v2 orkle prototype
deelawn Jan 18, 2024
ed864e3
implemented gh verify oracle using new model
deelawn Jan 19, 2024
c5dcc10
exclude inactive feeds from agent requests
deelawn Jan 19, 2024
03958de
tried to implement whitelisting effectively
deelawn Jan 23, 2024
fc3d750
moved the gh verification task to the realm
deelawn Jan 23, 2024
d00ffaa
delete code and move new version to the gno p and r folders
deelawn Jan 23, 2024
cd63af0
tidy go mod
deelawn Jan 23, 2024
c91084d
rename orkle -> gnorkle
deelawn Jan 23, 2024
cab8a03
bug fixes and realm ownership
deelawn Jan 23, 2024
1ac9af8
try to fix weird vcs sync issue
deelawn Jan 23, 2024
f73a94b
gno mod tidy
deelawn Jan 23, 2024
10e52de
added godocs, comments, and minor changes
deelawn Jan 24, 2024
88b231e
added ghverify realm test
deelawn Jan 24, 2024
797c7a1
gno mod tidy
deelawn Jan 24, 2024
5ea02ff
added ghverify accessors
deelawn Jan 24, 2024
3a43959
fix type error
deelawn Jan 24, 2024
02920e5
docstrings and cleanup
deelawn Jan 24, 2024
d3d9376
prevent overwriting existing verification requests
deelawn Jan 24, 2024
2c11cb3
added readmes
deelawn Jan 25, 2024
f2c0d0d
removed v1 suffix
deelawn Feb 22, 2024
31f955a
txtar test and contract bug fix
deelawn Feb 22, 2024
433228e
Merge branch 'master' into feat/agents
deelawn Feb 23, 2024
719bde4
txtar loadpkg
deelawn Feb 23, 2024
667fc06
Update examples/gno.land/r/gnoland/ghverify/readme.md
deelawn Mar 4, 2024
bead186
MarshalToJSON -> MarshalJSON
deelawn Mar 4, 2024
2e19ebd
Merge branch 'feat/agents' of github.com:deelawn/gno into feat/agents
deelawn Mar 4, 2024
89d8e33
capitalized readme
deelawn Mar 4, 2024
a4b301e
filename typo
deelawn Mar 4, 2024
5d45122
added an example for each proposed feed type
deelawn Mar 6, 2024
139984f
added more examples
deelawn Mar 6, 2024
d10aa8b
set first to false after first iternation
deelawn Mar 6, 2024
0ddd13d
make feed task arguments variadic
deelawn Mar 7, 2024
0934899
return errors from package code and panic in the realm
deelawn Mar 7, 2024
3a500aa
fixed contract tests
deelawn Mar 7, 2024
6b9c9de
use proper return types
deelawn Mar 7, 2024
fed4a3f
remove unused import
deelawn Apr 28, 2024
5f62b9e
Merge branch 'master' into feat/agents
deelawn Apr 30, 2024
850393c
add error return types to methods of gnorkle interfaces and consolida…
deelawn May 3, 2024
3960abc
added some tests
deelawn May 3, 2024
6fa61f7
added feed tests
deelawn May 7, 2024
dfba393
Merge branch 'master' into feat/agents
deelawn May 7, 2024
d97f4ab
examples gno mod tidy
deelawn May 7, 2024
6696f7a
Merge branch 'feat/agents' of github.com:deelawn/gno into feat/agents
deelawn May 7, 2024
dc851ce
updated type
deelawn May 7, 2024
189bcfa
fix address type issues
deelawn May 7, 2024
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
463 changes: 463 additions & 0 deletions agent/devmock/avl/node.go

Large diffs are not rendered by default.

82 changes: 82 additions & 0 deletions agent/devmock/avl/tree.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package avl
deelawn marked this conversation as resolved.
Show resolved Hide resolved

type IterCbFn func(key string, value interface{}) bool

//----------------------------------------
// Tree

// The zero struct can be used as an empty tree.
type Tree struct {
node *Node
}

func NewTree() *Tree {
return &Tree{
node: nil,
}
}

func (tree *Tree) Size() int {
return tree.node.Size()
}

func (tree *Tree) Has(key string) (has bool) {
return tree.node.Has(key)
}

func (tree *Tree) Get(key string) (value interface{}, exists bool) {
_, value, exists = tree.node.Get(key)
return
}

func (tree *Tree) GetByIndex(index int) (key string, value interface{}) {
return tree.node.GetByIndex(index)
}

func (tree *Tree) Set(key string, value interface{}) (updated bool) {
newnode, updated := tree.node.Set(key, value)
tree.node = newnode
return updated
}

func (tree *Tree) Remove(key string) (value interface{}, removed bool) {
newnode, _, value, removed := tree.node.Remove(key)
tree.node = newnode
return value, removed
}

// Shortcut for TraverseInRange.
func (tree *Tree) Iterate(start, end string, cb IterCbFn) bool {
return tree.node.TraverseInRange(start, end, true, true,
func(node *Node) bool {
return cb(node.Key(), node.Value())
},
)
}

// Shortcut for TraverseInRange.
func (tree *Tree) ReverseIterate(start, end string, cb IterCbFn) bool {
return tree.node.TraverseInRange(start, end, false, true,
func(node *Node) bool {
return cb(node.Key(), node.Value())
},
)
}

// Shortcut for TraverseByOffset.
func (tree *Tree) IterateByOffset(offset int, count int, cb IterCbFn) bool {
return tree.node.TraverseByOffset(offset, count, true, true,
func(node *Node) bool {
return cb(node.Key(), node.Value())
},
)
}

// Shortcut for TraverseByOffset.
func (tree *Tree) ReverseIterateByOffset(offset int, count int, cb IterCbFn) bool {
return tree.node.TraverseByOffset(offset, count, false, true,
func(node *Node) bool {
return cb(node.Key(), node.Value())
},
)
}
1 change: 1 addition & 0 deletions agent/devmock/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package devmock
7 changes: 7 additions & 0 deletions agent/devmock/std/std.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package std

type Address string

func GetOrigCaller() Address {
return ""
}
133 changes: 133 additions & 0 deletions agent/p/agent/agent.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package agent

import (
// TODO: replace with std

"strings"

"gno.land/p/demo/avl"
"gno.land/p/demo/std"
)

var (
tasks *avl.Tree

// Not sure this is necessary.
adminAddress string
)

const (
FunctionFinish = "finish"
FunctionRequest = "request"
FunctionSubmit = "submit"
)

type PostRequestAction func(function string, task Task)

func HandleRequest(payload string, post PostRequestAction) string {
payloadParts := strings.SplitN(payload, ",", 1)
if len(payloadParts) != 2 {
panic("invalid agent payload")
}

switch function := payloadParts[0]; function {
case FunctionFinish:
task := FinishTask(payloadParts[1])
if post != nil {
post(function, task)
}
case FunctionRequest:
return RequestTasks()
case FunctionSubmit:
submitArgs := strings.SplitN(payloadParts[1], ",", 1)
if len(submitArgs) != 2 {
panic("invalid agent submission payload")
}

SubmitTaskValue(submitArgs[0], submitArgs[1])
if post != nil {
post(function, nil)
}
default:
panic("unknown function " + function)
}

return ""
}

func FinishTask(id string) Task {
task, ok := tasks.Get(id)
if !ok {
panic("task not found")
}

task.(Task).Finish(string(std.GetOrigCaller()))
return task.(Task)
}

func RequestTasks() string {
buf := new(strings.Builder)
buf.WriteString("[")
first := true
tasks.Iterate("", "", func(_ string, value interface{}) bool {
if !first {
buf.WriteString(",")
}

task := value.(Task)
taskBytes, err := task.MarshalJSON()
if err != nil {
panic(err)
}

// Guard against any tasks that shouldn't be returned; maybe they are not active because they have
// already been completed.
if len(taskBytes) == 0 {
return true
}

first = false
buf.Write(taskBytes)
return true
})
buf.WriteString("]")
return buf.String()
}

func SubmitTaskValue(id, value string) Task {
task, ok := tasks.Get(id)
if !ok {
panic("task not found")
}

task.(Task).SubmitResult(string(std.GetOrigCaller()), value)
return task.(Task)
}

func AddTask(task Task) {
if tasks.Has(task.ID()) {
panic("task id " + task.ID() + " already exists")
}

tasks.Set(task.ID(), task)
}

func RemoveTask(id string) {
if _, removed := tasks.Remove(id); !removed {
panic("task id " + id + " not found")
}
}

func Init(admin std.Address, newTasks ...Task) {
if tasks != nil {
panic("already initialized")
}

adminAddress = string(admin)
tasks = avl.NewTree()
for _, task := range newTasks {
if updated := tasks.Set(task.ID(), task); updated {
panic("task id " + task.ID() + " already exists")
}
}
}
30 changes: 30 additions & 0 deletions agent/p/agent/github/verification/task/definition.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package task

import (
"bufio"
"bytes"
)

const Type string = "gh-verification"

type Definition struct {
Handle string
Address string
}

func (d Definition) MarshalJSON() ([]byte, error) {
buf := new(bytes.Buffer)
w := bufio.NewWriter(buf)

w.WriteString(
`{"handle":"` + d.Handle +
`","address":"` + d.Address + `"}`,
)

w.Flush()
return buf.Bytes(), nil
}

deelawn marked this conversation as resolved.
Show resolved Hide resolved
func (d Definition) Type() string {
return Type
}
6 changes: 6 additions & 0 deletions agent/p/agent/pricefeed/task/definition.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package task

type Definition struct {
Pair string // USD/CAD
AcceptedDeviation float64
}
31 changes: 31 additions & 0 deletions agent/p/agent/random/task/aggregator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package task

import (
"math"
"strconv"
)

type Aggregator struct {
sum uint64
taskDefinition *Definition
}

func (a *Aggregator) Aggregate() string {
randomValue := a.taskDefinition.RangeStart + a.sum%a.taskDefinition.RangeEnd
a.sum = 0
return strconv.FormatUint(randomValue, 10)
}

func (a *Aggregator) AddValue(value string) {
intValue, err := strconv.ParseUint(value, 10, 64)
if err != nil {
panic("value needs to be type uint64: " + err.Error())
}

// Account for overflow.
if diff := math.MaxUint64 - a.sum; diff < intValue {
a.sum = intValue - diff
} else {
a.sum += intValue
}
}
32 changes: 32 additions & 0 deletions agent/p/agent/random/task/definition.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package task

import (
"bufio"
"bytes"
"strconv"
)

const Type string = "random"

// Input in this range.
type Definition struct {
RangeStart uint64
RangeEnd uint64
}

func (d Definition) MarshalJSON() ([]byte, error) {
buf := new(bytes.Buffer)
w := bufio.NewWriter(buf)

w.WriteString(
`{"start":` + strconv.FormatUint(d.RangeStart, 10) +
`,"end":` + strconv.FormatUint(d.RangeEnd, 10) + `}`,
)

w.Flush()
return buf.Bytes(), nil
}

func (d Definition) Type() string {
return Type
}
12 changes: 12 additions & 0 deletions agent/p/agent/task.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package agent

import "github.com/gnolang/gno/agent/p/agent/task"

type Task interface {
Definition() task.Definition
Finish(origCaller string)
GetResult() (result task.Result, hasResult bool)
ID() string
MarshalJSON() ([]byte, error)
SubmitResult(origCaller, value string)
}
8 changes: 8 additions & 0 deletions agent/p/agent/task/aggregator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package task

type Aggregator interface {
// Aggregate runs an aggregation on all values written using the AddValue method.
// It returns the aggregated value as a string.
Aggregate() string
AddValue(value string)
}
6 changes: 6 additions & 0 deletions agent/p/agent/task/definition.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package task

type Definition interface {
MarshalJSON() ([]byte, error)
Type() string
}
16 changes: 16 additions & 0 deletions agent/p/agent/task/history.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package task

type History struct {
Size int
NumRemoved int
Results []Result
}

func (h *History) AddResult(result Result) {
h.Results = append(h.Results, result)
if numResults := len(h.Results); numResults > h.Size {
numToRemove := numResults - h.Size
h.Results = h.Results[numToRemove:]
h.NumRemoved += numToRemove
}
}
8 changes: 8 additions & 0 deletions agent/p/agent/task/result.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package task

import "time"

type Result struct {
Value string
Time time.Time
}
Loading
Loading