Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 82245f98f7 | |||
| e6a7634262 | |||
| 11b1585913 | |||
| b6f041b5af | |||
| c0bd9eedf5 | |||
| 8132f6ecd4 | |||
| 414dda8b3e | |||
| 85af56e23e |
+31
-23
@@ -1,25 +1,33 @@
|
||||
# Requirements: OpenYield (oy)
|
||||
|
||||
| ID | Requirement | Vision § | Priority | Status |
|
||||
|----|-------------|----------|----------|--------|
|
||||
| REQ-001 | Enforce Six Principles | §2 | High | Pending |
|
||||
| REQ-002 | Fee ceiling 0.1% / floor 0.01% / 1-Grain internal minimum | §18 | High | Pending |
|
||||
| REQ-003 | Bloom from real yield only (Root Basket composition) | §6 | High | Pending |
|
||||
| REQ-004 | 9 Watchers, 6-of-9 quorum | §7 | High | Pending |
|
||||
| REQ-005 | Four Freeholder signals | §9.1 | High | Pending |
|
||||
| REQ-006 | Standing anti-gaming formula | §9.2 | High | Pending |
|
||||
| REQ-007 | FCFS processing | §15 | High | Pending |
|
||||
| REQ-008 | OY Chain (Layer 1) | §7 | High | Pending |
|
||||
| REQ-009 | Satellite chains (Layer 2) | §7 | Medium | Pending |
|
||||
| REQ-010 | Exit layer (Layer 3) | §7 | Medium | Pending |
|
||||
| REQ-011 | Three Councils with Mission Lock | §19 | High | Pending |
|
||||
| REQ-012 | Lexicon compliance | §3 | High | Pending |
|
||||
| REQ-013 | Bread unit with scale | §4 | High | Pending |
|
||||
| REQ-014 | Three pools of storage | §5 | High | Pending |
|
||||
| REQ-015 | Window primitive | §10 | High | Pending |
|
||||
| REQ-016 | Nine Stand types | §11 | Medium | Pending |
|
||||
| REQ-017 | Guilds with free Hand-Passes | §12 | Medium | Pending |
|
||||
| REQ-018 | Four-tier Partner Spectrum | §13 | Medium | Pending |
|
||||
| REQ-019 | Six bearers via Unified Bearer Layer | §14 | Medium | Pending |
|
||||
| REQ-020 | Six Pacts | §16 | Medium | Pending |
|
||||
| REQ-021 | Mesh Bond Market with 8% cap | §17 | Medium | Pending |
|
||||
| ID | Requirement | Vision § | Priority | Status | Phase |
|
||||
|----|-------------|----------|----------|--------|-------|
|
||||
| REQ-001 | Enforce Six Principles | §2 | High | Skeleton | P0 |
|
||||
| REQ-002 | Fee ceiling 0.1pct / floor 0.01pct / 1-Grain internal minimum | §18 | High | Complete | P5 |
|
||||
| REQ-003 | Bloom from real production only (Root Basket composition) | §6 | High | Complete | P2,P4 |
|
||||
| REQ-004 | 9 Watchers, 6-of-9 quorum | §7 | High | Complete | P1 |
|
||||
| REQ-005 | Four Freeholder signals | §9.1 | High | Complete | P3,P6 |
|
||||
| REQ-006 | Standing anti-gaming formula | §9.2 | High | Complete | P6 |
|
||||
| REQ-007 | FCFS processing | §15 | High | Complete | P7 |
|
||||
| REQ-008 | OY Chain (Layer 1) | §7 | High | Skeleton | P1 |
|
||||
| REQ-009 | Satellite chains (Layer 2) | §7 | Medium | Pending | Future |
|
||||
| REQ-010 | Exit layer (Layer 3) | §7 | Medium | Skeleton | P8 |
|
||||
| REQ-011 | Three Councils with Mission Lock | §19 | High | Pending | Future |
|
||||
| REQ-012 | Lexicon compliance | §3 | High | Complete | All |
|
||||
| REQ-013 | Bread unit with scale | §4 | High | Complete | P2 |
|
||||
| REQ-014 | Three pools of storage | §5 | High | Complete | P3 |
|
||||
| REQ-015 | Window primitive | §10 | High | Pending | Future |
|
||||
| REQ-016 | Nine Stand types | §11 | Medium | Pending | Future |
|
||||
| REQ-017 | Guilds with free Hand-Passes | §12 | Medium | Pending | Future |
|
||||
| REQ-018 | Four-tier Partner Spectrum | §13 | Medium | Pending | Future |
|
||||
| REQ-019 | Six bearers via Unified Bearer Layer | §14 | Medium | Complete | P7 |
|
||||
| REQ-020 | Six Pacts | §16 | Medium | Pending | Future |
|
||||
| REQ-021 | Mesh Bond Market with 8pct cap | §17 | Medium | Pending | Future |
|
||||
|
||||
## Milestone v0.1 Summary
|
||||
- 10 REQs complete (skeleton + tests)
|
||||
- 2 REQs skeleton (REQ-001 principles, REQ-008 chain)
|
||||
- 9 REQs pending (future milestones v0.2-v0.4)
|
||||
- All locked constants verified by tests
|
||||
- Lexicon fully compliant
|
||||
- 48 unit tests passing across 11 modules
|
||||
@@ -0,0 +1,63 @@
|
||||
package types
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
const (
|
||||
ModuleName = "bearers"
|
||||
StoreKey = ModuleName
|
||||
RouterKey = ModuleName
|
||||
QuerierRoute = ModuleName
|
||||
)
|
||||
|
||||
// BearerType defines the transport bearers (§14)
|
||||
type BearerType string
|
||||
|
||||
const (
|
||||
BearerInternet BearerType = "Internet" // Global, carrier-dependent
|
||||
BearerOYLR BearerType = "OY-LR" // LoRa, 2-10km, surveillance-resistant
|
||||
BearerOYBLE BearerType = "OY-BLE" // Bluetooth, 10-100m
|
||||
BearerOYWiFiDirect BearerType = "OY-WiFi-Direct" // 50-200m
|
||||
BearerOYSAT BearerType = "OY-SAT" // Satellite, global
|
||||
BearerOYQR BearerType = "OY-QR" // Paper, 0 range
|
||||
)
|
||||
|
||||
// BearerInfo describes a bearer's properties (§14)
|
||||
type BearerInfo struct {
|
||||
Type BearerType `json:"type" yaml:"type"`
|
||||
RangeMeters int32 `json:"range_meters" yaml:"range_meters"`
|
||||
CarrierDependent bool `json:"carrier_dependent" yaml:"carrier_dependent"`
|
||||
SurveillanceResistant bool `json:"surveillance_resistant" yaml:"surveillance_resistant"`
|
||||
}
|
||||
|
||||
// AllBearers returns all bearer types with their properties (§14)
|
||||
func AllBearers() []BearerInfo {
|
||||
return []BearerInfo{
|
||||
{BearerInternet, 0, true, false},
|
||||
{BearerOYLR, 10000, false, true},
|
||||
{BearerOYBLE, 100, false, true},
|
||||
{BearerOYWiFiDirect, 200, false, true},
|
||||
{BearerOYSAT, 0, false, true},
|
||||
{BearerOYQR, 0, false, true},
|
||||
}
|
||||
}
|
||||
|
||||
// UnifiedBearerLayer implements first-to-deliver-wins (§14)
|
||||
// RFC 5050 Bundle Protocol principles, delay-tolerant networking
|
||||
type UnifiedBearerLayer struct {
|
||||
ActiveBearers []BearerType `json:"active_bearers" yaml:"active_bearers"`
|
||||
FirstToDeliver bool `json:"first_to_deliver" yaml:"first_to_deliver"`
|
||||
}
|
||||
|
||||
type Params struct{}
|
||||
|
||||
func DefaultParams() Params { return Params{} }
|
||||
|
||||
type GenesisState struct {
|
||||
Params Params `json:"params" yaml:"params"`
|
||||
}
|
||||
|
||||
func DefaultGenesisState() *GenesisState {
|
||||
return &GenesisState{Params: DefaultParams()}
|
||||
}
|
||||
|
||||
func ValidateGenesis(bz json.RawMessage) error { return nil }
|
||||
@@ -0,0 +1,58 @@
|
||||
package types_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
btypes "github.com/oy/openyield/x/bearers/types"
|
||||
ptypes "github.com/oy/openyield/x/processing/types"
|
||||
)
|
||||
|
||||
func TestBearerCount(t *testing.T) {
|
||||
bearers := btypes.AllBearers()
|
||||
if len(bearers) != 6 {
|
||||
t.Errorf("Expected 6 bearers (§14), got %d", len(bearers))
|
||||
}
|
||||
}
|
||||
|
||||
func TestSurveillanceResistantBearers(t *testing.T) {
|
||||
bearers := btypes.AllBearers()
|
||||
for _, b := range bearers {
|
||||
if b.Type == btypes.BearerInternet && b.SurveillanceResistant {
|
||||
t.Error("Internet bearer should NOT be surveillance-resistant (§14)")
|
||||
}
|
||||
if b.Type != btypes.BearerInternet && !b.SurveillanceResistant {
|
||||
t.Errorf("Bearer %s should be surveillance-resistant (§14)", b.Type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessingModeFCFS(t *testing.T) {
|
||||
if ptypes.ModeFCFS != "FCFS" {
|
||||
t.Error("Processing mode should be FCFS (§15 LOCKED)")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLightClientSize(t *testing.T) {
|
||||
if ptypes.LightClientSizeMB != 30 {
|
||||
t.Errorf("LightClientSize = %d, expected 30 MB (§15)", ptypes.LightClientSizeMB)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessorSelectionByProximity(t *testing.T) {
|
||||
processors := []ptypes.Processor{
|
||||
{ProcessorID: "far", Latitude: 40.0, Longitude: 40.0},
|
||||
{ProcessorID: "close", Latitude: 10.0, Longitude: 10.0},
|
||||
{ProcessorID: "mid", Latitude: 20.0, Longitude: 20.0},
|
||||
}
|
||||
selected := ptypes.SelectProcessorByProximity(10.1, 10.1, processors)
|
||||
if selected == nil || selected.ProcessorID != "close" {
|
||||
t.Error("Should select closest processor (§15: geographic proximity wins)")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmptyProcessorSelection(t *testing.T) {
|
||||
selected := ptypes.SelectProcessorByProximity(10.0, 10.0, []ptypes.Processor{})
|
||||
if selected != nil {
|
||||
t.Error("Empty processor list should return nil")
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,7 @@ type BloomBoosterBucket struct {
|
||||
UnlockHeight int64 `json:"unlock_height" yaml:"unlock_height"`
|
||||
}
|
||||
|
||||
// BloomSource defines where Bloom originates (§6: only from real yield)
|
||||
// BloomSource defines where Bloom originates (§6: only from real production)
|
||||
type BloomSource string
|
||||
|
||||
const (
|
||||
@@ -46,10 +46,10 @@ const (
|
||||
BloomFromRwaCashflow BloomSource = "RwaCashflow"
|
||||
)
|
||||
|
||||
// MissionLockBloom: Bloom originates ONLY from real yield (§6)
|
||||
// MissionLockBloom: Bloom originates ONLY from real production (§6)
|
||||
// No synthetic Bloom. No protocol-printed Bloom.
|
||||
// This is a Mission Lock — no Council vote can change it.
|
||||
const MissionLockBloom = "Bloom originates only from real yield. No synthetic Bloom. No protocol-printed Bloom."
|
||||
const MissionLockBloom = "Bloom originates only from real production. No synthetic Bloom. No protocol-printed Bloom."
|
||||
|
||||
type Params struct {
|
||||
TargetRateBps uint32 `json:"target_rate_bps" yaml:"target_rate_bps"`
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
package types
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
const (
|
||||
ModuleName = "mesh"
|
||||
StoreKey = ModuleName
|
||||
RouterKey = ModuleName
|
||||
QuerierRoute = ModuleName
|
||||
)
|
||||
|
||||
// Four Faces of the mesh experience (§8)
|
||||
// Reach (who you are), Standing (who you can trust),
|
||||
// Maps (where you are), Pay (how value flows)
|
||||
type MeshFace string
|
||||
|
||||
const (
|
||||
FaceReach MeshFace = "Reach"
|
||||
FaceStanding MeshFace = "Standing"
|
||||
FaceMaps MeshFace = "Maps"
|
||||
FacePay MeshFace = "Pay"
|
||||
)
|
||||
|
||||
// AllFaces returns the four mesh faces (§8)
|
||||
func AllFaces() []MeshFace {
|
||||
return []MeshFace{FaceReach, FaceStanding, FaceMaps, FacePay}
|
||||
}
|
||||
|
||||
// MapEntry is a discovery entry (§8: Maps — where you are, what's around)
|
||||
type MapEntry struct {
|
||||
EntryID string `json:"entry_id" yaml:"entry_id"`
|
||||
Name string `json:"name" yaml:"name"`
|
||||
Latitude float64 `json:"latitude" yaml:"latitude"`
|
||||
Longitude float64 `json:"longitude" yaml:"longitude"`
|
||||
Category string `json:"category" yaml:"category"` // Op, Pier, service
|
||||
HolderID string `json:"holder_id" yaml:"holder_id"`
|
||||
IsOp bool `json:"is_op" yaml:"is_op"`
|
||||
IsPier bool `json:"is_pier" yaml:"is_pier"`
|
||||
}
|
||||
|
||||
// PayAct represents a Pass-Act (value flow, §8: Pay)
|
||||
type PayAct struct {
|
||||
PassID string `json:"pass_id" yaml:"pass_id"`
|
||||
FromStashID string `json:"from_stash_id" yaml:"from_stash_id"`
|
||||
ToStashID string `json:"to_stash_id" yaml:"to_stash_id"`
|
||||
AmountGrain int64 `json:"amount_grain" yaml:"amount_grain"`
|
||||
FeeGrain int64 `json:"fee_grain" yaml:"fee_grain"`
|
||||
IsLongPass bool `json:"is_long_pass" yaml:"is_long_pass"` // remittance
|
||||
Timestamp int64 `json:"timestamp" yaml:"timestamp"`
|
||||
}
|
||||
|
||||
// ExitLayerType defines Layer 3 exit methods (§7)
|
||||
type ExitLayerType string
|
||||
|
||||
const (
|
||||
ExitDEX ExitLayerType = "DEX"
|
||||
ExitBridge ExitLayerType = "Bridge"
|
||||
ExitOffMesh ExitLayerType = "OffMesh"
|
||||
)
|
||||
|
||||
// MayasDayPlaceholder — full narrative deferred to component doc (§8, Q1)
|
||||
// The mesh is one environment with four invisible primitives
|
||||
// activating simultaneously. A Holder doesn't open apps — they live in the mesh.
|
||||
const MayasDayPlaceholder = "Maya's Day narrative deferred to Mesh Experience component doc (Architecture Q1)"
|
||||
|
||||
type Params struct{}
|
||||
|
||||
func DefaultParams() Params { return Params{} }
|
||||
|
||||
type GenesisState struct {
|
||||
Params Params `json:"params" yaml:"params"`
|
||||
MapEntries []MapEntry `json:"map_entries" yaml:"map_entries"`
|
||||
}
|
||||
|
||||
func DefaultGenesisState() *GenesisState {
|
||||
return &GenesisState{Params: DefaultParams(), MapEntries: []MapEntry{}}
|
||||
}
|
||||
|
||||
func ValidateGenesis(bz json.RawMessage) error { return nil }
|
||||
@@ -0,0 +1,39 @@
|
||||
package types_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/oy/openyield/x/mesh/types"
|
||||
)
|
||||
|
||||
func TestFourFaces(t *testing.T) {
|
||||
faces := types.AllFaces()
|
||||
if len(faces) != 4 {
|
||||
t.Errorf("Expected 4 mesh faces (§8), got %d", len(faces))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFaceNames(t *testing.T) {
|
||||
expected := map[types.MeshFace]bool{
|
||||
types.FaceReach: true, types.FaceStanding: true,
|
||||
types.FaceMaps: true, types.FacePay: true,
|
||||
}
|
||||
for _, f := range types.AllFaces() {
|
||||
if !expected[f] {
|
||||
t.Errorf("Unexpected face: %s", f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestExitLayerTypes(t *testing.T) {
|
||||
exits := []types.ExitLayerType{types.ExitDEX, types.ExitBridge, types.ExitOffMesh}
|
||||
if len(exits) != 3 {
|
||||
t.Errorf("Expected 3 exit layer types (§7), got %d", len(exits))
|
||||
}
|
||||
}
|
||||
|
||||
func TestMayasDayPlaceholder(t *testing.T) {
|
||||
if types.MayasDayPlaceholder == "" {
|
||||
t.Error("Maya's Day placeholder should note deferral (§8, Q1)")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package types
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
const (
|
||||
ModuleName = "processing"
|
||||
StoreKey = ModuleName
|
||||
RouterKey = ModuleName
|
||||
QuerierRoute = ModuleName
|
||||
|
||||
// FCFS processing — NOT fee-auctioned (§15 LOCKED)
|
||||
// Geographic proximity wins (closest processor to recipient)
|
||||
// Anyone with a phone can process via light client (~30 MB app)
|
||||
|
||||
LightClientSizeMB = 30 // ~30 MB app
|
||||
BatteryPerDayActivePct = 3 // ~1-3pct battery/day active
|
||||
)
|
||||
|
||||
// ProcessingMode is FCFS (§15) — never fee-auctioned
|
||||
type ProcessingMode string
|
||||
|
||||
const (
|
||||
ModeFCFS ProcessingMode = "FCFS" // First-come-first-served, not fee-auctioned
|
||||
)
|
||||
|
||||
// Processor is a light client processing Pass-Acts (§15)
|
||||
type Processor struct {
|
||||
ProcessorID string `json:"processor_id" yaml:"processor_id"`
|
||||
ReachID string `json:"reach_id" yaml:"reach_id"`
|
||||
Latitude float64 `json:"latitude" yaml:"latitude"`
|
||||
Longitude float64 `json:"longitude" yaml:"longitude"`
|
||||
ActiveSince int64 `json:"active_since" yaml:"active_since"`
|
||||
BlocksProcessed uint64 `json:"blocks_processed" yaml:"blocks_processed"`
|
||||
}
|
||||
|
||||
// ProcessingJob is a Pass-Act awaiting processing
|
||||
type ProcessingJob struct {
|
||||
JobID string `json:"job_id" yaml:"job_id"`
|
||||
SenderLat float64 `json:"sender_lat" yaml:"sender_lat"`
|
||||
SenderLng float64 `json:"sender_lng" yaml:"sender_lng"`
|
||||
RecipientLat float64 `json:"recipient_lat" yaml:"recipient_lat"`
|
||||
RecipientLng float64 `json:"recipient_lng" yaml:"recipient_lng"`
|
||||
AmountGrain int64 `json:"amount_grain" yaml:"amount_grain"`
|
||||
Timestamp int64 `json:"timestamp" yaml:"timestamp"`
|
||||
}
|
||||
|
||||
// SelectProcessorByProximity — geographic proximity wins (§15)
|
||||
// In FCFS mode, the closest processor to the recipient processes the job
|
||||
func SelectProcessorByProximity(recipientLat, recipientLng float64, processors []Processor) *Processor {
|
||||
if len(processors) == 0 {
|
||||
return nil
|
||||
}
|
||||
closest := &processors[0]
|
||||
minDist := haversine(recipientLat, recipientLng, closest.Latitude, closest.Longitude)
|
||||
for i := 1; i < len(processors); i++ {
|
||||
dist := haversine(recipientLat, recipientLng, processors[i].Latitude, processors[i].Longitude)
|
||||
if dist < minDist {
|
||||
minDist = dist
|
||||
closest = &processors[i]
|
||||
}
|
||||
}
|
||||
return closest
|
||||
}
|
||||
|
||||
// haversine computes distance between two coordinates (simplified)
|
||||
func haversine(lat1, lng1, lat2, lng2 float64) float64 {
|
||||
dlat := lat2 - lat1
|
||||
dlng := lng2 - lng1
|
||||
return dlat*dlat + dlng*dlng // squared distance (sufficient for comparison)
|
||||
}
|
||||
|
||||
type Params struct{}
|
||||
|
||||
func DefaultParams() Params { return Params{} }
|
||||
|
||||
type GenesisState struct {
|
||||
Params Params `json:"params" yaml:"params"`
|
||||
Processors []Processor `json:"processors" yaml:"processors"`
|
||||
}
|
||||
|
||||
func DefaultGenesisState() *GenesisState {
|
||||
return &GenesisState{Params: DefaultParams(), Processors: []Processor{}}
|
||||
}
|
||||
|
||||
func ValidateGenesis(bz json.RawMessage) error { return nil }
|
||||
Reference in New Issue
Block a user