169 lines
3.4 KiB
Go
169 lines
3.4 KiB
Go
// Copyright 2020 dfuse Platform Inc.
|
|
//
|
|
// 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 system
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
|
|
solana "github.com/dfuse-io/solana-go"
|
|
"github.com/lunixbochs/struc"
|
|
)
|
|
|
|
type SystemInstruction struct {
|
|
Type solana.Varuint16
|
|
Variant interface{}
|
|
}
|
|
|
|
func (si *SystemInstruction) Unpack(r io.Reader, length int, opt *struc.Options) (err error) {
|
|
if err = struc.Unpack(r, &si.Type); err != nil {
|
|
return
|
|
}
|
|
|
|
var el interface{}
|
|
switch si.Type {
|
|
case 0:
|
|
el = &CreateAccount{}
|
|
case 1:
|
|
el = &Assign{}
|
|
case 2:
|
|
el = &Transfer{}
|
|
default:
|
|
return fmt.Errorf("unsupported System Instruction variant %d", si.Type)
|
|
}
|
|
si.Variant = el
|
|
|
|
return struc.Unpack(r, el)
|
|
}
|
|
|
|
func (si SystemInstruction) Pack(p []byte, opt *struc.Options) (written int, err error) {
|
|
fmt.Println("CALLING OUR SI PACK", len(p), cap(p))
|
|
|
|
buf := &bytes.Buffer{}
|
|
w := &solana.ByteCountWriter{Writer: buf}
|
|
|
|
switch si.Variant.(type) {
|
|
case *CreateAccount:
|
|
si.Type = 0
|
|
case *Assign:
|
|
si.Type = 1
|
|
case *Transfer:
|
|
si.Type = 2
|
|
default:
|
|
return 0, fmt.Errorf("unsupported variant %T", si.Variant)
|
|
}
|
|
|
|
err = struc.Pack(w, si.Type)
|
|
if err != nil {
|
|
return 0, fmt.Errorf("pack type: %w", err)
|
|
}
|
|
|
|
err = struc.Pack(w, si.Variant)
|
|
if err != nil {
|
|
return 0, fmt.Errorf("pack impl: %w", err)
|
|
}
|
|
|
|
fmt.Println("byte count", w.ByteCount)
|
|
|
|
copy(p, buf.Bytes())
|
|
|
|
return w.ByteCount, nil
|
|
}
|
|
|
|
func (si SystemInstruction) Size(opt *struc.Options) int {
|
|
s1, err := struc.Sizeof(si.Type)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
s2, err := struc.Sizeof(si.Variant)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return s1 + s2
|
|
}
|
|
|
|
func (si SystemInstruction) String() string {
|
|
return fmt.Sprintf("variant %d, %T", si.Type, si.Variant)
|
|
}
|
|
|
|
type CreateAccount struct {
|
|
// prefixed with byte 0x00
|
|
Lamports solana.U64
|
|
Space solana.U64
|
|
Owner solana.PublicKey
|
|
}
|
|
|
|
type Assign struct {
|
|
// prefixed with byte 0x01
|
|
Owner solana.PublicKey
|
|
}
|
|
|
|
type Transfer struct {
|
|
// Prefixed with byte 0x02
|
|
Lamports solana.U64
|
|
}
|
|
|
|
type CreateAccountWithSeed struct {
|
|
// Prefixed with byte 0x03
|
|
Base solana.PublicKey
|
|
SeedSize int `struc:"sizeof=Seed"`
|
|
Seed string
|
|
Lamports solana.U64
|
|
Space solana.U64
|
|
Owner solana.PublicKey
|
|
}
|
|
|
|
type AdvanceNonceAccount struct {
|
|
// Prefix with 0x04
|
|
}
|
|
|
|
type WithdrawNonceAccount struct {
|
|
// Prefix with 0x05
|
|
Lamports solana.U64
|
|
}
|
|
|
|
type InitializeNonceAccount struct {
|
|
// Prefix with 0x06
|
|
AuthorizedAccount solana.PublicKey
|
|
}
|
|
|
|
type AuthorizeNonceAccount struct {
|
|
// Prefix with 0x07
|
|
AuthorizeAccount solana.PublicKey
|
|
}
|
|
|
|
type Allocate struct {
|
|
// Prefix with 0x08
|
|
Space solana.U64
|
|
}
|
|
|
|
type AllocateWithSeed struct {
|
|
// Prefixed with byte 0x09
|
|
Base solana.PublicKey
|
|
SeedSize int `struc:"sizeof=Seed"`
|
|
Seed string
|
|
Space solana.U64
|
|
Owner solana.PublicKey
|
|
}
|
|
|
|
type AssignWithSeed struct {
|
|
// Prefixed with byte 0x0a
|
|
Base solana.PublicKey
|
|
SeedSize int `struc:"sizeof=Seed"`
|
|
Seed string
|
|
Owner solana.PublicKey
|
|
}
|