-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinterface.go
More file actions
189 lines (153 loc) · 5.42 KB
/
interface.go
File metadata and controls
189 lines (153 loc) · 5.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
// Copyright 2024, Nunet
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and limitations under the License.
package actor
import (
"context"
"time"
"github.com/depinkit/crypto"
"github.com/depinkit/did"
"github.com/depinkit/ucan"
)
type (
ID = crypto.ID
DID = did.DID
Capability = ucan.Capability
)
// ActorHandle is a handle for naming an actor reachable in the network
type Handle struct {
ID ID `json:"id"`
DID DID `json:"did"`
Address Address `json:"addr"`
}
// ActorAddress is a raw actor address representation
type Address struct {
HostID string `json:"host,omitempty"`
InboxAddress string `json:"inbox,omitempty"`
}
// Envelope is the envelope for messages in the actor system
type Envelope struct {
To Handle `json:"to"`
Behavior string `json:"be"`
From Handle `json:"from"`
Nonce uint64 `json:"nonce"`
Options EnvelopeOptions `json:"opt"`
Message []byte `json:"msg"`
Capability []byte `json:"cap,omitempty"`
Signature []byte `json:"sig,omitempty"`
Discard func() `json:"-"`
}
// EnvelopeOptions are sender specified options for processing an envelope
type EnvelopeOptions struct {
Expire uint64 `json:"exp"`
ReplyTo string `json:"cont,omitempty"`
Topic string `json:"topic,omitempty"`
}
// Actor is the local interface to the actor system
type Actor interface {
Context() context.Context
Handle() Handle
Security() SecurityContext
Supervisor() Handle
AddBehavior(behavior string, continuation Behavior, opt ...BehaviorOption) error
RemoveBehavior(behavior string)
Receive(msg Envelope) error
Send(msg Envelope) error
Invoke(msg Envelope) (<-chan Envelope, error)
Publish(msg Envelope) error
Subscribe(topic string, setup ...BroadcastSetup) error
Start() error
Stop() error
// TODO: add child termination strategies
// e.g.: childSelfRelease which relies on a func `f` to self release and terminate
// the child actor
CreateChild(id string, super Handle, opts ...CreateChildOption) (Actor, error)
Parent() Handle
Children() map[did.DID]Handle
Limiter() RateLimiter
}
// ActorSecurityContext provides a context for which to perform cryptographic operations
// for an actor.
// This includes:
// - signing messages
// - verifying message signatures
// - requiring capabilities
// - granting capabilities
type SecurityContext interface {
ID() ID
DID() DID
Nonce() uint64
PrivKey() crypto.PrivKey
// Require checks the capability token(s).
// It succeeds if and only if
// - the signature is valid
// - the capability token(s) in the envelope grants the origin actor ID/DID
// any of the specified capabilities.
Require(msg Envelope, invoke []Capability) error
// Provide populates the envelope with necessary capability tokens and signs it.
// the envelope is modified in place
Provide(msg *Envelope, invoke []Capability, delegate []Capability) error
// Require verifies the envelope and checks the capability tokens
// for a broadcast topic
RequireBroadcast(msg Envelope, topic string, broadcast []Capability) error
// ProvideBroadcast populates the envelope with the necessary capability tokens
// for broadcast in the topic and signs it
ProvideBroadcast(msg *Envelope, topic string, broadcast []Capability) error
// Verify verifies the message signature in an envelope
Verify(msg Envelope) error
// Sign signs an envelope; the envelope is modified in place.
Sign(msg *Envelope) error
// Grant grants the specified capabilities to the specified audience.
//
// Useful for granting capabilities between actors without sending
// tokens to each other.
Grant(sub, aud did.DID, caps []ucan.Capability, expiry time.Duration) error
// Discard discards unwanted tokens from a consumed envelope
Discard(msg Envelope)
// Return the capability context
Capability() ucan.CapabilityContext
}
// RateLimiter implements a stateful resource access limiter
// This is necessary to combat spam attacks and ensure that our system does not
// become overloaded with too many goroutines.
type RateLimiter interface {
Allow(msg Envelope) bool
Acquire(msg Envelope) error
Release(msg Envelope)
Config() RateLimiterConfig
SetConfig(cfg RateLimiterConfig)
}
type RateLimiterConfig struct {
PublicLimitAllow int
PublicLimitAcquire int
BroadcastLimitAllow int
BroadcastLimitAcquire int
TopicDefaultLimit int
TopicLimit map[string]int
}
type (
Behavior func(msg Envelope)
MessageOption func(msg *Envelope) error
)
type BehaviorOption func(opt *BehaviorOptions) error
type BehaviorOptions struct {
Capability []Capability
Expire uint64
OneShot bool
Topic string
}
type BroadcastSetup func(topic string) error
type CreateChildOption func(*CreateChildOptions)
type CreateChildOptions struct {
PrivKey crypto.PrivKey
}
// WithPrivKey sets a specific private key for the child actor
func WithPrivKey(privKey crypto.PrivKey) CreateChildOption {
return func(o *CreateChildOptions) {
o.PrivKey = privKey
}
}