Skip to content

Commit a7d5488

Browse files
authored
feat: make fvm compile optional (#550)
Disable with FFI_DISABLE_FVM=1 while building
1 parent a56795c commit a7d5488

File tree

11 files changed

+257
-81
lines changed

11 files changed

+257
-81
lines changed

.github/workflows/ci.yml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,14 @@ jobs:
100100
with:
101101
submodules: recursive
102102
ref: ${{ github.event.inputs.ref }}
103+
- if: runner.os == 'Linux'
104+
name: Install GCC 12 and set environment
105+
run: |
106+
sudo apt-get update
107+
sudo apt-get install -y gcc-12 g++-12
108+
echo "CC=gcc-12" >> $GITHUB_ENV
109+
echo "CXX=g++-12" >> $GITHUB_ENV
110+
echo "NVCC_PREPEND_FLAGS=-allow-unsupported-compiler" >> $GITHUB_ENV
103111
- if: runner.os == 'macOS'
104112
run: cd rust && cargo fetch
105113
- name: Build project
@@ -142,7 +150,7 @@ jobs:
142150
env:
143151
CC: gcc-12
144152
CXX: g++-12
145-
NVCC_PREPEND_FLAGS: "-ccbin /usr/bin/g++-12"
153+
NVCC_PREPEND_FLAGS: "-allow-unsupported-compiler"
146154
steps:
147155
- uses: actions/checkout@v4
148156
with:
@@ -153,5 +161,9 @@ jobs:
153161
with:
154162
submodules: recursive
155163
ref: ${{ github.event.inputs.ref }}
164+
- name: Install GCC 12
165+
run: |
166+
sudo apt-get update
167+
sudo apt-get install -y gcc-12 g++-12
156168
- name: Build project with `FFI_USE_CUDA_SUPRASEAL=1`
157169
run: FFI_BUILD_FROM_SOURCE=1 FFI_USE_CUDA_SUPRASEAL=1 make

cgo/errors.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,22 @@ package cgo
44
// #cgo darwin LDFLAGS: ${SRCDIR}/../libfilcrypto.a -Wl,-undefined,dynamic_lookup
55
// #cgo pkg-config: ${SRCDIR}/../filcrypto.pc
66
// #include "../filcrypto.h"
7+
// // Provide fallbacks when FVM is not compiled into filcrypto
8+
// #ifndef FVM_ERROR_INVALID_HANDLE
9+
// #define FVM_ERROR_INVALID_HANDLE -1
10+
// #endif
11+
// #ifndef FVM_ERROR_NOT_FOUND
12+
// #define FVM_ERROR_NOT_FOUND -2
13+
// #endif
14+
// #ifndef FVM_ERROR_IO
15+
// #define FVM_ERROR_IO -3
16+
// #endif
17+
// #ifndef FVM_ERROR_INVALID_ARGUMENT
18+
// #define FVM_ERROR_INVALID_ARGUMENT -4
19+
// #endif
20+
// #ifndef FVM_ERROR_PANIC
21+
// #define FVM_ERROR_PANIC -5
22+
// #endif
723
import "C"
824
import (
925
"fmt"

cgo/fvm.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//go:build fvm
2+
13
package cgo
24

35
/*

cgo/types.go

Lines changed: 7 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ type RegisteredAggregationProof C.RegisteredAggregationProof_t
1818
type RegisteredPoStProof C.RegisteredPoStProof_t
1919
type RegisteredUpdateProof C.RegisteredUpdateProof_t
2020

21-
type FvmRegisteredVersion C.FvmRegisteredVersion_t
21+
// FVM types moved to types_fvm.go behind build tag
2222

2323
type AggregationInputs C.AggregationInputs_t
2424

@@ -49,8 +49,7 @@ type ByteArray32 C.uint8_32_array_t
4949
type ByteArray48 C.uint8_48_array_t
5050
type ByteArray96 C.uint8_96_array_t
5151

52-
type FvmMachine C.InnerFvmMachine_t
53-
type FvmMachineExecuteResponse C.FvmMachineExecuteResponse_t
52+
// FVM types moved to types_fvm.go behind build tag
5453

5554
type resultBool C.Result_bool_t
5655
type resultGeneratePieceCommitment C.Result_GeneratePieceCommitment_t
@@ -70,8 +69,7 @@ type resultGenerateFallbackSectorChallenges C.Result_GenerateFallbackSectorChall
7069
type resultGenerateSingleWindowPoStWithVanilla C.Result_GenerateSingleWindowPoStWithVanilla_t
7170
type resultPoStProof C.Result_PoStProof_t
7271

73-
type resultFvmMachine C.Result_InnerFvmMachine_ptr_t
74-
type resultFvmMachineExecuteResponse C.Result_FvmMachineExecuteResponse_t
72+
// FVM types moved to types_fvm.go behind build tag
7573

7674
type result interface {
7775
statusCode() FCPResponseStatus
@@ -606,63 +604,10 @@ func (ptr *PoStProof) Destroy() {
606604
}
607605
}
608606

609-
func (ptr *resultFvmMachineExecuteResponse) statusCode() FCPResponseStatus {
610-
return FCPResponseStatus(ptr.status_code)
611-
}
612-
613-
func (ptr *resultFvmMachineExecuteResponse) errorMsg() *SliceBoxedUint8 {
614-
return (*SliceBoxedUint8)(&ptr.error_msg)
615-
}
616-
617-
func (ptr *resultFvmMachineExecuteResponse) destroy() {
618-
if ptr != nil {
619-
C.destroy_fvm_machine_execute_response((*C.Result_FvmMachineExecuteResponse_t)(ptr))
620-
ptr = nil
621-
}
622-
}
623-
624-
func (ptr *resultFvmMachine) statusCode() FCPResponseStatus {
625-
return FCPResponseStatus(ptr.status_code)
626-
}
607+
// FVM helpers moved to types_fvm.go
627608

628-
func (ptr *resultFvmMachine) errorMsg() *SliceBoxedUint8 {
629-
return (*SliceBoxedUint8)(&ptr.error_msg)
630-
}
609+
// FVM helpers moved to types_fvm.go
631610

632-
func (ptr *resultFvmMachine) destroy() {
633-
if ptr != nil {
634-
C.destroy_create_fvm_machine_response((*C.Result_InnerFvmMachine_ptr_t)(ptr))
635-
ptr = nil
636-
}
637-
}
611+
// FVM helpers moved to types_fvm.go
638612

639-
func (ptr *FvmMachine) Destroy() {
640-
if ptr != nil {
641-
C.drop_fvm_machine((*C.InnerFvmMachine_t)(ptr))
642-
ptr = nil
643-
}
644-
}
645-
646-
func (r FvmMachineExecuteResponse) copy() FvmMachineExecuteResponseGo {
647-
return FvmMachineExecuteResponseGo{
648-
ExitCode: uint64(r.exit_code),
649-
ReturnVal: (*SliceBoxedUint8)(&r.return_val).copy(),
650-
GasUsed: uint64(r.gas_used),
651-
PenaltyHi: uint64(r.penalty_hi),
652-
PenaltyLo: uint64(r.penalty_lo),
653-
MinerTipHi: uint64(r.miner_tip_hi),
654-
MinerTipLo: uint64(r.miner_tip_lo),
655-
BaseFeeBurnHi: uint64(r.base_fee_burn_hi),
656-
BaseFeeBurnLo: uint64(r.base_fee_burn_lo),
657-
OverEstimationBurnHi: uint64(r.over_estimation_burn_hi),
658-
OverEstimationBurnLo: uint64(r.over_estimation_burn_lo),
659-
RefundHi: uint64(r.refund_hi),
660-
RefundLo: uint64(r.refund_lo),
661-
GasRefund: int64(r.gas_refund),
662-
GasBurned: int64(r.gas_burned),
663-
ExecTrace: (*SliceBoxedUint8)(&r.exec_trace).copy(),
664-
FailureInfo: string((*SliceBoxedUint8)(&r.failure_info).slice()),
665-
Events: (*SliceBoxedUint8)(&r.events).copy(),
666-
EventsRoot: (*SliceBoxedUint8)(&r.events_root).copy(),
667-
}
668-
}
613+
// FVM helpers moved to types_fvm.go

cgo/types_fvm.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
//go:build fvm
2+
3+
package cgo
4+
5+
/*
6+
#cgo LDFLAGS: -L${SRCDIR}/..
7+
#cgo pkg-config: ${SRCDIR}/../filcrypto.pc
8+
#include "../filcrypto.h"
9+
#include <stdlib.h>
10+
*/
11+
import "C"
12+
13+
type FvmRegisteredVersion C.FvmRegisteredVersion_t
14+
15+
type FvmMachine C.InnerFvmMachine_t
16+
type FvmMachineExecuteResponse C.FvmMachineExecuteResponse_t
17+
18+
type resultFvmMachine C.Result_InnerFvmMachine_ptr_t
19+
type resultFvmMachineExecuteResponse C.Result_FvmMachineExecuteResponse_t
20+
21+
func (ptr *resultFvmMachineExecuteResponse) statusCode() FCPResponseStatus {
22+
return FCPResponseStatus(ptr.status_code)
23+
}
24+
25+
func (ptr *resultFvmMachineExecuteResponse) errorMsg() *SliceBoxedUint8 {
26+
return (*SliceBoxedUint8)(&ptr.error_msg)
27+
}
28+
29+
func (ptr *resultFvmMachineExecuteResponse) destroy() {
30+
if ptr != nil {
31+
C.destroy_fvm_machine_execute_response((*C.Result_FvmMachineExecuteResponse_t)(ptr))
32+
ptr = nil
33+
}
34+
}
35+
36+
func (ptr *resultFvmMachine) statusCode() FCPResponseStatus {
37+
return FCPResponseStatus(ptr.status_code)
38+
}
39+
40+
func (ptr *resultFvmMachine) errorMsg() *SliceBoxedUint8 {
41+
return (*SliceBoxedUint8)(&ptr.error_msg)
42+
}
43+
44+
func (ptr *resultFvmMachine) destroy() {
45+
if ptr != nil {
46+
C.destroy_create_fvm_machine_response((*C.Result_InnerFvmMachine_ptr_t)(ptr))
47+
ptr = nil
48+
}
49+
}
50+
51+
func (ptr *FvmMachine) Destroy() {
52+
if ptr != nil {
53+
C.drop_fvm_machine((*C.InnerFvmMachine_t)(ptr))
54+
ptr = nil
55+
}
56+
}
57+
58+
func (r FvmMachineExecuteResponse) copy() FvmMachineExecuteResponseGo {
59+
return FvmMachineExecuteResponseGo{
60+
ExitCode: uint64(r.exit_code),
61+
ReturnVal: (*SliceBoxedUint8)(&r.return_val).copy(),
62+
GasUsed: uint64(r.gas_used),
63+
PenaltyHi: uint64(r.penalty_hi),
64+
PenaltyLo: uint64(r.penalty_lo),
65+
MinerTipHi: uint64(r.miner_tip_hi),
66+
MinerTipLo: uint64(r.miner_tip_lo),
67+
BaseFeeBurnHi: uint64(r.base_fee_burn_hi),
68+
BaseFeeBurnLo: uint64(r.base_fee_burn_lo),
69+
OverEstimationBurnHi: uint64(r.over_estimation_burn_hi),
70+
OverEstimationBurnLo: uint64(r.over_estimation_burn_lo),
71+
RefundHi: uint64(r.refund_hi),
72+
RefundLo: uint64(r.refund_lo),
73+
GasRefund: int64(r.gas_refund),
74+
GasBurned: int64(r.gas_burned),
75+
ExecTrace: (*SliceBoxedUint8)(&r.exec_trace).copy(),
76+
FailureInfo: string((*SliceBoxedUint8)(&r.failure_info).slice()),
77+
Events: (*SliceBoxedUint8)(&r.events).copy(),
78+
EventsRoot: (*SliceBoxedUint8)(&r.events_root).copy(),
79+
}
80+
}

fvm.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
//go:build cgo && (amd64 || arm64 || riscv64)
1+
//go:build cgo && (amd64 || arm64 || riscv64) && fvm
22
// +build cgo
33
// +build amd64 arm64 riscv64
4+
// +build fvm
45

56
package ffi
67

fvm_stub.go

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
//go:build !fvm
2+
3+
package ffi
4+
5+
import (
6+
"context"
7+
"errors"
8+
9+
"github.com/filecoin-project/filecoin-ffi/cgo"
10+
"github.com/filecoin-project/go-state-types/abi"
11+
"github.com/filecoin-project/go-state-types/big"
12+
"github.com/filecoin-project/go-state-types/network"
13+
"github.com/ipfs/go-cid"
14+
"golang.org/x/xerrors"
15+
)
16+
17+
type FVM struct{}
18+
19+
type FVMOpts struct {
20+
FVMVersion uint64
21+
Externs cgo.Externs
22+
23+
Epoch abi.ChainEpoch
24+
Timestamp uint64
25+
ChainID uint64
26+
BaseFee abi.TokenAmount
27+
BaseCircSupply abi.TokenAmount
28+
NetworkVersion network.Version
29+
StateBase cid.Cid
30+
Tracing bool
31+
FlushAllBlocks bool
32+
33+
Debug bool
34+
ActorRedirect cid.Cid
35+
}
36+
37+
func CreateFVM(opts *FVMOpts) (*FVM, error) {
38+
return nil, errors.New("FVM support not built in this binary")
39+
}
40+
41+
func (f *FVM) ApplyMessage(_ []byte, _ uint) (*ApplyRet, error) {
42+
return nil, errors.New("FVM support not built in this binary")
43+
}
44+
45+
func (f *FVM) ApplyImplicitMessage(_ []byte) (*ApplyRet, error) {
46+
return nil, errors.New("FVM support not built in this binary")
47+
}
48+
49+
func (f *FVM) Flush() (cid.Cid, error) {
50+
return cid.Undef, errors.New("FVM support not built in this binary")
51+
}
52+
53+
// Minimal stubs to satisfy references
54+
type ApplyRet struct {
55+
Return []byte
56+
ExitCode uint64
57+
GasUsed int64
58+
MinerPenalty abi.TokenAmount
59+
MinerTip abi.TokenAmount
60+
BaseFeeBurn abi.TokenAmount
61+
OverEstimationBurn abi.TokenAmount
62+
Refund abi.TokenAmount
63+
GasRefund int64
64+
GasBurned int64
65+
ExecTraceBytes []byte
66+
FailureInfo string
67+
EventsRoot *cid.Cid
68+
EventsBytes []byte
69+
}
70+
71+
// Ensure cgo.Externs referenced to avoid unused import when stubbed
72+
var _ = func() any { return context.TODO() }
73+
74+
// splitBigInt splits a big.Int into high and low uint64 values.
75+
// This is used by tests and needs to be available even when FVM is not built.
76+
func splitBigInt(i big.Int) (hi uint64, lo uint64, err error) {
77+
if i.Sign() < 0 {
78+
return 0, 0, xerrors.Errorf("negative number: %s", i)
79+
}
80+
words := i.Bits()
81+
switch len(words) {
82+
case 2:
83+
hi = uint64(words[1])
84+
fallthrough
85+
case 1:
86+
lo = uint64(words[0])
87+
case 0:
88+
default:
89+
return 0, 0, xerrors.Errorf("exceeds max bigint size: %s", i)
90+
}
91+
return hi, lo, nil
92+
}

install-filcrypto

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -232,12 +232,24 @@ build_from_source() {
232232
use_fixed_rows_to_discard=",fixed-rows-to-discard"
233233
fi
234234

235-
additional_flags=""
236-
# Add feature specific rust flags as needed here.
235+
# Collect features into an array, stripping leading commas as we go
236+
features=()
237+
[ -n "${use_multicore_sdr}" ] && features+=("${use_multicore_sdr}")
238+
239+
[ -n "${gpu_flags}" ] && features+=("${gpu_flags#,}")
240+
[ "${FFI_DISABLE_FVM}" != "1" ] && features+=("fvm")
241+
[ -n "${use_fixed_rows_to_discard}" ] && features+=("${use_fixed_rows_to_discard#,}")
237242
if [ "${FFI_USE_BLST_PORTABLE}" == "1" ] || [ "${FFI_PORTABLE}" == "1" ]; then
238-
additional_flags="${additional_flags} --no-default-features --features ${use_multicore_sdr},blst-portable${gpu_flags}${use_fixed_rows_to_discard}"
243+
features+=("blst-portable")
244+
fi
245+
246+
# Join features with commas
247+
feature_list=$(IFS=','; printf '%s' "${features[*]}")
248+
249+
if [ -n "${feature_list}" ]; then
250+
additional_flags="--no-default-features --features ${feature_list}"
239251
else
240-
additional_flags="${additional_flags} --no-default-features --features ${use_multicore_sdr}${gpu_flags}${use_fixed_rows_to_discard}"
252+
additional_flags="--no-default-features"
241253
fi
242254

243255
echo "Using additional build flags: ${additional_flags}"

0 commit comments

Comments
 (0)