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

HTTP Gateway Protocol V2 #5

Merged
merged 2 commits into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
21 changes: 21 additions & 0 deletions agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,32 @@ func (a Agent) GetCanisterInfo(canisterID principal.Principal, subPath string) (
return certificate.Lookup(path, node), nil
}

func (a Agent) GetCanisterMetadata(canisterID principal.Principal, subPath string) ([]byte, error) {
path := [][]byte{[]byte("canister"), canisterID.Raw, []byte("metadata"), []byte(subPath)}
c, err := a.readStateCertificate(canisterID, [][][]byte{path})
if err != nil {
return nil, err
}
var state map[string]any
if err := cbor.Unmarshal(c, &state); err != nil {
return nil, err
}
node, err := certificate.DeserializeNode(state["tree"].([]any))
if err != nil {
return nil, err
}
return certificate.Lookup(path, node), nil
}

// GetCanisterModuleHash returns the module hash for the given canister.
func (a Agent) GetCanisterModuleHash(canisterID principal.Principal) ([]byte, error) {
return a.GetCanisterInfo(canisterID, "module_hash")
}

func (a Agent) GetRootKey() []byte {
return a.rootKey
}

func (a Agent) Query(canisterID principal.Principal, methodName string, args []any, values []any) error {
rawArgs, err := idl.Marshal(args)
if err != nil {
Expand Down
6 changes: 3 additions & 3 deletions candid/internal/blob/grammar.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Do not edit. This file is auto-generated.
// Grammar: CANDID-BLOB (v0.1.0) github.com/di-wu/candid-go/internal/blob
// Grammar: CANDID-BLOB (v0.1.0) github.com/aviate-labs/agent-go/candid/internal/blob

package blob

Expand All @@ -13,7 +13,7 @@ import (
const (
Unknown = iota

// CANDID-BLOB (github.com/di-wu/candid-go/internal/blob)
// CANDID-BLOB (github.com/aviate-labs/agent-go/candid/internal/blob)

BlobT // 001
AlphaT // 002
Expand All @@ -23,7 +23,7 @@ const (
var NodeTypes = []string{
"UNKNOWN",

// CANDID-BLOB (github.com/di-wu/candid-go/internal/blob)
// CANDID-BLOB (github.com/aviate-labs/agent-go/candid/internal/blob)

"Blob",
"Alpha",
Expand Down
2 changes: 1 addition & 1 deletion candid/internal/blob/grammar.pegn
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# CANDID-BLOB (v0.1.0) github.com/di-wu/candid-go/internal/blob
# CANDID-BLOB (v0.1.0) github.com/aviate-labs/agent-go/candid/internal/blob

Blob <-- (Alpha / '\' Hex)+
Alpha <-- ([A-Z] / [a-z])+
Expand Down
8 changes: 4 additions & 4 deletions candid/internal/candid/grammar.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Do not edit. This file is auto-generated.
// Grammar: CANDID (v0.1.1) github.com/di-wu/candid-go/internal/candid
// Grammar: CANDID (v0.1.1) github.com/aviate-labs/agent-go/candid/internal/candid

package candid

Expand All @@ -13,7 +13,7 @@ import (
const (
Unknown = iota

// CANDID (github.com/di-wu/candid-go/internal/candid)
// CANDID (github.com/aviate-labs/agent-go/candid/internal/candid)

ProgT // 001
TypeT // 002
Expand Down Expand Up @@ -44,15 +44,15 @@ const (

// Token Definitions
const (
// CANDID (github.com/di-wu/candid-go/internal/candid)
// CANDID (github.com/aviate-labs/agent-go/candid/internal/candid)

ESC = 0x005C // \
)

var NodeTypes = []string{
"UNKNOWN",

// CANDID (github.com/di-wu/candid-go/internal/candid)
// CANDID (github.com/aviate-labs/agent-go/candid/internal/candid)

"Prog",
"Type",
Expand Down
2 changes: 1 addition & 1 deletion candid/internal/candid/grammar.pegn
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# CANDID (v0.1.1) github.com/di-wu/candid-go/internal/candid
# CANDID (v0.1.1) github.com/aviate-labs/agent-go/candid/internal/candid

Prog <-- (Ws Def (';' Ws Def)*)? ';'? Ws
(Ws Actor (';' Ws Actor)*)? ';'? Ws
Expand Down
8 changes: 4 additions & 4 deletions candid/internal/candidtest/grammar.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Do not edit. This file is auto-generated.
// Grammar: CANDID-TEST (v0.1.0) github.com/di-wu/candid-go/internal/candidtest
// Grammar: CANDID-TEST (v0.1.0) github.com/aviate-labs/agent-go/candid/internal/candidtest

package candidtest

Expand All @@ -13,7 +13,7 @@ import (
const (
Unknown = iota

// CANDID-TEST (github.com/di-wu/candid-go/internal/candidtest)
// CANDID-TEST (github.com/aviate-labs/agent-go/candid/internal/candidtest)

TestDataT // 001
CommentTextT // 002
Expand All @@ -38,15 +38,15 @@ const (

// Token Definitions
const (
// CANDID-TEST (github.com/di-wu/candid-go/internal/candidtest)
// CANDID-TEST (github.com/aviate-labs/agent-go/candid/internal/candidtest)

ESC = 0x005C // \
)

var NodeTypes = []string{
"UNKNOWN",

// CANDID-TEST (github.com/di-wu/candid-go/internal/candidtest)
// CANDID-TEST (github.com/aviate-labs/agent-go/candid/internal/candidtest)

"TestData",
"CommentText",
Expand Down
2 changes: 1 addition & 1 deletion candid/internal/candidtest/grammar.pegn
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# CANDID-TEST (v0.1.0) github.com/di-wu/candid-go/internal/candidtest
# CANDID-TEST (v0.1.0) github.com/aviate-labs/agent-go/candid/internal/candidtest

TestData <-- (Comment / Test / EndLine)+

Expand Down
8 changes: 4 additions & 4 deletions candid/internal/candidvalue/grammar.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Do not edit. This file is auto-generated.
// Grammar: CANDID (v0.1.0) github.com/di-wu/candid-go/internal/candid/candidvalue
// Grammar: CANDID (v0.1.0) github.com/aviate-labs/agent-go/candid/internal/candid/candidvalue

package candidvalue

Expand All @@ -13,7 +13,7 @@ import (
const (
Unknown = iota

// CANDID (github.com/di-wu/candid-go/internal/candid/candidvalue)
// CANDID (github.com/aviate-labs/agent-go/candid/internal/candid/candidvalue)

ValuesT // 001
OptValueT // 002
Expand All @@ -35,15 +35,15 @@ const (

// Token Definitions
const (
// CANDID (github.com/di-wu/candid-go/internal/candid/candidvalue)
// CANDID (github.com/aviate-labs/agent-go/candid/internal/candid/candidvalue)

ESC = 0x005C // \
)

var NodeTypes = []string{
"UNKNOWN",

// CANDID (github.com/di-wu/candid-go/internal/candid/candidvalue)
// CANDID (github.com/aviate-labs/agent-go/candid/internal/candid/candidvalue)

"Values",
"OptValue",
Expand Down
2 changes: 1 addition & 1 deletion candid/internal/candidvalue/grammar.pegn
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# CANDID (v0.1.0) github.com/di-wu/candid-go/internal/candid/candidvalue
# CANDID (v0.1.0) github.com/aviate-labs/agent-go/candid/internal/candid/candidvalue

Values <-- '(' Sp (Value (Sp ',' Sp Value)*)? Sp ')' / Value
Value <- OptValue / Num / Bool / Null / Text / Record / Variant / Principal / Vec / Blob
Expand Down
3 changes: 2 additions & 1 deletion candid/internal/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package main

import (
"fmt"
pegn "github.com/pegn/pegn-go"
"io/ioutil"
"log"
)
Expand All @@ -20,7 +21,7 @@ func main() {
} {
rawGrammar, _ := ioutil.ReadFile(fmt.Sprintf("%s/grammar.pegn", grammar.path))
if err := pegn.GenerateFromFiles(fmt.Sprintf("%s/", grammar.path), pegn.Config{
ModulePath: fmt.Sprintf("github.com/di-wu/candid-go/%s", grammar.path),
ModulePath: fmt.Sprintf("github.com/aviate-labs/agent-go/candid/%s", grammar.path),
ModuleName: grammar.name,
IgnoreReserved: true,
TypeSuffix: "T",
Expand Down
33 changes: 17 additions & 16 deletions certificate/certificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ type Cert struct {
// Certificate is a certificate gets returned by the IC and can be used to verify
// the state root based on the root key and canister ID.
type Certificate struct {
cert Cert
rootKey []byte
canisterID principal.Principal
Cert Cert
RootKey []byte
CanisterID principal.Principal
}

// New creates a new certificate.
Expand All @@ -33,23 +33,23 @@ func New(canisterID principal.Principal, rootKey []byte, certificate []byte) (*C
return nil, err
}
return &Certificate{
cert: cert,
rootKey: rootKey,
canisterID: canisterID,
Cert: cert,
RootKey: rootKey,
CanisterID: canisterID,
}, nil
}

// Verify verifies the certificate.
func (c Certificate) Verify() error {
signature, err := bls.SignatureFromBytes(c.cert.Signature)
signature, err := bls.SignatureFromBytes(c.Cert.Signature)
if err != nil {
return err
}
publicKey, err := c.getPublicKey()
if err != nil {
return err
}
rootHash := c.cert.Tree.Digest()
rootHash := c.Cert.Tree.Digest()
message := append(DomainSeparator("ic-state-root"), rootHash[:]...)
if !signature.Verify(publicKey, string(message)) {
return fmt.Errorf("signature verification failed")
Expand All @@ -59,13 +59,14 @@ func (c Certificate) Verify() error {

// getPublicKey checks the delegation and returns the public key.
func (c Certificate) getPublicKey() (*bls.PublicKey, error) {
if c.cert.Delegation == nil {
return bls.PublicKeyFromBytes(c.rootKey)
if c.Cert.Delegation == nil {
return bls.PublicKeyFromBytes(c.RootKey)
}
cert := c.cert.Delegation

cert := c.Cert.Delegation
canisterRanges := Lookup(
LookupPath("subnet", string(cert.SubnetId.Raw), "canister_ranges"),
cert.Certificate.cert.Tree.root,
cert.Certificate.Cert.Tree.Root,
)
if canisterRanges == nil {
return nil, fmt.Errorf("no canister ranges found for subnet %s", cert.SubnetId)
Expand All @@ -80,18 +81,18 @@ func (c Certificate) getPublicKey() (*bls.PublicKey, error) {
if len(pair) != 2 {
return nil, fmt.Errorf("invalid range: %v", pair)
}
if slices.Compare(pair[0], c.canisterID.Raw) <= 0 && slices.Compare(c.canisterID.Raw, pair[1]) <= 0 {
if slices.Compare(pair[0], c.CanisterID.Raw) <= 0 && slices.Compare(c.CanisterID.Raw, pair[1]) <= 0 {
inRange = true
break
}
}
if !inRange {
return nil, fmt.Errorf("canister %s is not in range", c.canisterID)
return nil, fmt.Errorf("canister %s is not in range", c.CanisterID)
}

publicKey := Lookup(
LookupPath("subnet", string(cert.SubnetId.Raw), "public_key"),
cert.Certificate.cert.Tree.root,
cert.Certificate.Cert.Tree.Root,
)
if publicKey == nil {
return nil, fmt.Errorf("no public key found for subnet %s", cert.SubnetId)
Expand Down Expand Up @@ -131,7 +132,7 @@ func (d *Delegation) UnmarshalCBOR(bytes []byte) error {
Raw: v.([]byte),
}
case "certificate":
if err := cbor.Unmarshal(v.([]byte), &d.Certificate.cert); err != nil {
if err := cbor.Unmarshal(v.([]byte), &d.Certificate.Cert); err != nil {
return err
}
default:
Expand Down
5 changes: 5 additions & 0 deletions certificate/http/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# HTTP Gateway Protocol

## References

- [Specification](https://internetcomputer.org/docs/current/references/http-gateway-protocol-spec)
Loading