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

FVM integration #217

Merged
merged 82 commits into from
Apr 1, 2022
Merged
Show file tree
Hide file tree
Changes from 64 commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
f48a5c8
feat: get basic fvm code pulled in
cryptonemo Dec 15, 2021
665619b
feat: try to instantiate an fvm machine with basic defaults
cryptonemo Dec 16, 2021
0a0463c
store machines and retrieve them
dignifiedquire Dec 16, 2021
7e6e4c8
fix compile and update deps
dignifiedquire Dec 16, 2021
497da29
feat: add execute_message API and some more code
cryptonemo Dec 16, 2021
67ce452
feat: update dependencies
cryptonemo Dec 17, 2021
768ed2a
Apply some review feedback
cryptonemo Dec 20, 2021
97279f3
fix: rebased, but the fvm imports are broken after they were moved
cryptonemo Jan 13, 2022
cb7bc67
Update to the latest FVM code
arajasek Jan 14, 2022
061b759
feat: update to latest fvm code, using latest proofs code
cryptonemo Jan 19, 2022
dd1f6e2
feat: update to latest fvm
cryptonemo Jan 19, 2022
6ab5769
style: fix clippy warnings
cryptonemo Jan 19, 2022
db01ec7
style: rust fmt
cryptonemo Jan 19, 2022
27ff0fa
add go bindings
arajasek Jan 14, 2022
f42386e
dep: update specs-actors to master
Stebalien Jan 24, 2022
6bae4f3
fix compile
Stebalien Jan 28, 2022
deb3597
fvm: remove the fvm registry map
Stebalien Jan 28, 2022
7b89e76
fvm: avoid double-freeing the return data
Stebalien Jan 28, 2022
65f2e4e
fvm: implement machine flush
Stebalien Jan 28, 2022
e6730c4
fvm: optimize bigint conversions
Stebalien Jan 28, 2022
81bf427
fvm: move externs into FFI
Stebalien Jan 31, 2022
a5ead0e
fvm: fixup return types
Stebalien Jan 31, 2022
b6cfd8e
fvm: get rust -> go bindings compiling and linking
Stebalien Jan 31, 2022
f4fb585
fvm: add context to externs
Stebalien Jan 31, 2022
dc4040f
fvm: move fvm back to the top-level
Stebalien Jan 31, 2022
86f38e0
fvm: match lotus randomness API
Stebalien Jan 31, 2022
8807f57
chore: update deps
Stebalien Jan 31, 2022
a729528
fvm: remove default features from wasmtime
Stebalien Jan 31, 2022
88fd1a1
fvm: initialize registry
Stebalien Jan 31, 2022
951c965
fix: don't drop executor in response
Stebalien Jan 31, 2022
5ccdbe4
fvm: useful error messages
Stebalien Feb 2, 2022
b71619c
fvm: correctly patch dependencies
Stebalien Feb 2, 2022
1898f2f
fvm: pass the chain length for gas accounting
Stebalien Feb 5, 2022
8229d7c
fvm: use the correct length for the CID returned from flush
Stebalien Feb 5, 2022
1e18dc4
fvm: update FVM for caching and fixes
Stebalien Feb 5, 2022
c689267
fvm: fix and test bigint splitting logic
Stebalien Feb 9, 2022
73f84f3
fvm: change base circ supply to fil vested
Stebalien Feb 9, 2022
f029f27
fvm: keep FVM alive
Stebalien Feb 9, 2022
0ddea12
chore: update fvm
Stebalien Feb 10, 2022
021290c
chore: update fvm
Stebalien Feb 11, 2022
a220a54
Merge branch 'master' into asr/fvm
arajasek Feb 13, 2022
d65d377
chore: update fvm
Stebalien Feb 17, 2022
f87048c
feat: implement put many in the cgo blockstore
Stebalien Feb 17, 2022
7dc35f8
Merge pull request #238 from filecoin-project/steb/put-many
Stebalien Feb 17, 2022
2c66830
fvm: return gasused when verifying consensus faults
arajasek Feb 15, 2022
c588fb9
FVM: VerifyConsensusFault: don't try to resolve address if there's no…
arajasek Feb 18, 2022
9ff2301
Merge pull request #235 from filecoin-project/asr/fault
arajasek Feb 18, 2022
23ba048
fvm: pass contexts and address TODOs
Stebalien Feb 21, 2022
1db75b0
fvm: use shared reference for locked FVM executor
Stebalien Feb 22, 2022
3cd2aea
fvm: add wasm32 build target
Stebalien Feb 22, 2022
98e5f6b
fvm: use correct feature flags for crypto
Stebalien Feb 22, 2022
a671fb8
fvm: fix lint warnings
Stebalien Feb 22, 2022
d3c8c6d
ci: install wasm32 target in CI
Stebalien Feb 22, 2022
3369d4b
ci: update golang
Stebalien Feb 22, 2022
ce15391
fvm: fix int reformatting lints and compile on go 1.16
Stebalien Feb 22, 2022
7bf4d92
fvm: fix linking on macos
Stebalien Feb 22, 2022
048c3b6
Merge pull request #239 from filecoin-project/steb/address-todos
Stebalien Feb 22, 2022
843cd56
fvm: fix invalid return bytes pointer
Stebalien Feb 28, 2022
ae1a4a5
Merge pull request #241 from filecoin-project/steb/fix-invalid-ptr
Stebalien Feb 28, 2022
084ee86
FVM: support nv15 (#240)
arajasek Mar 11, 2022
6865a5e
Update Cargo.lock
arajasek Mar 15, 2022
c2668aa
Merge branch 'master' into fvm
arajasek Mar 16, 2022
4b620e6
fix: resolve conflicting proofs-api dep
cryptonemo Mar 17, 2022
decb2a0
remove const (#245)
turuslan Mar 17, 2022
12b6b1e
Bump v7 actors to v7.0.6
arajasek Mar 23, 2022
e81d302
Merge pull request #248 from filecoin-project/asr/v7-actors-bump
arajasek Mar 23, 2022
d7affa9
doc(fvm): document bindgen feature
Stebalien Mar 23, 2022
bd31298
chore(fvm): rename out parameters to make usage clear
Stebalien Mar 23, 2022
27aa405
feat(fvm): construct FVM with an options struct
Stebalien Mar 23, 2022
20b1cd2
chore: remove 32bit support from the FVM
Stebalien Mar 23, 2022
046b147
doc(fvm): document why we explicitly call KeepAlive
Stebalien Mar 23, 2022
5df6856
doc(fvm): document cgo constants/logic
Stebalien Mar 23, 2022
7b28c52
fix: remove identity hash workaround
Stebalien Mar 24, 2022
f69feda
doc(fvm): expand rust-side extern/blockstore documentation
Stebalien Mar 24, 2022
7f93fe5
chore: bump to actor v7.0.7
jennijuju Mar 27, 2022
5ec79e9
fix: completely remove the multihash identity feature
Stebalien Mar 28, 2022
dd1c85a
chore: update fvm & actors
Stebalien Mar 29, 2022
5bb0764
chore: update FVM
Stebalien Mar 30, 2022
9522c86
fix: use exported constants in FVM/cgo errors
Stebalien Mar 30, 2022
d418486
chore(fvm): fix code comment
Stebalien Mar 31, 2022
bf1b7b1
use the latest v6 & v7 actors
jennijuju Apr 1, 2022
4b939fe
Merge pull request #256 from filecoin-project/jen/actorbump
arajasek Apr 1, 2022
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
8 changes: 5 additions & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ orbs:
executors:
golang:
docker:
- image: circleci/golang:1.13
- image: circleci/golang:1.16.4
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI this version is significantly out of date in terms of bugfix releases, the latest is 1.16.15. 1.16.x is also unsupported now that 1.18 is out, but I imagine you're already aware of that.

resource_class: 2xlarge
rust:
docker:
Expand All @@ -32,7 +32,7 @@ jobs:
- go/mod-download
- go/install-golangci-lint:
gobin: $HOME/.local/bin
version: 1.32.0
version: 1.44.2
- run:
command: make go-lint

Expand Down Expand Up @@ -109,6 +109,7 @@ jobs:
- cargo-v0-{{ checksum "rust/rust-toolchain" }}-{{ checksum "rust/Cargo.toml" }}-{{ checksum "rust/Cargo.lock" }}-{{ arch }}
- run: cd rust && rustup install $(cat rust-toolchain)
- run: cd rust && rustup default $(cat rust-toolchain)
- run: cd rust && rustup target add wasm32-unknown-unknown
- run: cd rust && rustup component add rustfmt
- run: cd rust && rustup component add clippy
- run: cd rust && cargo fetch
Expand Down Expand Up @@ -145,6 +146,7 @@ jobs:
- cargo-v0-{{ checksum "rust/rust-toolchain" }}-{{ checksum "rust/Cargo.toml" }}-{{ checksum "rust/Cargo.lock" }}-{{ arch }}
- run: cd rust && rustup install $(cat rust-toolchain)
- run: cd rust && rustup default $(cat rust-toolchain)
- run: cd rust && rustup target add wasm32-unknown-unknown
- run: cd rust && rustup component add rustfmt
- run: cd rust && rustup component add clippy
- run: cd rust && cargo fetch
Expand Down Expand Up @@ -209,7 +211,7 @@ commands:
- run:
name: Install Go
command: |
curl https://dl.google.com/go/go1.13.7.darwin-amd64.pkg -o /tmp/go.pkg && \
curl https://dl.google.com/go/go1.16.4.darwin-amd64.pkg -o /tmp/go.pkg && \
sudo installer -pkg /tmp/go.pkg -target /
go version
- run:
Expand Down
6 changes: 4 additions & 2 deletions bls.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
//+build cgo
//go:build cgo
dignifiedquire marked this conversation as resolved.
Show resolved Hide resolved
// +build cgo

package ffi

// #cgo LDFLAGS: ${SRCDIR}/libfilcrypto.a
// #cgo linux LDFLAGS: ${SRCDIR}/libfilcrypto.a -Wl,-unresolved-symbols=ignore-all
// #cgo darwin LDFLAGS: ${SRCDIR}/libfilcrypto.a -Wl,-undefined,dynamic_lookup
// #cgo pkg-config: ${SRCDIR}/filcrypto.pc
// #include "./filcrypto.h"
import "C"
Expand Down
130 changes: 130 additions & 0 deletions cgo/blockstore.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package cgo

import (
"unsafe"

blocks "github.com/ipfs/go-block-format"
"github.com/ipfs/go-cid"
blockstore "github.com/ipfs/go-ipfs-blockstore"
)

/*
#include <stdint.h>
typedef const uint8_t* buf_t;
dignifiedquire marked this conversation as resolved.
Show resolved Hide resolved
*/
import "C"

func toCid(k C.buf_t, kLen C.int32_t) cid.Cid {
type cidRepr struct {
str string
}
return *(*cid.Cid)(unsafe.Pointer(&cidRepr{
str: C.GoStringN((*C.char)(unsafe.Pointer(k)), kLen),
}))
}

//export cgo_blockstore_get
func cgo_blockstore_get(handle C.uint64_t, k C.buf_t, kLen C.int32_t, block **C.uint8_t, size *C.int32_t) C.int32_t {
c := toCid(k, kLen)
externs, ctx := Lookup(uint64(handle))
if externs == nil {
return ErrInvalidHandle
}

err := externs.View(ctx, c, func(data []byte) error {
*block = (C.buf_t)(C.CBytes(data))
*size = C.int32_t(len(data))
return nil
})

switch err {
case nil:
return 0
case blockstore.ErrNotFound:
return ErrNotFound
default:
return ErrIO
}
}

//export cgo_blockstore_put
func cgo_blockstore_put(handle C.uint64_t, k C.buf_t, kLen C.int32_t, block C.buf_t, blockLen C.int32_t) C.int32_t {
c := toCid(k, kLen)
externs, ctx := Lookup(uint64(handle))
if externs == nil {
return ErrInvalidHandle
}
b, _ := blocks.NewBlockWithCid(C.GoBytes(unsafe.Pointer(block), blockLen), c)
if externs.Put(ctx, b) != nil {
return ErrIO
}
return 0
}

//export cgo_blockstore_put_many
func cgo_blockstore_put_many(handle C.uint64_t, lengths *C.int32_t, lengthsLen C.int32_t, blockBuf C.buf_t) C.int32_t {
externs, ctx := Lookup(uint64(handle))
if externs == nil {
return ErrInvalidHandle
}
// Get a reference to the lengths vector without copying.
const MAX_LEN = 1 << 30
if lengthsLen > MAX_LEN {
return ErrInvalidArgument
}

lengthsGo := (*[MAX_LEN]C.int32_t)(unsafe.Pointer(lengths))[:lengthsLen:lengthsLen]
blocksGo := make([]blocks.Block, 0, lengthsLen)
for _, length := range lengthsGo {
if length > MAX_LEN {
return ErrInvalidArgument
}
// get the next buffer. We could use C.GoBytes, but that copies.
buf := (*[MAX_LEN]byte)(unsafe.Pointer(blockBuf))[:length:length]

// read the CID. This function will copy the CID internally.
cidLen, k, err := cid.CidFromBytes(buf)
if err != nil {
return ErrInvalidArgument
}
buf = buf[cidLen:]

// Read the block and copy it. Unfortunately, our blockstore makes no guarantees
// about not holding onto blocks.
block := make([]byte, len(buf))
copy(block, buf)
b, _ := blocks.NewBlockWithCid(block, k)

// Add it to the batch.
blocksGo = append(blocksGo, b)

// Advance the block buffer.
blockBuf = (C.buf_t)(unsafe.Pointer(uintptr(unsafe.Pointer(blockBuf)) + uintptr(length)))
}
if externs.PutMany(ctx, blocksGo) != nil {
return ErrIO
}
return 0
}

//export cgo_blockstore_has
func cgo_blockstore_has(handle C.uint64_t, k C.buf_t, kLen C.int32_t) C.int32_t {
c := toCid(k, kLen)
externs, ctx := Lookup(uint64(handle))
if externs == nil {
return ErrInvalidHandle
}
has, err := externs.Has(ctx, c)
switch err {
case nil:
case blockstore.ErrNotFound:
// Some old blockstores still return this.
return 0
default:
return ErrIO
}
if has {
return 1
}
return 0
}
8 changes: 8 additions & 0 deletions cgo/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package cgo

const (
ErrInvalidHandle = -1 - iota
Stebalien marked this conversation as resolved.
Show resolved Hide resolved
ErrNotFound
ErrIO
ErrInvalidArgument
)
97 changes: 97 additions & 0 deletions cgo/extern.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package cgo

/*
#include <stdint.h>
typedef const uint8_t* buf_t;
*/
import "C"
import (
"unsafe"

"github.com/filecoin-project/go-address"

"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/crypto"
)

//export cgo_extern_get_chain_randomness
func cgo_extern_get_chain_randomness(
handle C.uint64_t, pers C.int64_t, round C.int64_t,
entropy C.buf_t, entropyLen C.int32_t,
output C.buf_t,
) C.int32_t {
out := (*[32]byte)(unsafe.Pointer(output))
externs, ctx := Lookup(uint64(handle))
if externs == nil {
return ErrInvalidHandle
}

rand, err := externs.GetChainRandomness(ctx, crypto.DomainSeparationTag(pers), abi.ChainEpoch(round), C.GoBytes(unsafe.Pointer(entropy), entropyLen))

switch err {
case nil:
copy(out[:], rand)
return 0
default:
return ErrIO
}
}

//export cgo_extern_get_beacon_randomness
func cgo_extern_get_beacon_randomness(
handle C.uint64_t, pers C.int64_t, round C.int64_t,
entropy C.buf_t, entropyLen C.int32_t,
output C.buf_t,
) C.int32_t {
out := (*[32]byte)(unsafe.Pointer(output))
externs, ctx := Lookup(uint64(handle))
if externs == nil {
return ErrInvalidHandle
}

rand, err := externs.GetBeaconRandomness(ctx, crypto.DomainSeparationTag(pers), abi.ChainEpoch(round), C.GoBytes(unsafe.Pointer(entropy), entropyLen))

switch err {
case nil:
copy(out[:], rand)
return 0
default:
return ErrIO
}
}

//export cgo_extern_verify_consensus_fault
func cgo_extern_verify_consensus_fault(
handle C.uint64_t,
h1 C.buf_t, h1Len C.int32_t,
h2 C.buf_t, h2Len C.int32_t,
extra C.buf_t, extraLen C.int32_t,
minerId *C.uint64_t,
Stebalien marked this conversation as resolved.
Show resolved Hide resolved
epoch *C.int64_t,
fault *C.int64_t,
gasUsed *C.int64_t,
) C.int32_t {
externs, ctx := Lookup(uint64(handle))
if externs == nil {
return ErrInvalidHandle
}

h1Go := C.GoBytes(unsafe.Pointer(h1), h1Len)
h2Go := C.GoBytes(unsafe.Pointer(h2), h2Len)
extraGo := C.GoBytes(unsafe.Pointer(extra), extraLen)

res, gas := externs.VerifyConsensusFault(ctx, h1Go, h2Go, extraGo)
*gasUsed = C.int64_t(gas)
*fault = C.int64_t(res.Type)

if res.Type != ConsensusFaultNone {
id, err := address.IDFromAddress(res.Target)
if err != nil {
return ErrIO
}
*epoch = C.int64_t(res.Epoch)
*minerId = C.uint64_t(id)
}

return 0
}
37 changes: 37 additions & 0 deletions cgo/interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package cgo

import (
"context"

"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/crypto"
blockstore "github.com/ipfs/go-ipfs-blockstore"
)

type ConsensusFault struct {
// Address of the miner at fault (always an ID address).
Target address.Address
// Epoch of the fault, which is the higher epoch of the two blocks causing it.
Epoch abi.ChainEpoch
// Type of fault.
Type ConsensusFaultType
}

type ConsensusFaultType int64

const (
ConsensusFaultNone ConsensusFaultType = 0
ConsensusFaultDoubleForkMining ConsensusFaultType = 1
ConsensusFaultParentGrinding ConsensusFaultType = 2
ConsensusFaultTimeOffsetMining ConsensusFaultType = 3
)

type Externs interface {
GetChainRandomness(ctx context.Context, personalization crypto.DomainSeparationTag, epoch abi.ChainEpoch, entropy []byte) ([]byte, error)
GetBeaconRandomness(ctx context.Context, personalization crypto.DomainSeparationTag, epoch abi.ChainEpoch, entropy []byte) ([]byte, error)
VerifyConsensusFault(ctx context.Context, h1, h2, extra []byte) (*ConsensusFault, int64)

blockstore.Blockstore
blockstore.Viewer
}
49 changes: 49 additions & 0 deletions cgo/registry.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package cgo

import (
"context"
"sync"
)

var (
mu sync.RWMutex
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Stebalien are you planning on pulling the atomic version into this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it work? IIRC, it was slower, right?

But anyways, I'd kind of like to merge this version first, if possible.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, hell no. Not unless this turns out to be the bottleneck.

registry map[uint64]registeredExterns
nextId uint64
)

type registeredExterns struct {
context.Context
Externs
}

// Register a new item and get a handle.
func Register(ctx context.Context, externs Externs) uint64 {
mu.Lock()
defer mu.Unlock()
if registry == nil {
registry = make(map[uint64]registeredExterns)
}
id := nextId
nextId++
registry[id] = registeredExterns{ctx, externs}
return id
}

// Unregister a blockstore.
//
// WARNING: This method must be called at most _once_ with a handle previously returned by Register.
func Unregister(handle uint64) {
mu.Lock()
defer mu.Unlock()

delete(registry, handle)
}

// Lookup a blockstore by handle.
func Lookup(handle uint64) (Externs, context.Context) {
mu.RLock()
externs := registry[handle]
mu.RUnlock()

return externs.Externs, externs.Context
}
Loading