Merge pull request #10153 from filecoin-project/maciej/merge-hyperspace
build: Merge release/v1.20.0 to Hyperspace branch
This commit is contained in:
@@ -426,6 +426,10 @@ jobs:
|
||||
steps:
|
||||
- setup_remote_docker
|
||||
- checkout
|
||||
- git_fetch_all_tags
|
||||
- run: git submodule sync
|
||||
- run: git submodule update --init
|
||||
|
||||
- docker/check:
|
||||
docker-username: DOCKERHUB_USERNAME
|
||||
docker-password: DOCKERHUB_PASSWORD
|
||||
@@ -473,7 +477,7 @@ jobs:
|
||||
- run:
|
||||
name: Docker push
|
||||
command: |
|
||||
docker push filecoin/<<parameters.image>>:<<parameters.channel>>
|
||||
docker push filecoin/<<parameters.image>>:<<parameters.channel>>-<<parameters.network>>
|
||||
if [[ ! -z $CIRCLE_SHA ]]; then
|
||||
docker image tag filecoin/<<parameters.image>>:<<parameters.channel>>-<<parameters.network>> filecoin/<<parameters.image>>:"${CIRCLE_SHA:0:7}"-<<parameters.network>>
|
||||
docker push filecoin/<<parameters.image>>:"${CIRCLE_SHA:0:7}"-<<parameters.network>>
|
||||
|
||||
@@ -426,6 +426,10 @@ jobs:
|
||||
steps:
|
||||
- setup_remote_docker
|
||||
- checkout
|
||||
- git_fetch_all_tags
|
||||
- run: git submodule sync
|
||||
- run: git submodule update --init
|
||||
|
||||
- docker/check:
|
||||
docker-username: DOCKERHUB_USERNAME
|
||||
docker-password: DOCKERHUB_PASSWORD
|
||||
@@ -473,7 +477,7 @@ jobs:
|
||||
- run:
|
||||
name: Docker push
|
||||
command: |
|
||||
docker push filecoin/<<parameters.image>>:<<parameters.channel>>
|
||||
docker push filecoin/<<parameters.image>>:<<parameters.channel>>-<<parameters.network>>
|
||||
if [["[[ ! -z $CIRCLE_SHA ]]"]]; then
|
||||
docker image tag filecoin/<<parameters.image>>:<<parameters.channel>>-<<parameters.network>> filecoin/<<parameters.image>>:"${CIRCLE_SHA:0:7}"-<<parameters.network>>
|
||||
docker push filecoin/<<parameters.image>>:"${CIRCLE_SHA:0:7}"-<<parameters.network>>
|
||||
|
||||
@@ -13,10 +13,14 @@ name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
branches:
|
||||
- master
|
||||
- 'release/*'
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ master ]
|
||||
branches:
|
||||
- master
|
||||
- 'release/*'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
@@ -33,17 +37,17 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- uses: actions/setup-go@v1
|
||||
- uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '1.18.8'
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
languages: go
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
@@ -52,7 +56,7 @@ jobs:
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
@@ -66,4 +70,4 @@ jobs:
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
||||
uses: github/codeql-action/analyze@v2
|
||||
|
||||
+5
-3
@@ -1,6 +1,3 @@
|
||||
/AppDir
|
||||
/appimage-builder-cache
|
||||
*.AppImage
|
||||
/lotus
|
||||
/lotus-miner
|
||||
/lotus-worker
|
||||
@@ -50,3 +47,8 @@ build/builtin-actors/v*
|
||||
build/builtin-actors/*.car
|
||||
|
||||
dist/
|
||||
|
||||
|
||||
# The following files are checked into git and result
|
||||
# in dirty git state if removed from the docker context
|
||||
!extern/filecoin-ffi/rust/filecoin.pc
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" viewBox="0 0 127 127" xml:space="preserve" enable-background="new 0 0 127 127"><style type="text/css">.st0{fill:#00d2d6}.st1{fill:#fff}</style><g><path class="st0" d="M63.5,127C28.5,127.1-0.2,98.4,0,63.2C0.2,28.3,28.6-0.2,63.9,0c34.8,0.2,63.3,28.7,63.1,64 C126.7,98.7,98.5,127.1,63.5,127z M71.4,57.6c5.5,0.8,11,1.5,16.5,2.3c0.5-1.7,0.9-3.1,1.3-4.7c-5.7-0.8-11.2-1.7-17.1-2.5 c2-7,3.7-13.7,5.8-20.2c0.7-2.2,2.3-4.2,3.9-5.9c2.1-2.2,5-1.7,6.8,0.7c0.7,1,1.4,2.1,2.3,2.9c1.1,1.1,2.8,1.6,4,0.6 c0.8-0.7,0.7-2.4,0.8-3.6c0-0.5-0.6-1.1-1-1.6c-2-2.3-4.7-3.1-7.5-3.2c-6.3-0.3-10.9,3-14.5,7.8c-3.5,4.8-5.1,10.5-6.8,16.2 c-0.5,1.6-0.9,3.3-1.4,5.1c-6.2-0.9-12.1-1.7-18.2-2.6c-0.2,1.6-0.4,3.2-0.6,4.8c6,0.9,11.8,1.8,17.8,2.7c-0.8,3.4-1.5,6.5-2.3,9.7 c-5.8-0.8-11.4-1.6-17-2.4c-0.2,1.8-0.4,3.2-0.6,4.8c5.6,0.9,11,1.7,16.5,2.5c0,0.6,0.1,1,0,1.3c-1.7,7.4-3.4,14.8-5.3,22.2 c-0.9,3.5-2.4,6.9-5.3,9.3c-2.4,2-5,1.7-6.8-0.8c-0.8-1.1-1.5-2.5-2.6-3.3c-0.8-0.6-2.5-0.9-3.1-0.5c-0.9,0.7-1.5,2.2-1.4,3.3 c0.1,1,1,2.2,1.9,2.8c3,2.3,6.5,2.6,10,1.9c5.9-1.2,10.1-4.9,12.7-10.1c2-4.1,3.6-8.5,5-12.9c1.3-4,2.2-8,3.3-12.2 c5.8,0.8,11.5,1.7,17.3,2.5c0.5-1.7,0.9-3.2,1.4-4.8c-6.1-0.9-11.9-1.7-17.7-2.6C70.1,64,70.7,60.9,71.4,57.6z"/><path class="st1" d="M71.4,57.6c-0.7,3.3-1.3,6.4-2,9.8c5.9,0.9,11.7,1.7,17.7,2.6c-0.5,1.6-0.9,3.1-1.4,4.8 c-5.8-0.8-11.5-1.7-17.3-2.5c-1.1,4.2-2,8.3-3.3,12.2c-1.4,4.4-3,8.7-5,12.9c-2.6,5.2-6.8,8.9-12.7,10.1c-3.5,0.7-7,0.4-10-1.9 c-0.9-0.7-1.8-1.8-1.9-2.8c-0.1-1.1,0.5-2.7,1.4-3.3c0.6-0.5,2.3-0.1,3.1,0.5c1.1,0.8,1.8,2.1,2.6,3.3c1.8,2.5,4.4,2.9,6.8,0.8 c2.9-2.5,4.4-5.8,5.3-9.3c1.9-7.3,3.6-14.8,5.3-22.2c0.1-0.3,0-0.7,0-1.3c-5.4-0.8-10.8-1.7-16.5-2.5c0.2-1.6,0.4-3,0.6-4.8 c5.6,0.8,11.1,1.6,17,2.4c0.8-3.2,1.5-6.4,2.3-9.7c-6-0.9-11.7-1.8-17.8-2.7c0.2-1.6,0.4-3.2,0.6-4.8c6.1,0.9,12,1.7,18.2,2.6 c0.5-1.8,0.9-3.5,1.4-5.1c1.7-5.6,3.2-11.3,6.8-16.2c3.6-4.9,8.1-8.1,14.5-7.8c2.8,0.1,5.5,0.9,7.5,3.2c0.4,0.5,1,1.1,1,1.6 c-0.1,1.2,0,2.9-0.8,3.6c-1.1,1.1-2.8,0.5-4-0.6c-0.9-0.9-1.6-1.9-2.3-2.9c-1.8-2.4-4.7-2.9-6.8-0.7c-1.6,1.7-3.2,3.7-3.9,5.9 C75.7,39.4,74,46,72,53c5.9,0.9,11.4,1.7,17.1,2.5c-0.5,1.6-0.9,3.1-1.3,4.7C82.3,59.1,76.9,58.3,71.4,57.6z"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 2.2 KiB |
@@ -1,71 +0,0 @@
|
||||
version: 1
|
||||
AppDir:
|
||||
path: ./AppDir
|
||||
app_info:
|
||||
id: io.filecoin.lotus
|
||||
name: Lotus
|
||||
icon: icon
|
||||
version: latest
|
||||
exec: usr/bin/lotus
|
||||
exec_args: $@
|
||||
apt:
|
||||
arch: amd64
|
||||
allow_unauthenticated: true
|
||||
sources:
|
||||
- sourceline: deb http://archive.ubuntu.com/ubuntu/ focal main restricted
|
||||
- sourceline: deb http://archive.ubuntu.com/ubuntu/ focal-updates main restricted
|
||||
- sourceline: deb http://archive.ubuntu.com/ubuntu/ focal universe
|
||||
- sourceline: deb http://archive.ubuntu.com/ubuntu/ focal-updates universe
|
||||
- sourceline: deb http://archive.ubuntu.com/ubuntu/ focal multiverse
|
||||
- sourceline: deb http://archive.ubuntu.com/ubuntu/ focal-updates multiverse
|
||||
- sourceline: deb http://archive.ubuntu.com/ubuntu/ focal-backports main restricted
|
||||
universe multiverse
|
||||
- sourceline: deb http://security.ubuntu.com/ubuntu focal-security main restricted
|
||||
- sourceline: deb http://security.ubuntu.com/ubuntu focal-security universe
|
||||
- sourceline: deb http://security.ubuntu.com/ubuntu focal-security multiverse
|
||||
- sourceline: deb https://cli-assets.heroku.com/apt ./
|
||||
- sourceline: deb http://ppa.launchpad.net/openjdk-r/ppa/ubuntu focal main
|
||||
- sourceline: deb http://ppa.launchpad.net/git-core/ppa/ubuntu focal main
|
||||
- sourceline: deb http://archive.canonical.com/ubuntu focal partner
|
||||
include:
|
||||
- ocl-icd-libopencl1
|
||||
- libhwloc15
|
||||
exclude: []
|
||||
files:
|
||||
include:
|
||||
- /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
|
||||
- /usr/lib/x86_64-linux-gnu/libpthread-2.31.so
|
||||
- /usr/lib/x86_64-linux-gnu/libm-2.31.so
|
||||
- /usr/lib/x86_64-linux-gnu/libdl-2.31.so
|
||||
- /usr/lib/x86_64-linux-gnu/libc-2.31.so
|
||||
- /usr/lib/x86_64-linux-gnu/libudev.so.1.6.17
|
||||
exclude:
|
||||
- usr/share/man
|
||||
- usr/share/doc/*/README.*
|
||||
- usr/share/doc/*/changelog.*
|
||||
- usr/share/doc/*/NEWS.*
|
||||
- usr/share/doc/*/TODO.*
|
||||
test:
|
||||
fedora:
|
||||
image: appimagecrafters/tests-env:fedora-30
|
||||
command: ./AppRun
|
||||
use_host_x: false
|
||||
debian:
|
||||
image: appimagecrafters/tests-env:debian-stable
|
||||
command: ./AppRun
|
||||
use_host_x: false
|
||||
arch:
|
||||
image: appimagecrafters/tests-env:archlinux-latest
|
||||
command: ./AppRun
|
||||
use_host_x: false
|
||||
centos:
|
||||
image: appimagecrafters/tests-env:centos-7
|
||||
command: ./AppRun
|
||||
use_host_x: false
|
||||
ubuntu:
|
||||
image: appimagecrafters/tests-env:ubuntu-xenial
|
||||
command: ./AppRun
|
||||
use_host_x: false
|
||||
AppImage:
|
||||
arch: x86_64
|
||||
|
||||
@@ -33,6 +33,8 @@ RUN set -eux; \
|
||||
COPY ./ /opt/filecoin
|
||||
WORKDIR /opt/filecoin
|
||||
|
||||
RUN scripts/docker-git-state-check.sh
|
||||
|
||||
### make configurable filecoin-ffi build
|
||||
ARG FFI_BUILD_FROM_SOURCE=0
|
||||
ENV FFI_BUILD_FROM_SOURCE=${FFI_BUILD_FROM_SOURCE}
|
||||
|
||||
+11
-1
@@ -16,6 +16,7 @@ import (
|
||||
datatransfer "github.com/filecoin-project/go-data-transfer"
|
||||
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
|
||||
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
||||
"github.com/filecoin-project/go-jsonrpc"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
"github.com/filecoin-project/go-state-types/builtin/v8/paych"
|
||||
@@ -831,11 +832,14 @@ type FullNode interface {
|
||||
// - logs: notify new event logs that match a criteria
|
||||
// params contains additional parameters used with the log event type
|
||||
// The client will receive a stream of EthSubscriptionResponse values until EthUnsubscribe is called.
|
||||
EthSubscribe(ctx context.Context, eventType string, params *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error) //perm:write
|
||||
EthSubscribe(ctx context.Context, params jsonrpc.RawParams) (ethtypes.EthSubscriptionID, error) //perm:write
|
||||
|
||||
// Unsubscribe from a websocket subscription
|
||||
EthUnsubscribe(ctx context.Context, id ethtypes.EthSubscriptionID) (bool, error) //perm:write
|
||||
|
||||
// Returns the client version
|
||||
Web3ClientVersion(ctx context.Context) (string, error) //perm:read
|
||||
|
||||
// CreateBackup creates node backup onder the specified file name. The
|
||||
// method requires that the lotus daemon is running with the
|
||||
// LOTUS_BACKUP_BASE_PATH environment variable set to some path, and that
|
||||
@@ -846,6 +850,12 @@ type FullNode interface {
|
||||
RaftLeader(ctx context.Context) (peer.ID, error) //perm:read
|
||||
}
|
||||
|
||||
// reverse interface to the client, called after EthSubscribe
|
||||
type EthSubscriber interface {
|
||||
// note: the parameter is ethtypes.EthSubscriptionResponse serialized as json object
|
||||
EthSubscription(ctx context.Context, r jsonrpc.RawParams) error //rpc_method:eth_subscription notify:true
|
||||
}
|
||||
|
||||
type StorageAsk struct {
|
||||
Response *storagemarket.StorageAsk
|
||||
|
||||
|
||||
+2
-1
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/ipfs/go-cid"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-jsonrpc"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/builtin/v9/miner"
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
@@ -102,6 +103,6 @@ type Gateway interface {
|
||||
EthNewBlockFilter(ctx context.Context) (ethtypes.EthFilterID, error)
|
||||
EthNewPendingTransactionFilter(ctx context.Context) (ethtypes.EthFilterID, error)
|
||||
EthUninstallFilter(ctx context.Context, id ethtypes.EthFilterID) (bool, error)
|
||||
EthSubscribe(ctx context.Context, eventType string, params *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error)
|
||||
EthSubscribe(ctx context.Context, params jsonrpc.RawParams) (ethtypes.EthSubscriptionID, error)
|
||||
EthUnsubscribe(ctx context.Context, id ethtypes.EthSubscriptionID) (bool, error)
|
||||
}
|
||||
|
||||
@@ -35,10 +35,10 @@ func NewFullNodeRPCV0(ctx context.Context, addr string, requestHeader http.Heade
|
||||
}
|
||||
|
||||
// NewFullNodeRPCV1 creates a new http jsonrpc client.
|
||||
func NewFullNodeRPCV1(ctx context.Context, addr string, requestHeader http.Header) (api.FullNode, jsonrpc.ClientCloser, error) {
|
||||
func NewFullNodeRPCV1(ctx context.Context, addr string, requestHeader http.Header, opts ...jsonrpc.Option) (api.FullNode, jsonrpc.ClientCloser, error) {
|
||||
var res v1api.FullNodeStruct
|
||||
closer, err := jsonrpc.NewMergeClient(ctx, addr, "Filecoin",
|
||||
api.GetInternalStructs(&res), requestHeader, jsonrpc.WithErrors(api.RPCErrors))
|
||||
api.GetInternalStructs(&res), requestHeader, append([]jsonrpc.Option{jsonrpc.WithErrors(api.RPCErrors)}, opts...)...)
|
||||
|
||||
return &res, closer, err
|
||||
}
|
||||
|
||||
@@ -41,4 +41,6 @@ func CreateEthRPCAliases(as apitypes.Aliaser) {
|
||||
|
||||
as.AliasMethod("net_version", "Filecoin.NetVersion")
|
||||
as.AliasMethod("net_listening", "Filecoin.NetListening")
|
||||
|
||||
as.AliasMethod("web3_clientVersion", "Filecoin.Web3ClientVersion")
|
||||
}
|
||||
|
||||
+21
-5
@@ -23,6 +23,7 @@ import (
|
||||
bitfield "github.com/filecoin-project/go-bitfield"
|
||||
datatransfer "github.com/filecoin-project/go-data-transfer"
|
||||
retrievalmarket "github.com/filecoin-project/go-fil-markets/retrievalmarket"
|
||||
jsonrpc "github.com/filecoin-project/go-jsonrpc"
|
||||
auth "github.com/filecoin-project/go-jsonrpc/auth"
|
||||
abi "github.com/filecoin-project/go-state-types/abi"
|
||||
big "github.com/filecoin-project/go-state-types/big"
|
||||
@@ -1388,18 +1389,18 @@ func (mr *MockFullNodeMockRecorder) EthSendRawTransaction(arg0, arg1 interface{}
|
||||
}
|
||||
|
||||
// EthSubscribe mocks base method.
|
||||
func (m *MockFullNode) EthSubscribe(arg0 context.Context, arg1 string, arg2 *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error) {
|
||||
func (m *MockFullNode) EthSubscribe(arg0 context.Context, arg1 jsonrpc.RawParams) (ethtypes.EthSubscriptionID, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "EthSubscribe", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].(<-chan ethtypes.EthSubscriptionResponse)
|
||||
ret := m.ctrl.Call(m, "EthSubscribe", arg0, arg1)
|
||||
ret0, _ := ret[0].(ethtypes.EthSubscriptionID)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// EthSubscribe indicates an expected call of EthSubscribe.
|
||||
func (mr *MockFullNodeMockRecorder) EthSubscribe(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
func (mr *MockFullNodeMockRecorder) EthSubscribe(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthSubscribe", reflect.TypeOf((*MockFullNode)(nil).EthSubscribe), arg0, arg1, arg2)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthSubscribe", reflect.TypeOf((*MockFullNode)(nil).EthSubscribe), arg0, arg1)
|
||||
}
|
||||
|
||||
// EthUninstallFilter mocks base method.
|
||||
@@ -4096,3 +4097,18 @@ func (mr *MockFullNodeMockRecorder) WalletVerify(arg0, arg1, arg2, arg3 interfac
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WalletVerify", reflect.TypeOf((*MockFullNode)(nil).WalletVerify), arg0, arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
// Web3ClientVersion mocks base method.
|
||||
func (m *MockFullNode) Web3ClientVersion(arg0 context.Context) (string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "Web3ClientVersion", arg0)
|
||||
ret0, _ := ret[0].(string)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// Web3ClientVersion indicates an expected call of Web3ClientVersion.
|
||||
func (mr *MockFullNodeMockRecorder) Web3ClientVersion(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Web3ClientVersion", reflect.TypeOf((*MockFullNode)(nil).Web3ClientVersion), arg0)
|
||||
}
|
||||
|
||||
+610
-553
File diff suppressed because it is too large
Load Diff
+228
-224
@@ -39,383 +39,385 @@ type FullNodeStruct struct {
|
||||
|
||||
NetStruct
|
||||
|
||||
Internal struct {
|
||||
BeaconGetEntry func(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) `perm:"read"`
|
||||
Internal FullNodeMethods
|
||||
}
|
||||
|
||||
ChainDeleteObj func(p0 context.Context, p1 cid.Cid) error `perm:"admin"`
|
||||
type FullNodeMethods struct {
|
||||
BeaconGetEntry func(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) `perm:"read"`
|
||||
|
||||
ChainExport func(p0 context.Context, p1 abi.ChainEpoch, p2 bool, p3 types.TipSetKey) (<-chan []byte, error) `perm:"read"`
|
||||
ChainDeleteObj func(p0 context.Context, p1 cid.Cid) error `perm:"admin"`
|
||||
|
||||
ChainGetBlock func(p0 context.Context, p1 cid.Cid) (*types.BlockHeader, error) `perm:"read"`
|
||||
ChainExport func(p0 context.Context, p1 abi.ChainEpoch, p2 bool, p3 types.TipSetKey) (<-chan []byte, error) `perm:"read"`
|
||||
|
||||
ChainGetBlockMessages func(p0 context.Context, p1 cid.Cid) (*api.BlockMessages, error) `perm:"read"`
|
||||
ChainGetBlock func(p0 context.Context, p1 cid.Cid) (*types.BlockHeader, error) `perm:"read"`
|
||||
|
||||
ChainGetGenesis func(p0 context.Context) (*types.TipSet, error) `perm:"read"`
|
||||
ChainGetBlockMessages func(p0 context.Context, p1 cid.Cid) (*api.BlockMessages, error) `perm:"read"`
|
||||
|
||||
ChainGetMessage func(p0 context.Context, p1 cid.Cid) (*types.Message, error) `perm:"read"`
|
||||
ChainGetGenesis func(p0 context.Context) (*types.TipSet, error) `perm:"read"`
|
||||
|
||||
ChainGetMessagesInTipset func(p0 context.Context, p1 types.TipSetKey) ([]api.Message, error) `perm:"read"`
|
||||
ChainGetMessage func(p0 context.Context, p1 cid.Cid) (*types.Message, error) `perm:"read"`
|
||||
|
||||
ChainGetNode func(p0 context.Context, p1 string) (*api.IpldObject, error) `perm:"read"`
|
||||
ChainGetMessagesInTipset func(p0 context.Context, p1 types.TipSetKey) ([]api.Message, error) `perm:"read"`
|
||||
|
||||
ChainGetParentMessages func(p0 context.Context, p1 cid.Cid) ([]api.Message, error) `perm:"read"`
|
||||
ChainGetNode func(p0 context.Context, p1 string) (*api.IpldObject, error) `perm:"read"`
|
||||
|
||||
ChainGetParentReceipts func(p0 context.Context, p1 cid.Cid) ([]*types.MessageReceipt, error) `perm:"read"`
|
||||
ChainGetParentMessages func(p0 context.Context, p1 cid.Cid) ([]api.Message, error) `perm:"read"`
|
||||
|
||||
ChainGetPath func(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey) ([]*api.HeadChange, error) `perm:"read"`
|
||||
ChainGetParentReceipts func(p0 context.Context, p1 cid.Cid) ([]*types.MessageReceipt, error) `perm:"read"`
|
||||
|
||||
ChainGetRandomnessFromBeacon func(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) `perm:"read"`
|
||||
ChainGetPath func(p0 context.Context, p1 types.TipSetKey, p2 types.TipSetKey) ([]*api.HeadChange, error) `perm:"read"`
|
||||
|
||||
ChainGetRandomnessFromTickets func(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) `perm:"read"`
|
||||
ChainGetRandomnessFromBeacon func(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) `perm:"read"`
|
||||
|
||||
ChainGetTipSet func(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) `perm:"read"`
|
||||
ChainGetRandomnessFromTickets func(p0 context.Context, p1 types.TipSetKey, p2 crypto.DomainSeparationTag, p3 abi.ChainEpoch, p4 []byte) (abi.Randomness, error) `perm:"read"`
|
||||
|
||||
ChainGetTipSetByHeight func(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) `perm:"read"`
|
||||
ChainGetTipSet func(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) `perm:"read"`
|
||||
|
||||
ChainHasObj func(p0 context.Context, p1 cid.Cid) (bool, error) `perm:"read"`
|
||||
ChainGetTipSetByHeight func(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) `perm:"read"`
|
||||
|
||||
ChainHead func(p0 context.Context) (*types.TipSet, error) `perm:"read"`
|
||||
ChainHasObj func(p0 context.Context, p1 cid.Cid) (bool, error) `perm:"read"`
|
||||
|
||||
ChainNotify func(p0 context.Context) (<-chan []*api.HeadChange, error) `perm:"read"`
|
||||
ChainHead func(p0 context.Context) (*types.TipSet, error) `perm:"read"`
|
||||
|
||||
ChainPutObj func(p0 context.Context, p1 blocks.Block) error ``
|
||||
ChainNotify func(p0 context.Context) (<-chan []*api.HeadChange, error) `perm:"read"`
|
||||
|
||||
ChainReadObj func(p0 context.Context, p1 cid.Cid) ([]byte, error) `perm:"read"`
|
||||
ChainPutObj func(p0 context.Context, p1 blocks.Block) error ``
|
||||
|
||||
ChainSetHead func(p0 context.Context, p1 types.TipSetKey) error `perm:"admin"`
|
||||
ChainReadObj func(p0 context.Context, p1 cid.Cid) ([]byte, error) `perm:"read"`
|
||||
|
||||
ChainStatObj func(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (api.ObjStat, error) `perm:"read"`
|
||||
ChainSetHead func(p0 context.Context, p1 types.TipSetKey) error `perm:"admin"`
|
||||
|
||||
ChainTipSetWeight func(p0 context.Context, p1 types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
ChainStatObj func(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (api.ObjStat, error) `perm:"read"`
|
||||
|
||||
ClientCalcCommP func(p0 context.Context, p1 string) (*api.CommPRet, error) `perm:"write"`
|
||||
ChainTipSetWeight func(p0 context.Context, p1 types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
|
||||
ClientCancelDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"`
|
||||
ClientCalcCommP func(p0 context.Context, p1 string) (*api.CommPRet, error) `perm:"write"`
|
||||
|
||||
ClientCancelRetrievalDeal func(p0 context.Context, p1 retrievalmarket.DealID) error `perm:"write"`
|
||||
ClientCancelDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"`
|
||||
|
||||
ClientDataTransferUpdates func(p0 context.Context) (<-chan api.DataTransferChannel, error) `perm:"write"`
|
||||
ClientCancelRetrievalDeal func(p0 context.Context, p1 retrievalmarket.DealID) error `perm:"write"`
|
||||
|
||||
ClientDealPieceCID func(p0 context.Context, p1 cid.Cid) (api.DataCIDSize, error) `perm:"read"`
|
||||
ClientDataTransferUpdates func(p0 context.Context) (<-chan api.DataTransferChannel, error) `perm:"write"`
|
||||
|
||||
ClientDealSize func(p0 context.Context, p1 cid.Cid) (api.DataSize, error) `perm:"read"`
|
||||
ClientDealPieceCID func(p0 context.Context, p1 cid.Cid) (api.DataCIDSize, error) `perm:"read"`
|
||||
|
||||
ClientFindData func(p0 context.Context, p1 cid.Cid, p2 *cid.Cid) ([]api.QueryOffer, error) `perm:"read"`
|
||||
ClientDealSize func(p0 context.Context, p1 cid.Cid) (api.DataSize, error) `perm:"read"`
|
||||
|
||||
ClientGenCar func(p0 context.Context, p1 api.FileRef, p2 string) error `perm:"write"`
|
||||
ClientFindData func(p0 context.Context, p1 cid.Cid, p2 *cid.Cid) ([]api.QueryOffer, error) `perm:"read"`
|
||||
|
||||
ClientGetDealInfo func(p0 context.Context, p1 cid.Cid) (*api.DealInfo, error) `perm:"read"`
|
||||
ClientGenCar func(p0 context.Context, p1 api.FileRef, p2 string) error `perm:"write"`
|
||||
|
||||
ClientGetDealStatus func(p0 context.Context, p1 uint64) (string, error) `perm:"read"`
|
||||
ClientGetDealInfo func(p0 context.Context, p1 cid.Cid) (*api.DealInfo, error) `perm:"read"`
|
||||
|
||||
ClientGetDealUpdates func(p0 context.Context) (<-chan api.DealInfo, error) `perm:"write"`
|
||||
ClientGetDealStatus func(p0 context.Context, p1 uint64) (string, error) `perm:"read"`
|
||||
|
||||
ClientGetRetrievalUpdates func(p0 context.Context) (<-chan api.RetrievalInfo, error) `perm:"write"`
|
||||
ClientGetDealUpdates func(p0 context.Context) (<-chan api.DealInfo, error) `perm:"write"`
|
||||
|
||||
ClientHasLocal func(p0 context.Context, p1 cid.Cid) (bool, error) `perm:"write"`
|
||||
ClientGetRetrievalUpdates func(p0 context.Context) (<-chan api.RetrievalInfo, error) `perm:"write"`
|
||||
|
||||
ClientImport func(p0 context.Context, p1 api.FileRef) (*api.ImportRes, error) `perm:"admin"`
|
||||
ClientHasLocal func(p0 context.Context, p1 cid.Cid) (bool, error) `perm:"write"`
|
||||
|
||||
ClientListDataTransfers func(p0 context.Context) ([]api.DataTransferChannel, error) `perm:"write"`
|
||||
ClientImport func(p0 context.Context, p1 api.FileRef) (*api.ImportRes, error) `perm:"admin"`
|
||||
|
||||
ClientListDeals func(p0 context.Context) ([]api.DealInfo, error) `perm:"write"`
|
||||
ClientListDataTransfers func(p0 context.Context) ([]api.DataTransferChannel, error) `perm:"write"`
|
||||
|
||||
ClientListImports func(p0 context.Context) ([]api.Import, error) `perm:"write"`
|
||||
ClientListDeals func(p0 context.Context) ([]api.DealInfo, error) `perm:"write"`
|
||||
|
||||
ClientListRetrievals func(p0 context.Context) ([]api.RetrievalInfo, error) `perm:"write"`
|
||||
ClientListImports func(p0 context.Context) ([]api.Import, error) `perm:"write"`
|
||||
|
||||
ClientMinerQueryOffer func(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (api.QueryOffer, error) `perm:"read"`
|
||||
ClientListRetrievals func(p0 context.Context) ([]api.RetrievalInfo, error) `perm:"write"`
|
||||
|
||||
ClientQueryAsk func(p0 context.Context, p1 peer.ID, p2 address.Address) (*storagemarket.StorageAsk, error) `perm:"read"`
|
||||
ClientMinerQueryOffer func(p0 context.Context, p1 address.Address, p2 cid.Cid, p3 *cid.Cid) (api.QueryOffer, error) `perm:"read"`
|
||||
|
||||
ClientRemoveImport func(p0 context.Context, p1 imports.ID) error `perm:"admin"`
|
||||
ClientQueryAsk func(p0 context.Context, p1 peer.ID, p2 address.Address) (*storagemarket.StorageAsk, error) `perm:"read"`
|
||||
|
||||
ClientRestartDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"`
|
||||
ClientRemoveImport func(p0 context.Context, p1 imports.ID) error `perm:"admin"`
|
||||
|
||||
ClientRetrieve func(p0 context.Context, p1 RetrievalOrder, p2 *api.FileRef) error `perm:"admin"`
|
||||
ClientRestartDataTransfer func(p0 context.Context, p1 datatransfer.TransferID, p2 peer.ID, p3 bool) error `perm:"write"`
|
||||
|
||||
ClientRetrieveTryRestartInsufficientFunds func(p0 context.Context, p1 address.Address) error `perm:"write"`
|
||||
ClientRetrieve func(p0 context.Context, p1 RetrievalOrder, p2 *api.FileRef) error `perm:"admin"`
|
||||
|
||||
ClientRetrieveWithEvents func(p0 context.Context, p1 RetrievalOrder, p2 *api.FileRef) (<-chan marketevents.RetrievalEvent, error) `perm:"admin"`
|
||||
ClientRetrieveTryRestartInsufficientFunds func(p0 context.Context, p1 address.Address) error `perm:"write"`
|
||||
|
||||
ClientStartDeal func(p0 context.Context, p1 *api.StartDealParams) (*cid.Cid, error) `perm:"admin"`
|
||||
ClientRetrieveWithEvents func(p0 context.Context, p1 RetrievalOrder, p2 *api.FileRef) (<-chan marketevents.RetrievalEvent, error) `perm:"admin"`
|
||||
|
||||
ClientStatelessDeal func(p0 context.Context, p1 *api.StartDealParams) (*cid.Cid, error) `perm:"write"`
|
||||
ClientStartDeal func(p0 context.Context, p1 *api.StartDealParams) (*cid.Cid, error) `perm:"admin"`
|
||||
|
||||
CreateBackup func(p0 context.Context, p1 string) error `perm:"admin"`
|
||||
ClientStatelessDeal func(p0 context.Context, p1 *api.StartDealParams) (*cid.Cid, error) `perm:"write"`
|
||||
|
||||
GasEstimateFeeCap func(p0 context.Context, p1 *types.Message, p2 int64, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
CreateBackup func(p0 context.Context, p1 string) error `perm:"admin"`
|
||||
|
||||
GasEstimateGasLimit func(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (int64, error) `perm:"read"`
|
||||
GasEstimateFeeCap func(p0 context.Context, p1 *types.Message, p2 int64, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
|
||||
GasEstimateGasPremium func(p0 context.Context, p1 uint64, p2 address.Address, p3 int64, p4 types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
GasEstimateGasLimit func(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (int64, error) `perm:"read"`
|
||||
|
||||
GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) `perm:"read"`
|
||||
GasEstimateGasPremium func(p0 context.Context, p1 uint64, p2 address.Address, p3 int64, p4 types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
|
||||
MarketAddBalance func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) `perm:"sign"`
|
||||
GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) `perm:"read"`
|
||||
|
||||
MarketGetReserved func(p0 context.Context, p1 address.Address) (types.BigInt, error) `perm:"sign"`
|
||||
MarketAddBalance func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) `perm:"sign"`
|
||||
|
||||
MarketReleaseFunds func(p0 context.Context, p1 address.Address, p2 types.BigInt) error `perm:"sign"`
|
||||
MarketGetReserved func(p0 context.Context, p1 address.Address) (types.BigInt, error) `perm:"sign"`
|
||||
|
||||
MarketReserveFunds func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) `perm:"sign"`
|
||||
MarketReleaseFunds func(p0 context.Context, p1 address.Address, p2 types.BigInt) error `perm:"sign"`
|
||||
|
||||
MarketWithdraw func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) `perm:"sign"`
|
||||
MarketReserveFunds func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) `perm:"sign"`
|
||||
|
||||
MinerCreateBlock func(p0 context.Context, p1 *api.BlockTemplate) (*types.BlockMsg, error) `perm:"write"`
|
||||
MarketWithdraw func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (cid.Cid, error) `perm:"sign"`
|
||||
|
||||
MinerGetBaseInfo func(p0 context.Context, p1 address.Address, p2 abi.ChainEpoch, p3 types.TipSetKey) (*api.MiningBaseInfo, error) `perm:"read"`
|
||||
MinerCreateBlock func(p0 context.Context, p1 *api.BlockTemplate) (*types.BlockMsg, error) `perm:"write"`
|
||||
|
||||
MpoolBatchPush func(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) `perm:"write"`
|
||||
MinerGetBaseInfo func(p0 context.Context, p1 address.Address, p2 abi.ChainEpoch, p3 types.TipSetKey) (*api.MiningBaseInfo, error) `perm:"read"`
|
||||
|
||||
MpoolBatchPushMessage func(p0 context.Context, p1 []*types.Message, p2 *api.MessageSendSpec) ([]*types.SignedMessage, error) `perm:"sign"`
|
||||
MpoolBatchPush func(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) `perm:"write"`
|
||||
|
||||
MpoolBatchPushUntrusted func(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) `perm:"write"`
|
||||
MpoolBatchPushMessage func(p0 context.Context, p1 []*types.Message, p2 *api.MessageSendSpec) ([]*types.SignedMessage, error) `perm:"sign"`
|
||||
|
||||
MpoolClear func(p0 context.Context, p1 bool) error `perm:"write"`
|
||||
MpoolBatchPushUntrusted func(p0 context.Context, p1 []*types.SignedMessage) ([]cid.Cid, error) `perm:"write"`
|
||||
|
||||
MpoolGetConfig func(p0 context.Context) (*types.MpoolConfig, error) `perm:"read"`
|
||||
MpoolClear func(p0 context.Context, p1 bool) error `perm:"write"`
|
||||
|
||||
MpoolGetNonce func(p0 context.Context, p1 address.Address) (uint64, error) `perm:"read"`
|
||||
MpoolGetConfig func(p0 context.Context) (*types.MpoolConfig, error) `perm:"read"`
|
||||
|
||||
MpoolPending func(p0 context.Context, p1 types.TipSetKey) ([]*types.SignedMessage, error) `perm:"read"`
|
||||
MpoolGetNonce func(p0 context.Context, p1 address.Address) (uint64, error) `perm:"read"`
|
||||
|
||||
MpoolPush func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) `perm:"write"`
|
||||
MpoolPending func(p0 context.Context, p1 types.TipSetKey) ([]*types.SignedMessage, error) `perm:"read"`
|
||||
|
||||
MpoolPushMessage func(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec) (*types.SignedMessage, error) `perm:"sign"`
|
||||
MpoolPush func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) `perm:"write"`
|
||||
|
||||
MpoolPushUntrusted func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) `perm:"write"`
|
||||
MpoolPushMessage func(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec) (*types.SignedMessage, error) `perm:"sign"`
|
||||
|
||||
MpoolSelect func(p0 context.Context, p1 types.TipSetKey, p2 float64) ([]*types.SignedMessage, error) `perm:"read"`
|
||||
MpoolPushUntrusted func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) `perm:"write"`
|
||||
|
||||
MpoolSetConfig func(p0 context.Context, p1 *types.MpoolConfig) error `perm:"admin"`
|
||||
MpoolSelect func(p0 context.Context, p1 types.TipSetKey, p2 float64) ([]*types.SignedMessage, error) `perm:"read"`
|
||||
|
||||
MpoolSub func(p0 context.Context) (<-chan api.MpoolUpdate, error) `perm:"read"`
|
||||
MpoolSetConfig func(p0 context.Context, p1 *types.MpoolConfig) error `perm:"admin"`
|
||||
|
||||
MsigAddApprove func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (cid.Cid, error) `perm:"sign"`
|
||||
MpoolSub func(p0 context.Context) (<-chan api.MpoolUpdate, error) `perm:"read"`
|
||||
|
||||
MsigAddCancel func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (cid.Cid, error) `perm:"sign"`
|
||||
MsigAddApprove func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 bool) (cid.Cid, error) `perm:"sign"`
|
||||
|
||||
MsigAddPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) `perm:"sign"`
|
||||
MsigAddCancel func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 bool) (cid.Cid, error) `perm:"sign"`
|
||||
|
||||
MsigApprove func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (cid.Cid, error) `perm:"sign"`
|
||||
MsigAddPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) `perm:"sign"`
|
||||
|
||||
MsigApproveTxnHash func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 address.Address, p5 types.BigInt, p6 address.Address, p7 uint64, p8 []byte) (cid.Cid, error) `perm:"sign"`
|
||||
MsigApprove func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address) (cid.Cid, error) `perm:"sign"`
|
||||
|
||||
MsigCancel func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (cid.Cid, error) `perm:"sign"`
|
||||
MsigApproveTxnHash func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 address.Address, p5 types.BigInt, p6 address.Address, p7 uint64, p8 []byte) (cid.Cid, error) `perm:"sign"`
|
||||
|
||||
MsigCreate func(p0 context.Context, p1 uint64, p2 []address.Address, p3 abi.ChainEpoch, p4 types.BigInt, p5 address.Address, p6 types.BigInt) (cid.Cid, error) `perm:"sign"`
|
||||
MsigCancel func(p0 context.Context, p1 address.Address, p2 uint64, p3 address.Address, p4 types.BigInt, p5 address.Address, p6 uint64, p7 []byte) (cid.Cid, error) `perm:"sign"`
|
||||
|
||||
MsigGetAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
MsigCreate func(p0 context.Context, p1 uint64, p2 []address.Address, p3 abi.ChainEpoch, p4 types.BigInt, p5 address.Address, p6 types.BigInt) (cid.Cid, error) `perm:"sign"`
|
||||
|
||||
MsigGetPending func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*api.MsigTransaction, error) `perm:"read"`
|
||||
MsigGetAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
|
||||
MsigGetVested func(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
MsigGetPending func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*api.MsigTransaction, error) `perm:"read"`
|
||||
|
||||
MsigGetVestingSchedule func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MsigVesting, error) `perm:"read"`
|
||||
MsigGetVested func(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
|
||||
MsigPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (cid.Cid, error) `perm:"sign"`
|
||||
MsigGetVestingSchedule func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MsigVesting, error) `perm:"read"`
|
||||
|
||||
MsigRemoveSigner func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) `perm:"sign"`
|
||||
MsigPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt, p4 address.Address, p5 uint64, p6 []byte) (cid.Cid, error) `perm:"sign"`
|
||||
|
||||
MsigSwapApprove func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 address.Address) (cid.Cid, error) `perm:"sign"`
|
||||
MsigRemoveSigner func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 bool) (cid.Cid, error) `perm:"sign"`
|
||||
|
||||
MsigSwapCancel func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (cid.Cid, error) `perm:"sign"`
|
||||
MsigSwapApprove func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address, p6 address.Address) (cid.Cid, error) `perm:"sign"`
|
||||
|
||||
MsigSwapPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (cid.Cid, error) `perm:"sign"`
|
||||
MsigSwapCancel func(p0 context.Context, p1 address.Address, p2 address.Address, p3 uint64, p4 address.Address, p5 address.Address) (cid.Cid, error) `perm:"sign"`
|
||||
|
||||
PaychAllocateLane func(p0 context.Context, p1 address.Address) (uint64, error) `perm:"sign"`
|
||||
MsigSwapPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (cid.Cid, error) `perm:"sign"`
|
||||
|
||||
PaychAvailableFunds func(p0 context.Context, p1 address.Address) (*api.ChannelAvailableFunds, error) `perm:"sign"`
|
||||
PaychAllocateLane func(p0 context.Context, p1 address.Address) (uint64, error) `perm:"sign"`
|
||||
|
||||
PaychAvailableFundsByFromTo func(p0 context.Context, p1 address.Address, p2 address.Address) (*api.ChannelAvailableFunds, error) `perm:"sign"`
|
||||
PaychAvailableFunds func(p0 context.Context, p1 address.Address) (*api.ChannelAvailableFunds, error) `perm:"sign"`
|
||||
|
||||
PaychCollect func(p0 context.Context, p1 address.Address) (cid.Cid, error) `perm:"sign"`
|
||||
PaychAvailableFundsByFromTo func(p0 context.Context, p1 address.Address, p2 address.Address) (*api.ChannelAvailableFunds, error) `perm:"sign"`
|
||||
|
||||
PaychGet func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*api.ChannelInfo, error) `perm:"sign"`
|
||||
PaychCollect func(p0 context.Context, p1 address.Address) (cid.Cid, error) `perm:"sign"`
|
||||
|
||||
PaychGetWaitReady func(p0 context.Context, p1 cid.Cid) (address.Address, error) `perm:"sign"`
|
||||
PaychGet func(p0 context.Context, p1 address.Address, p2 address.Address, p3 types.BigInt) (*api.ChannelInfo, error) `perm:"sign"`
|
||||
|
||||
PaychList func(p0 context.Context) ([]address.Address, error) `perm:"read"`
|
||||
PaychGetWaitReady func(p0 context.Context, p1 cid.Cid) (address.Address, error) `perm:"sign"`
|
||||
|
||||
PaychNewPayment func(p0 context.Context, p1 address.Address, p2 address.Address, p3 []api.VoucherSpec) (*api.PaymentInfo, error) `perm:"sign"`
|
||||
PaychList func(p0 context.Context) ([]address.Address, error) `perm:"read"`
|
||||
|
||||
PaychSettle func(p0 context.Context, p1 address.Address) (cid.Cid, error) `perm:"sign"`
|
||||
PaychNewPayment func(p0 context.Context, p1 address.Address, p2 address.Address, p3 []api.VoucherSpec) (*api.PaymentInfo, error) `perm:"sign"`
|
||||
|
||||
PaychStatus func(p0 context.Context, p1 address.Address) (*api.PaychStatus, error) `perm:"read"`
|
||||
PaychSettle func(p0 context.Context, p1 address.Address) (cid.Cid, error) `perm:"sign"`
|
||||
|
||||
PaychVoucherAdd func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 types.BigInt) (types.BigInt, error) `perm:"write"`
|
||||
PaychStatus func(p0 context.Context, p1 address.Address) (*api.PaychStatus, error) `perm:"read"`
|
||||
|
||||
PaychVoucherCheckSpendable func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (bool, error) `perm:"read"`
|
||||
PaychVoucherAdd func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 types.BigInt) (types.BigInt, error) `perm:"write"`
|
||||
|
||||
PaychVoucherCheckValid func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher) error `perm:"read"`
|
||||
PaychVoucherCheckSpendable func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (bool, error) `perm:"read"`
|
||||
|
||||
PaychVoucherCreate func(p0 context.Context, p1 address.Address, p2 types.BigInt, p3 uint64) (*api.VoucherCreateResult, error) `perm:"sign"`
|
||||
PaychVoucherCheckValid func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher) error `perm:"read"`
|
||||
|
||||
PaychVoucherList func(p0 context.Context, p1 address.Address) ([]*paych.SignedVoucher, error) `perm:"write"`
|
||||
PaychVoucherCreate func(p0 context.Context, p1 address.Address, p2 types.BigInt, p3 uint64) (*api.VoucherCreateResult, error) `perm:"sign"`
|
||||
|
||||
PaychVoucherSubmit func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (cid.Cid, error) `perm:"sign"`
|
||||
PaychVoucherList func(p0 context.Context, p1 address.Address) ([]*paych.SignedVoucher, error) `perm:"write"`
|
||||
|
||||
StateAccountKey func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `perm:"read"`
|
||||
PaychVoucherSubmit func(p0 context.Context, p1 address.Address, p2 *paych.SignedVoucher, p3 []byte, p4 []byte) (cid.Cid, error) `perm:"sign"`
|
||||
|
||||
StateActorCodeCIDs func(p0 context.Context, p1 abinetwork.Version) (map[string]cid.Cid, error) `perm:"read"`
|
||||
StateAccountKey func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `perm:"read"`
|
||||
|
||||
StateActorManifestCID func(p0 context.Context, p1 abinetwork.Version) (cid.Cid, error) `perm:"read"`
|
||||
StateActorCodeCIDs func(p0 context.Context, p1 abinetwork.Version) (map[string]cid.Cid, error) `perm:"read"`
|
||||
|
||||
StateAllMinerFaults func(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) ([]*api.Fault, error) `perm:"read"`
|
||||
StateActorManifestCID func(p0 context.Context, p1 abinetwork.Version) (cid.Cid, error) `perm:"read"`
|
||||
|
||||
StateCall func(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*api.InvocResult, error) `perm:"read"`
|
||||
StateAllMinerFaults func(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) ([]*api.Fault, error) `perm:"read"`
|
||||
|
||||
StateChangedActors func(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (map[string]types.Actor, error) `perm:"read"`
|
||||
StateCall func(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*api.InvocResult, error) `perm:"read"`
|
||||
|
||||
StateCirculatingSupply func(p0 context.Context, p1 types.TipSetKey) (abi.TokenAmount, error) `perm:"read"`
|
||||
StateChangedActors func(p0 context.Context, p1 cid.Cid, p2 cid.Cid) (map[string]types.Actor, error) `perm:"read"`
|
||||
|
||||
StateCompute func(p0 context.Context, p1 abi.ChainEpoch, p2 []*types.Message, p3 types.TipSetKey) (*api.ComputeStateOutput, error) `perm:"read"`
|
||||
StateCirculatingSupply func(p0 context.Context, p1 types.TipSetKey) (abi.TokenAmount, error) `perm:"read"`
|
||||
|
||||
StateDealProviderCollateralBounds func(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) `perm:"read"`
|
||||
StateCompute func(p0 context.Context, p1 abi.ChainEpoch, p2 []*types.Message, p3 types.TipSetKey) (*api.ComputeStateOutput, error) `perm:"read"`
|
||||
|
||||
StateDecodeParams func(p0 context.Context, p1 address.Address, p2 abi.MethodNum, p3 []byte, p4 types.TipSetKey) (interface{}, error) `perm:"read"`
|
||||
StateDealProviderCollateralBounds func(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) `perm:"read"`
|
||||
|
||||
StateGetActor func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) `perm:"read"`
|
||||
StateDecodeParams func(p0 context.Context, p1 address.Address, p2 abi.MethodNum, p3 []byte, p4 types.TipSetKey) (interface{}, error) `perm:"read"`
|
||||
|
||||
StateGetAllocation func(p0 context.Context, p1 address.Address, p2 verifregtypes.AllocationId, p3 types.TipSetKey) (*verifregtypes.Allocation, error) `perm:"read"`
|
||||
StateGetActor func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) `perm:"read"`
|
||||
|
||||
StateGetAllocationForPendingDeal func(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*verifregtypes.Allocation, error) `perm:"read"`
|
||||
StateGetAllocation func(p0 context.Context, p1 address.Address, p2 verifregtypes.AllocationId, p3 types.TipSetKey) (*verifregtypes.Allocation, error) `perm:"read"`
|
||||
|
||||
StateGetAllocations func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (map[verifregtypes.AllocationId]verifregtypes.Allocation, error) `perm:"read"`
|
||||
StateGetAllocationForPendingDeal func(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*verifregtypes.Allocation, error) `perm:"read"`
|
||||
|
||||
StateGetClaim func(p0 context.Context, p1 address.Address, p2 verifregtypes.ClaimId, p3 types.TipSetKey) (*verifregtypes.Claim, error) `perm:"read"`
|
||||
StateGetAllocations func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (map[verifregtypes.AllocationId]verifregtypes.Allocation, error) `perm:"read"`
|
||||
|
||||
StateGetClaims func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (map[verifregtypes.ClaimId]verifregtypes.Claim, error) `perm:"read"`
|
||||
StateGetClaim func(p0 context.Context, p1 address.Address, p2 verifregtypes.ClaimId, p3 types.TipSetKey) (*verifregtypes.Claim, error) `perm:"read"`
|
||||
|
||||
StateGetNetworkParams func(p0 context.Context) (*api.NetworkParams, error) `perm:"read"`
|
||||
StateGetClaims func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (map[verifregtypes.ClaimId]verifregtypes.Claim, error) `perm:"read"`
|
||||
|
||||
StateGetRandomnessFromBeacon func(p0 context.Context, p1 crypto.DomainSeparationTag, p2 abi.ChainEpoch, p3 []byte, p4 types.TipSetKey) (abi.Randomness, error) `perm:"read"`
|
||||
StateGetNetworkParams func(p0 context.Context) (*api.NetworkParams, error) `perm:"read"`
|
||||
|
||||
StateGetRandomnessFromTickets func(p0 context.Context, p1 crypto.DomainSeparationTag, p2 abi.ChainEpoch, p3 []byte, p4 types.TipSetKey) (abi.Randomness, error) `perm:"read"`
|
||||
StateGetRandomnessFromBeacon func(p0 context.Context, p1 crypto.DomainSeparationTag, p2 abi.ChainEpoch, p3 []byte, p4 types.TipSetKey) (abi.Randomness, error) `perm:"read"`
|
||||
|
||||
StateGetReceipt func(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) `perm:"read"`
|
||||
StateGetRandomnessFromTickets func(p0 context.Context, p1 crypto.DomainSeparationTag, p2 abi.ChainEpoch, p3 []byte, p4 types.TipSetKey) (abi.Randomness, error) `perm:"read"`
|
||||
|
||||
StateListActors func(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) `perm:"read"`
|
||||
StateGetReceipt func(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) `perm:"read"`
|
||||
|
||||
StateListMessages func(p0 context.Context, p1 *api.MessageMatch, p2 types.TipSetKey, p3 abi.ChainEpoch) ([]cid.Cid, error) `perm:"read"`
|
||||
StateListActors func(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) `perm:"read"`
|
||||
|
||||
StateListMiners func(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) `perm:"read"`
|
||||
StateListMessages func(p0 context.Context, p1 *api.MessageMatch, p2 types.TipSetKey, p3 abi.ChainEpoch) ([]cid.Cid, error) `perm:"read"`
|
||||
|
||||
StateLookupID func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `perm:"read"`
|
||||
StateListMiners func(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) `perm:"read"`
|
||||
|
||||
StateMarketBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MarketBalance, error) `perm:"read"`
|
||||
StateLookupID func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) `perm:"read"`
|
||||
|
||||
StateMarketDeals func(p0 context.Context, p1 types.TipSetKey) (map[string]*api.MarketDeal, error) `perm:"read"`
|
||||
StateMarketBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MarketBalance, error) `perm:"read"`
|
||||
|
||||
StateMarketParticipants func(p0 context.Context, p1 types.TipSetKey) (map[string]api.MarketBalance, error) `perm:"read"`
|
||||
StateMarketDeals func(p0 context.Context, p1 types.TipSetKey) (map[string]*api.MarketDeal, error) `perm:"read"`
|
||||
|
||||
StateMarketStorageDeal func(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*api.MarketDeal, error) `perm:"read"`
|
||||
StateMarketParticipants func(p0 context.Context, p1 types.TipSetKey) (map[string]api.MarketBalance, error) `perm:"read"`
|
||||
|
||||
StateMinerActiveSectors func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) `perm:"read"`
|
||||
StateMarketStorageDeal func(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*api.MarketDeal, error) `perm:"read"`
|
||||
|
||||
StateMinerAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
StateMinerActiveSectors func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) `perm:"read"`
|
||||
|
||||
StateMinerDeadlines func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]api.Deadline, error) `perm:"read"`
|
||||
StateMinerAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
|
||||
StateMinerFaults func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) `perm:"read"`
|
||||
StateMinerDeadlines func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]api.Deadline, error) `perm:"read"`
|
||||
|
||||
StateMinerInfo func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MinerInfo, error) `perm:"read"`
|
||||
StateMinerFaults func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) `perm:"read"`
|
||||
|
||||
StateMinerInitialPledgeCollateral func(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
StateMinerInfo func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MinerInfo, error) `perm:"read"`
|
||||
|
||||
StateMinerPartitions func(p0 context.Context, p1 address.Address, p2 uint64, p3 types.TipSetKey) ([]api.Partition, error) `perm:"read"`
|
||||
StateMinerInitialPledgeCollateral func(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
|
||||
StateMinerPower func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.MinerPower, error) `perm:"read"`
|
||||
StateMinerPartitions func(p0 context.Context, p1 address.Address, p2 uint64, p3 types.TipSetKey) ([]api.Partition, error) `perm:"read"`
|
||||
|
||||
StateMinerPreCommitDepositForPower func(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
StateMinerPower func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.MinerPower, error) `perm:"read"`
|
||||
|
||||
StateMinerProvingDeadline func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) `perm:"read"`
|
||||
StateMinerPreCommitDepositForPower func(p0 context.Context, p1 address.Address, p2 miner.SectorPreCommitInfo, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
|
||||
StateMinerRecoveries func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) `perm:"read"`
|
||||
StateMinerProvingDeadline func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) `perm:"read"`
|
||||
|
||||
StateMinerSectorAllocated func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (bool, error) `perm:"read"`
|
||||
StateMinerRecoveries func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (bitfield.BitField, error) `perm:"read"`
|
||||
|
||||
StateMinerSectorCount func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MinerSectors, error) `perm:"read"`
|
||||
StateMinerSectorAllocated func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (bool, error) `perm:"read"`
|
||||
|
||||
StateMinerSectors func(p0 context.Context, p1 address.Address, p2 *bitfield.BitField, p3 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) `perm:"read"`
|
||||
StateMinerSectorCount func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MinerSectors, error) `perm:"read"`
|
||||
|
||||
StateNetworkName func(p0 context.Context) (dtypes.NetworkName, error) `perm:"read"`
|
||||
StateMinerSectors func(p0 context.Context, p1 address.Address, p2 *bitfield.BitField, p3 types.TipSetKey) ([]*miner.SectorOnChainInfo, error) `perm:"read"`
|
||||
|
||||
StateNetworkVersion func(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) `perm:"read"`
|
||||
StateNetworkName func(p0 context.Context) (dtypes.NetworkName, error) `perm:"read"`
|
||||
|
||||
StateReadState func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.ActorState, error) `perm:"read"`
|
||||
StateNetworkVersion func(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) `perm:"read"`
|
||||
|
||||
StateReplay func(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*api.InvocResult, error) `perm:"read"`
|
||||
StateReadState func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.ActorState, error) `perm:"read"`
|
||||
|
||||
StateSearchMsg func(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) `perm:"read"`
|
||||
StateReplay func(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid) (*api.InvocResult, error) `perm:"read"`
|
||||
|
||||
StateSearchMsgLimited func(p0 context.Context, p1 cid.Cid, p2 abi.ChainEpoch) (*api.MsgLookup, error) `perm:"read"`
|
||||
StateSearchMsg func(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) `perm:"read"`
|
||||
|
||||
StateSectorExpiration func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*lminer.SectorExpiration, error) `perm:"read"`
|
||||
StateSearchMsgLimited func(p0 context.Context, p1 cid.Cid, p2 abi.ChainEpoch) (*api.MsgLookup, error) `perm:"read"`
|
||||
|
||||
StateSectorGetInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) `perm:"read"`
|
||||
StateSectorExpiration func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*lminer.SectorExpiration, error) `perm:"read"`
|
||||
|
||||
StateSectorPartition func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*lminer.SectorLocation, error) `perm:"read"`
|
||||
StateSectorGetInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) `perm:"read"`
|
||||
|
||||
StateSectorPreCommitInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) `perm:"read"`
|
||||
StateSectorPartition func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*lminer.SectorLocation, error) `perm:"read"`
|
||||
|
||||
StateVMCirculatingSupplyInternal func(p0 context.Context, p1 types.TipSetKey) (api.CirculatingSupply, error) `perm:"read"`
|
||||
StateSectorPreCommitInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) `perm:"read"`
|
||||
|
||||
StateVerifiedClientStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) `perm:"read"`
|
||||
StateVMCirculatingSupplyInternal func(p0 context.Context, p1 types.TipSetKey) (api.CirculatingSupply, error) `perm:"read"`
|
||||
|
||||
StateVerifiedRegistryRootKey func(p0 context.Context, p1 types.TipSetKey) (address.Address, error) `perm:"read"`
|
||||
StateVerifiedClientStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) `perm:"read"`
|
||||
|
||||
StateVerifierStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) `perm:"read"`
|
||||
StateVerifiedRegistryRootKey func(p0 context.Context, p1 types.TipSetKey) (address.Address, error) `perm:"read"`
|
||||
|
||||
StateWaitMsg func(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) `perm:"read"`
|
||||
StateVerifierStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) `perm:"read"`
|
||||
|
||||
StateWaitMsgLimited func(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch) (*api.MsgLookup, error) `perm:"read"`
|
||||
StateWaitMsg func(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) `perm:"read"`
|
||||
|
||||
SyncCheckBad func(p0 context.Context, p1 cid.Cid) (string, error) `perm:"read"`
|
||||
StateWaitMsgLimited func(p0 context.Context, p1 cid.Cid, p2 uint64, p3 abi.ChainEpoch) (*api.MsgLookup, error) `perm:"read"`
|
||||
|
||||
SyncCheckpoint func(p0 context.Context, p1 types.TipSetKey) error `perm:"admin"`
|
||||
SyncCheckBad func(p0 context.Context, p1 cid.Cid) (string, error) `perm:"read"`
|
||||
|
||||
SyncIncomingBlocks func(p0 context.Context) (<-chan *types.BlockHeader, error) `perm:"read"`
|
||||
SyncCheckpoint func(p0 context.Context, p1 types.TipSetKey) error `perm:"admin"`
|
||||
|
||||
SyncMarkBad func(p0 context.Context, p1 cid.Cid) error `perm:"admin"`
|
||||
SyncIncomingBlocks func(p0 context.Context) (<-chan *types.BlockHeader, error) `perm:"read"`
|
||||
|
||||
SyncState func(p0 context.Context) (*api.SyncState, error) `perm:"read"`
|
||||
SyncMarkBad func(p0 context.Context, p1 cid.Cid) error `perm:"admin"`
|
||||
|
||||
SyncSubmitBlock func(p0 context.Context, p1 *types.BlockMsg) error `perm:"write"`
|
||||
SyncState func(p0 context.Context) (*api.SyncState, error) `perm:"read"`
|
||||
|
||||
SyncUnmarkAllBad func(p0 context.Context) error `perm:"admin"`
|
||||
SyncSubmitBlock func(p0 context.Context, p1 *types.BlockMsg) error `perm:"write"`
|
||||
|
||||
SyncUnmarkBad func(p0 context.Context, p1 cid.Cid) error `perm:"admin"`
|
||||
SyncUnmarkAllBad func(p0 context.Context) error `perm:"admin"`
|
||||
|
||||
SyncValidateTipset func(p0 context.Context, p1 types.TipSetKey) (bool, error) `perm:"read"`
|
||||
SyncUnmarkBad func(p0 context.Context, p1 cid.Cid) error `perm:"admin"`
|
||||
|
||||
WalletBalance func(p0 context.Context, p1 address.Address) (types.BigInt, error) `perm:"read"`
|
||||
SyncValidateTipset func(p0 context.Context, p1 types.TipSetKey) (bool, error) `perm:"read"`
|
||||
|
||||
WalletDefaultAddress func(p0 context.Context) (address.Address, error) `perm:"write"`
|
||||
WalletBalance func(p0 context.Context, p1 address.Address) (types.BigInt, error) `perm:"read"`
|
||||
|
||||
WalletDelete func(p0 context.Context, p1 address.Address) error `perm:"admin"`
|
||||
WalletDefaultAddress func(p0 context.Context) (address.Address, error) `perm:"write"`
|
||||
|
||||
WalletExport func(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) `perm:"admin"`
|
||||
WalletDelete func(p0 context.Context, p1 address.Address) error `perm:"admin"`
|
||||
|
||||
WalletHas func(p0 context.Context, p1 address.Address) (bool, error) `perm:"write"`
|
||||
WalletExport func(p0 context.Context, p1 address.Address) (*types.KeyInfo, error) `perm:"admin"`
|
||||
|
||||
WalletImport func(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) `perm:"admin"`
|
||||
WalletHas func(p0 context.Context, p1 address.Address) (bool, error) `perm:"write"`
|
||||
|
||||
WalletList func(p0 context.Context) ([]address.Address, error) `perm:"write"`
|
||||
WalletImport func(p0 context.Context, p1 *types.KeyInfo) (address.Address, error) `perm:"admin"`
|
||||
|
||||
WalletNew func(p0 context.Context, p1 types.KeyType) (address.Address, error) `perm:"write"`
|
||||
WalletList func(p0 context.Context) ([]address.Address, error) `perm:"write"`
|
||||
|
||||
WalletSetDefault func(p0 context.Context, p1 address.Address) error `perm:"write"`
|
||||
WalletNew func(p0 context.Context, p1 types.KeyType) (address.Address, error) `perm:"write"`
|
||||
|
||||
WalletSign func(p0 context.Context, p1 address.Address, p2 []byte) (*crypto.Signature, error) `perm:"sign"`
|
||||
WalletSetDefault func(p0 context.Context, p1 address.Address) error `perm:"write"`
|
||||
|
||||
WalletSignMessage func(p0 context.Context, p1 address.Address, p2 *types.Message) (*types.SignedMessage, error) `perm:"sign"`
|
||||
WalletSign func(p0 context.Context, p1 address.Address, p2 []byte) (*crypto.Signature, error) `perm:"sign"`
|
||||
|
||||
WalletValidateAddress func(p0 context.Context, p1 string) (address.Address, error) `perm:"read"`
|
||||
WalletSignMessage func(p0 context.Context, p1 address.Address, p2 *types.Message) (*types.SignedMessage, error) `perm:"sign"`
|
||||
|
||||
WalletVerify func(p0 context.Context, p1 address.Address, p2 []byte, p3 *crypto.Signature) (bool, error) `perm:"read"`
|
||||
}
|
||||
WalletValidateAddress func(p0 context.Context, p1 string) (address.Address, error) `perm:"read"`
|
||||
|
||||
WalletVerify func(p0 context.Context, p1 address.Address, p2 []byte, p3 *crypto.Signature) (bool, error) `perm:"read"`
|
||||
}
|
||||
|
||||
type FullNodeStub struct {
|
||||
@@ -425,71 +427,73 @@ type FullNodeStub struct {
|
||||
}
|
||||
|
||||
type GatewayStruct struct {
|
||||
Internal struct {
|
||||
ChainGetBlockMessages func(p0 context.Context, p1 cid.Cid) (*api.BlockMessages, error) ``
|
||||
Internal GatewayMethods
|
||||
}
|
||||
|
||||
ChainGetMessage func(p0 context.Context, p1 cid.Cid) (*types.Message, error) ``
|
||||
type GatewayMethods struct {
|
||||
ChainGetBlockMessages func(p0 context.Context, p1 cid.Cid) (*api.BlockMessages, error) ``
|
||||
|
||||
ChainGetTipSet func(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) ``
|
||||
ChainGetMessage func(p0 context.Context, p1 cid.Cid) (*types.Message, error) ``
|
||||
|
||||
ChainGetTipSetByHeight func(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) ``
|
||||
ChainGetTipSet func(p0 context.Context, p1 types.TipSetKey) (*types.TipSet, error) ``
|
||||
|
||||
ChainHasObj func(p0 context.Context, p1 cid.Cid) (bool, error) ``
|
||||
ChainGetTipSetByHeight func(p0 context.Context, p1 abi.ChainEpoch, p2 types.TipSetKey) (*types.TipSet, error) ``
|
||||
|
||||
ChainHead func(p0 context.Context) (*types.TipSet, error) ``
|
||||
ChainHasObj func(p0 context.Context, p1 cid.Cid) (bool, error) ``
|
||||
|
||||
ChainNotify func(p0 context.Context) (<-chan []*api.HeadChange, error) ``
|
||||
ChainHead func(p0 context.Context) (*types.TipSet, error) ``
|
||||
|
||||
ChainPutObj func(p0 context.Context, p1 blocks.Block) error ``
|
||||
ChainNotify func(p0 context.Context) (<-chan []*api.HeadChange, error) ``
|
||||
|
||||
ChainReadObj func(p0 context.Context, p1 cid.Cid) ([]byte, error) ``
|
||||
ChainPutObj func(p0 context.Context, p1 blocks.Block) error ``
|
||||
|
||||
GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) ``
|
||||
ChainReadObj func(p0 context.Context, p1 cid.Cid) ([]byte, error) ``
|
||||
|
||||
MpoolPush func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) ``
|
||||
GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) ``
|
||||
|
||||
MsigGetAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) ``
|
||||
MpoolPush func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) ``
|
||||
|
||||
MsigGetPending func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*api.MsigTransaction, error) ``
|
||||
MsigGetAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) ``
|
||||
|
||||
MsigGetVested func(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) ``
|
||||
MsigGetPending func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) ([]*api.MsigTransaction, error) ``
|
||||
|
||||
StateAccountKey func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) ``
|
||||
MsigGetVested func(p0 context.Context, p1 address.Address, p2 types.TipSetKey, p3 types.TipSetKey) (types.BigInt, error) ``
|
||||
|
||||
StateDealProviderCollateralBounds func(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) ``
|
||||
StateAccountKey func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) ``
|
||||
|
||||
StateGetActor func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) ``
|
||||
StateDealProviderCollateralBounds func(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) ``
|
||||
|
||||
StateGetReceipt func(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) ``
|
||||
StateGetActor func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) ``
|
||||
|
||||
StateListMiners func(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) ``
|
||||
StateGetReceipt func(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) ``
|
||||
|
||||
StateLookupID func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) ``
|
||||
StateListMiners func(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) ``
|
||||
|
||||
StateMarketBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MarketBalance, error) ``
|
||||
StateLookupID func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) ``
|
||||
|
||||
StateMarketStorageDeal func(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*api.MarketDeal, error) ``
|
||||
StateMarketBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MarketBalance, error) ``
|
||||
|
||||
StateMinerInfo func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MinerInfo, error) ``
|
||||
StateMarketStorageDeal func(p0 context.Context, p1 abi.DealID, p2 types.TipSetKey) (*api.MarketDeal, error) ``
|
||||
|
||||
StateMinerPower func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.MinerPower, error) ``
|
||||
StateMinerInfo func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (api.MinerInfo, error) ``
|
||||
|
||||
StateMinerProvingDeadline func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) ``
|
||||
StateMinerPower func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*api.MinerPower, error) ``
|
||||
|
||||
StateNetworkVersion func(p0 context.Context, p1 types.TipSetKey) (abinetwork.Version, error) ``
|
||||
StateMinerProvingDeadline func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) ``
|
||||
|
||||
StateSearchMsg func(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) ``
|
||||
StateNetworkVersion func(p0 context.Context, p1 types.TipSetKey) (abinetwork.Version, error) ``
|
||||
|
||||
StateSectorGetInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) ``
|
||||
StateSearchMsg func(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) ``
|
||||
|
||||
StateVerifiedClientStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) ``
|
||||
StateSectorGetInfo func(p0 context.Context, p1 address.Address, p2 abi.SectorNumber, p3 types.TipSetKey) (*miner.SectorOnChainInfo, error) ``
|
||||
|
||||
StateWaitMsg func(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) ``
|
||||
StateVerifiedClientStatus func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*abi.StoragePower, error) ``
|
||||
|
||||
Version func(p0 context.Context) (api.APIVersion, error) ``
|
||||
StateWaitMsg func(p0 context.Context, p1 cid.Cid, p2 uint64) (*api.MsgLookup, error) ``
|
||||
|
||||
WalletBalance func(p0 context.Context, p1 address.Address) (types.BigInt, error) ``
|
||||
}
|
||||
Version func(p0 context.Context) (api.APIVersion, error) ``
|
||||
|
||||
WalletBalance func(p0 context.Context, p1 address.Address) (types.BigInt, error) ``
|
||||
}
|
||||
|
||||
type GatewayStub struct {
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+2
-2
@@ -23,7 +23,7 @@ var NetworkBundle = "devnet"
|
||||
var BundleOverrides map[actorstypes.Version]string
|
||||
var ActorDebugging = true
|
||||
|
||||
const GenesisNetworkVersion = network.Version18
|
||||
const GenesisNetworkVersion = network.Version17
|
||||
|
||||
var UpgradeBreezeHeight = abi.ChainEpoch(-1)
|
||||
|
||||
@@ -59,7 +59,7 @@ var UpgradeSkyrHeight = abi.ChainEpoch(-19)
|
||||
|
||||
var UpgradeSharkHeight = abi.ChainEpoch(-20)
|
||||
|
||||
var UpgradeHyggeHeight = abi.ChainEpoch(-21)
|
||||
var UpgradeHyggeHeight = abi.ChainEpoch(30)
|
||||
|
||||
var UpgradeHyperspaceNV19Height = abi.ChainEpoch(60)
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
var SystemActorAddr = builtin.SystemActorAddr
|
||||
var BurntFundsActorAddr = builtin.BurntFundsActorAddr
|
||||
var CronActorAddr = builtin.CronActorAddr
|
||||
var EthereumAddressManagerActorAddr = builtin.EthereumAddressManagerActorAddr
|
||||
var SaftAddress = makeAddress("t0122")
|
||||
var ReserveAddress = makeAddress("t090")
|
||||
var RootVerifierAddress = makeAddress("t080")
|
||||
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
var SystemActorAddr = builtin.SystemActorAddr
|
||||
var BurntFundsActorAddr = builtin.BurntFundsActorAddr
|
||||
var CronActorAddr = builtin.CronActorAddr
|
||||
var EthereumAddressManagerActorAddr = builtin.EthereumAddressManagerActorAddr
|
||||
var SaftAddress = makeAddress("t0122")
|
||||
var ReserveAddress = makeAddress("t090")
|
||||
var RootVerifierAddress = makeAddress("t080")
|
||||
|
||||
@@ -67,34 +67,28 @@ func (ei *EthTxHashLookup) UpsertHash(txHash ethtypes.EthHash, c cid.Cid) error
|
||||
}
|
||||
|
||||
func (ei *EthTxHashLookup) GetCidFromHash(txHash ethtypes.EthHash) (cid.Cid, error) {
|
||||
q, err := ei.db.Query("SELECT cid FROM eth_tx_hashes WHERE hash = :hash;", sql.Named("hash", txHash.String()))
|
||||
if err != nil {
|
||||
return cid.Undef, err
|
||||
}
|
||||
row := ei.db.QueryRow("SELECT cid FROM eth_tx_hashes WHERE hash = :hash;", sql.Named("hash", txHash.String()))
|
||||
|
||||
var c string
|
||||
if !q.Next() {
|
||||
return cid.Undef, ErrNotFound
|
||||
}
|
||||
err = q.Scan(&c)
|
||||
err := row.Scan(&c)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return cid.Undef, ErrNotFound
|
||||
}
|
||||
return cid.Undef, err
|
||||
}
|
||||
return cid.Decode(c)
|
||||
}
|
||||
|
||||
func (ei *EthTxHashLookup) GetHashFromCid(c cid.Cid) (ethtypes.EthHash, error) {
|
||||
q, err := ei.db.Query("SELECT hash FROM eth_tx_hashes WHERE cid = :cid;", sql.Named("cid", c.String()))
|
||||
if err != nil {
|
||||
return ethtypes.EmptyEthHash, err
|
||||
}
|
||||
row := ei.db.QueryRow("SELECT hash FROM eth_tx_hashes WHERE cid = :cid;", sql.Named("cid", c.String()))
|
||||
|
||||
var hashString string
|
||||
if !q.Next() {
|
||||
return ethtypes.EmptyEthHash, ErrNotFound
|
||||
}
|
||||
err = q.Scan(&hashString)
|
||||
err := row.Scan(&c)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return ethtypes.EmptyEthHash, ErrNotFound
|
||||
}
|
||||
return ethtypes.EmptyEthHash, err
|
||||
}
|
||||
return ethtypes.ParseEthHash(hashString)
|
||||
|
||||
@@ -20,7 +20,12 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
const indexed uint8 = 0x01
|
||||
func isIndexedValue(b uint8) bool {
|
||||
// currently we mark the full entry as indexed if either the key
|
||||
// or the value are indexed; in the future we will need finer-grained
|
||||
// management of indices
|
||||
return b&(types.EventFlagIndexedKey|types.EventFlagIndexedValue) > 0
|
||||
}
|
||||
|
||||
type EventFilter struct {
|
||||
id types.FilterID
|
||||
@@ -100,18 +105,18 @@ func (f *EventFilter) CollectEvents(ctx context.Context, te *TipSetEvents, rever
|
||||
continue
|
||||
}
|
||||
|
||||
decodedEntries := make([]types.EventEntry, len(ev.Entries))
|
||||
entries := make([]types.EventEntry, len(ev.Entries))
|
||||
for i, entry := range ev.Entries {
|
||||
decodedEntries[i] = types.EventEntry{
|
||||
entries[i] = types.EventEntry{
|
||||
Flags: entry.Flags,
|
||||
Key: entry.Key,
|
||||
Value: decodeLogBytes(entry.Value),
|
||||
Value: entry.Value,
|
||||
}
|
||||
}
|
||||
|
||||
// event matches filter, so record it
|
||||
cev := &CollectedEvent{
|
||||
Entries: decodedEntries,
|
||||
Entries: entries,
|
||||
EmitterAddr: addr,
|
||||
EventIdx: evIdx,
|
||||
Reverted: revert,
|
||||
@@ -209,7 +214,7 @@ func (f *EventFilter) matchKeys(ees []types.EventEntry) bool {
|
||||
matched := map[string]bool{}
|
||||
for _, ee := range ees {
|
||||
// Skip an entry that is not indexable
|
||||
if ee.Flags&indexed != indexed {
|
||||
if !isIndexedValue(ee.Flags) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -221,7 +226,7 @@ func (f *EventFilter) matchKeys(ees []types.EventEntry) bool {
|
||||
}
|
||||
|
||||
wantlist, ok := f.keys[keyname]
|
||||
if !ok {
|
||||
if !ok || len(wantlist) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package filter
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
@@ -11,7 +10,6 @@ import (
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
@@ -153,13 +151,6 @@ func (ei *EventIndex) CollectEvents(ctx context.Context, te *TipSetEvents, rever
|
||||
return xerrors.Errorf("prepare insert entry: %w", err)
|
||||
}
|
||||
|
||||
isIndexedValue := func(b uint8) bool {
|
||||
// currently we mark the full entry as indexed if either the key
|
||||
// or the value are indexed; in the future we will need finer-grained
|
||||
// management of indices
|
||||
return b&(types.EventFlagIndexedKey|types.EventFlagIndexedValue) > 0
|
||||
}
|
||||
|
||||
for msgIdx, em := range ems {
|
||||
for evIdx, ev := range em.Events() {
|
||||
addr, found := addressLookups[ev.Emitter]
|
||||
@@ -198,13 +189,12 @@ func (ei *EventIndex) CollectEvents(ctx context.Context, te *TipSetEvents, rever
|
||||
}
|
||||
|
||||
for _, entry := range ev.Entries {
|
||||
value := decodeLogBytes(entry.Value)
|
||||
_, err := stmtEntry.Exec(
|
||||
lastID, // event_id
|
||||
isIndexedValue(entry.Flags), // indexed
|
||||
[]byte{entry.Flags}, // flags
|
||||
entry.Key, // key
|
||||
value, // value
|
||||
entry.Value, // value
|
||||
)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("exec insert entry: %w", err)
|
||||
@@ -220,21 +210,6 @@ func (ei *EventIndex) CollectEvents(ctx context.Context, te *TipSetEvents, rever
|
||||
return nil
|
||||
}
|
||||
|
||||
// decodeLogBytes decodes a CBOR-serialized array into its original form.
|
||||
//
|
||||
// This function swallows errors and returns the original array if it failed
|
||||
// to decode.
|
||||
func decodeLogBytes(orig []byte) []byte {
|
||||
if len(orig) == 0 {
|
||||
return orig
|
||||
}
|
||||
decoded, err := cbg.ReadByteArray(bytes.NewReader(orig), uint64(len(orig)))
|
||||
if err != nil {
|
||||
return orig
|
||||
}
|
||||
return decoded
|
||||
}
|
||||
|
||||
// PrefillFilter fills a filter's collection of events from the historic index
|
||||
func (ei *EventIndex) PrefillFilter(ctx context.Context, f *EventFilter) error {
|
||||
clauses := []string{}
|
||||
|
||||
@@ -202,7 +202,7 @@ func (ms *MessageSigner) dstoreKey(addr address.Address) datastore.Key {
|
||||
|
||||
func SigningBytes(msg *types.Message, sigType crypto.SigType) ([]byte, error) {
|
||||
if sigType == crypto.SigTypeDelegated {
|
||||
txArgs, err := ethtypes.EthTxArgsFromMessage(msg)
|
||||
txArgs, err := ethtypes.EthTxArgsFromUnsignedEthMessage(msg)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to reconstruct eth transaction: %w", err)
|
||||
}
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ func AuthenticateMessage(msg *types.SignedMessage, signer address.Address) error
|
||||
typ := msg.Signature.Type
|
||||
switch typ {
|
||||
case crypto.SigTypeDelegated:
|
||||
txArgs, err := ethtypes.EthTxArgsFromMessage(&msg.Message)
|
||||
txArgs, err := ethtypes.EthTxArgsFromUnsignedEthMessage(&msg.Message)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to reconstruct eth transaction: %w", err)
|
||||
}
|
||||
|
||||
@@ -403,7 +403,8 @@ func (sm *StateManager) GetCirculatingSupply(ctx context.Context, height abi.Cha
|
||||
a == builtin.CronActorAddr ||
|
||||
a == builtin.BurntFundsActorAddr ||
|
||||
a == builtin.SaftAddress ||
|
||||
a == builtin.ReserveAddress:
|
||||
a == builtin.ReserveAddress ||
|
||||
a == builtin.EthereumAddressManagerActorAddr:
|
||||
|
||||
unCirc = big.Add(unCirc, actor.Balance)
|
||||
|
||||
@@ -421,7 +422,12 @@ func (sm *StateManager) GetCirculatingSupply(ctx context.Context, height abi.Cha
|
||||
circ = big.Add(circ, big.Sub(actor.Balance, lb))
|
||||
unCirc = big.Add(unCirc, lb)
|
||||
|
||||
case builtin.IsAccountActor(actor.Code) || builtin.IsPaymentChannelActor(actor.Code):
|
||||
case builtin.IsAccountActor(actor.Code) ||
|
||||
builtin.IsPaymentChannelActor(actor.Code) ||
|
||||
builtin.IsEthAccountActor(actor.Code) ||
|
||||
builtin.IsEvmActor(actor.Code) ||
|
||||
builtin.IsPlaceholderActor(actor.Code):
|
||||
|
||||
circ = big.Add(circ, actor.Balance)
|
||||
|
||||
case builtin.IsStorageMinerActor(actor.Code):
|
||||
|
||||
@@ -12,13 +12,11 @@ import (
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
gocrypto "github.com/filecoin-project/go-crypto"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
builtintypes "github.com/filecoin-project/go-state-types/builtin"
|
||||
typescrypto "github.com/filecoin-project/go-state-types/crypto"
|
||||
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
)
|
||||
|
||||
@@ -58,11 +56,49 @@ type EthTxArgs struct {
|
||||
S big.Int `json:"s"`
|
||||
}
|
||||
|
||||
func EthTxArgsFromMessage(msg *types.Message) (EthTxArgs, error) {
|
||||
// EthTxFromSignedEthMessage does NOT populate:
|
||||
// - BlockHash
|
||||
// - BlockNumber
|
||||
// - TransactionIndex
|
||||
// - From
|
||||
// - Hash
|
||||
func EthTxFromSignedEthMessage(smsg *types.SignedMessage) (EthTx, error) {
|
||||
if smsg.Signature.Type != typescrypto.SigTypeDelegated {
|
||||
return EthTx{}, xerrors.Errorf("signature is not delegated type, is type: %d", smsg.Signature.Type)
|
||||
}
|
||||
|
||||
txArgs, err := EthTxArgsFromUnsignedEthMessage(&smsg.Message)
|
||||
if err != nil {
|
||||
return EthTx{}, xerrors.Errorf("failed to convert the unsigned message: %w", err)
|
||||
}
|
||||
|
||||
r, s, v, err := RecoverSignature(smsg.Signature)
|
||||
if err != nil {
|
||||
return EthTx{}, xerrors.Errorf("failed to recover signature: %w", err)
|
||||
}
|
||||
|
||||
return EthTx{
|
||||
Nonce: EthUint64(txArgs.Nonce),
|
||||
ChainID: EthUint64(txArgs.ChainID),
|
||||
To: txArgs.To,
|
||||
Value: EthBigInt(txArgs.Value),
|
||||
Type: Eip1559TxType,
|
||||
Gas: EthUint64(txArgs.GasLimit),
|
||||
MaxFeePerGas: EthBigInt(txArgs.MaxFeePerGas),
|
||||
MaxPriorityFeePerGas: EthBigInt(txArgs.MaxPriorityFeePerGas),
|
||||
V: v,
|
||||
R: r,
|
||||
S: s,
|
||||
Input: txArgs.Input,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func EthTxArgsFromUnsignedEthMessage(msg *types.Message) (EthTxArgs, error) {
|
||||
var (
|
||||
to *EthAddress
|
||||
params []byte
|
||||
paramsReader = bytes.NewReader(msg.Params)
|
||||
err error
|
||||
)
|
||||
|
||||
if msg.Version != 0 {
|
||||
@@ -72,11 +108,10 @@ func EthTxArgsFromMessage(msg *types.Message) (EthTxArgs, error) {
|
||||
if msg.To == builtintypes.EthereumAddressManagerActorAddr {
|
||||
switch msg.Method {
|
||||
case builtintypes.MethodsEAM.CreateExternal:
|
||||
var create abi.CborBytes
|
||||
if err := create.UnmarshalCBOR(paramsReader); err != nil {
|
||||
return EthTxArgs{}, err
|
||||
params, err = cbg.ReadByteArray(paramsReader, uint64(len(msg.Params)))
|
||||
if err != nil {
|
||||
return EthTxArgs{}, xerrors.Errorf("failed to read params byte array: %w", err)
|
||||
}
|
||||
params = create
|
||||
default:
|
||||
return EthTxArgs{}, fmt.Errorf("unsupported EAM method")
|
||||
}
|
||||
@@ -103,11 +138,6 @@ func EthTxArgsFromMessage(msg *types.Message) (EthTxArgs, error) {
|
||||
if err != nil {
|
||||
return EthTxArgs{}, xerrors.Errorf("failed to read params byte array: %w", err)
|
||||
}
|
||||
|
||||
if len(params) == 0 {
|
||||
// Otherwise, we don't get a guaranteed round-trip.
|
||||
return EthTxArgs{}, xerrors.Errorf("cannot invoke contracts with empty parameters from an eth-account")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +145,11 @@ func EthTxArgsFromMessage(msg *types.Message) (EthTxArgs, error) {
|
||||
return EthTxArgs{}, xerrors.Errorf("extra data found in params")
|
||||
}
|
||||
|
||||
if len(params) == 0 && msg.Method != builtintypes.MethodSend {
|
||||
// Otherwise, we don't get a guaranteed round-trip.
|
||||
return EthTxArgs{}, xerrors.Errorf("msgs with empty parameters from an eth-account must be Sends (MethodNum: %d)", msg.Method)
|
||||
}
|
||||
|
||||
return EthTxArgs{
|
||||
ChainID: build.Eip155ChainId,
|
||||
Nonce: int(msg.Nonce),
|
||||
@@ -143,12 +178,13 @@ func (tx *EthTxArgs) ToUnsignedMessage(from address.Address) (*types.Message, er
|
||||
if len(tx.Input) == 0 {
|
||||
return nil, xerrors.New("cannot call CreateExternal without params")
|
||||
}
|
||||
inputParams := abi.CborBytes(tx.Input)
|
||||
params, err = actors.SerializeParams(&inputParams)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to serialize Create params: %w", err)
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
if err = cbg.WriteByteArray(buf, tx.Input); err != nil {
|
||||
return nil, xerrors.Errorf("failed to serialize Create params: %w", err)
|
||||
}
|
||||
|
||||
params = buf.Bytes()
|
||||
} else {
|
||||
to, err = tx.To.ToFilecoinAddress()
|
||||
if err != nil {
|
||||
|
||||
@@ -363,6 +363,18 @@ func (h *EthHash) UnmarshalJSON(b []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h EthHash) String() string {
|
||||
return "0x" + hex.EncodeToString(h[:])
|
||||
}
|
||||
|
||||
// Should ONLY be used for blocks and Filecoin messages. Eth transactions expect a different hashing scheme.
|
||||
func (h EthHash) ToCid() cid.Cid {
|
||||
// err is always nil
|
||||
mh, _ := multihash.EncodeName(h[:], "blake2b-256")
|
||||
|
||||
return cid.NewCidV1(cid.DagCBOR, mh)
|
||||
}
|
||||
|
||||
func decodeHexString(s string, expectedLen int) ([]byte, error) {
|
||||
s = handleHexStringPrefix(s)
|
||||
if len(s) != expectedLen*2 {
|
||||
@@ -420,18 +432,6 @@ func EthHashFromTxBytes(b []byte) EthHash {
|
||||
return ethHash
|
||||
}
|
||||
|
||||
func (h EthHash) String() string {
|
||||
return "0x" + hex.EncodeToString(h[:])
|
||||
}
|
||||
|
||||
// Should ONLY be used for blocks and Filecoin messages. Eth transactions expect a different hashing scheme.
|
||||
func (h EthHash) ToCid() cid.Cid {
|
||||
// err is always nil
|
||||
mh, _ := multihash.EncodeName(h[:], "blake2b-256")
|
||||
|
||||
return cid.NewCidV1(cid.DagCBOR, mh)
|
||||
}
|
||||
|
||||
type EthFeeHistory struct {
|
||||
OldestBlock uint64 `json:"oldestBlock"`
|
||||
BaseFeePerGas []EthBigInt `json:"baseFeePerGas"`
|
||||
@@ -441,9 +441,33 @@ type EthFeeHistory struct {
|
||||
|
||||
type EthFilterID EthHash
|
||||
|
||||
func (h EthFilterID) MarshalJSON() ([]byte, error) {
|
||||
return (EthHash)(h).MarshalJSON()
|
||||
}
|
||||
|
||||
func (h *EthFilterID) UnmarshalJSON(b []byte) error {
|
||||
return (*EthHash)(h).UnmarshalJSON(b)
|
||||
}
|
||||
|
||||
func (h EthFilterID) String() string {
|
||||
return (EthHash)(h).String()
|
||||
}
|
||||
|
||||
// An opaque identifier generated by the Lotus node to refer to an active subscription.
|
||||
type EthSubscriptionID EthHash
|
||||
|
||||
func (h EthSubscriptionID) MarshalJSON() ([]byte, error) {
|
||||
return (EthHash)(h).MarshalJSON()
|
||||
}
|
||||
|
||||
func (h *EthSubscriptionID) UnmarshalJSON(b []byte) error {
|
||||
return (*EthHash)(h).UnmarshalJSON(b)
|
||||
}
|
||||
|
||||
func (h EthSubscriptionID) String() string {
|
||||
return (EthHash)(h).String()
|
||||
}
|
||||
|
||||
type EthFilterSpec struct {
|
||||
// Interpreted as an epoch or one of "latest" for last mined block, "earliest" for first,
|
||||
// "pending" for not yet committed messages.
|
||||
@@ -595,6 +619,43 @@ type EthLog struct {
|
||||
BlockNumber EthUint64 `json:"blockNumber"`
|
||||
}
|
||||
|
||||
// EthSubscribeParams handles raw jsonrpc params for eth_subscribe
|
||||
type EthSubscribeParams struct {
|
||||
EventType string
|
||||
Params *EthSubscriptionParams
|
||||
}
|
||||
|
||||
func (e *EthSubscribeParams) UnmarshalJSON(b []byte) error {
|
||||
var params []json.RawMessage
|
||||
err := json.Unmarshal(b, ¶ms)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch len(params) {
|
||||
case 2:
|
||||
err = json.Unmarshal(params[1], &e.Params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fallthrough
|
||||
case 1:
|
||||
err = json.Unmarshal(params[0], &e.EventType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return xerrors.Errorf("expected 1 or 2 params, got %d", len(params))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e EthSubscribeParams) MarshalJSON() ([]byte, error) {
|
||||
if e.Params != nil {
|
||||
return json.Marshal([]interface{}{e.EventType, e.Params})
|
||||
}
|
||||
return json.Marshal([]interface{}{e.EventType})
|
||||
}
|
||||
|
||||
type EthSubscriptionParams struct {
|
||||
// List of topics to be matched.
|
||||
// Optional, default: empty list
|
||||
|
||||
@@ -93,6 +93,48 @@ func TestEthHash(t *testing.T) {
|
||||
h1, err := EthHashFromCid(c)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, h, h1)
|
||||
|
||||
jm, err := json.Marshal(h)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, hash, string(jm))
|
||||
}
|
||||
}
|
||||
|
||||
func TestEthFilterID(t *testing.T) {
|
||||
testcases := []string{
|
||||
`"0x013dbb9442ca9667baccc6230fcd5c1c4b2d4d2870f4bd20681d4d47cfd15184"`,
|
||||
`"0xab8653edf9f51785664a643b47605a7ba3d917b5339a0724e7642c114d0e4738"`,
|
||||
}
|
||||
|
||||
for _, hash := range testcases {
|
||||
var h EthFilterID
|
||||
err := h.UnmarshalJSON([]byte(hash))
|
||||
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, h.String(), strings.Replace(hash, `"`, "", -1))
|
||||
|
||||
jm, err := json.Marshal(h)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, hash, string(jm))
|
||||
}
|
||||
}
|
||||
|
||||
func TestEthSubscriptionID(t *testing.T) {
|
||||
testcases := []string{
|
||||
`"0x013dbb9442ca9667baccc6230fcd5c1c4b2d4d2870f4bd20681d4d47cfd15184"`,
|
||||
`"0xab8653edf9f51785664a643b47605a7ba3d917b5339a0724e7642c114d0e4738"`,
|
||||
}
|
||||
|
||||
for _, hash := range testcases {
|
||||
var h EthSubscriptionID
|
||||
err := h.UnmarshalJSON([]byte(hash))
|
||||
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, h.String(), strings.Replace(hash, `"`, "", -1))
|
||||
|
||||
jm, err := json.Marshal(h)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, hash, string(jm))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -291,7 +291,10 @@ func DumpActorState(i *ActorRegistry, act *types.Actor, b []byte) (interface{},
|
||||
|
||||
um := actInfo.vmActor.State()
|
||||
if um == nil {
|
||||
// TODO::FVM @arajasek I would like to assert that we have the empty object here
|
||||
if act.Code != EmptyObjectCid {
|
||||
return nil, xerrors.Errorf("actor with code %s should only have empty object (%s) as its Head, instead has %s", act.Code, EmptyObjectCid, act.Head)
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
if err := um.UnmarshalCBOR(bytes.NewReader(b)); err != nil {
|
||||
|
||||
@@ -1517,6 +1517,8 @@ func GetAsks(ctx context.Context, api lapi.FullNode) ([]QueriedAsk, error) {
|
||||
}
|
||||
}(miner)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}()
|
||||
|
||||
loop:
|
||||
@@ -1590,6 +1592,8 @@ loop:
|
||||
lk.Unlock()
|
||||
}(miner)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}()
|
||||
|
||||
loop2:
|
||||
|
||||
+24
-2
@@ -319,11 +319,33 @@ func GetFullNodeAPIV1Single(ctx *cli.Context) (v1api.FullNode, jsonrpc.ClientClo
|
||||
return v1API, closer, nil
|
||||
}
|
||||
|
||||
func GetFullNodeAPIV1(ctx *cli.Context) (v1api.FullNode, jsonrpc.ClientCloser, error) {
|
||||
type GetFullNodeOptions struct {
|
||||
ethSubHandler api.EthSubscriber
|
||||
}
|
||||
|
||||
type GetFullNodeOption func(*GetFullNodeOptions)
|
||||
|
||||
func FullNodeWithEthSubscribtionHandler(sh api.EthSubscriber) GetFullNodeOption {
|
||||
return func(opts *GetFullNodeOptions) {
|
||||
opts.ethSubHandler = sh
|
||||
}
|
||||
}
|
||||
|
||||
func GetFullNodeAPIV1(ctx *cli.Context, opts ...GetFullNodeOption) (v1api.FullNode, jsonrpc.ClientCloser, error) {
|
||||
if tn, ok := ctx.App.Metadata["testnode-full"]; ok {
|
||||
return tn.(v1api.FullNode), func() {}, nil
|
||||
}
|
||||
|
||||
var options GetFullNodeOptions
|
||||
for _, opt := range opts {
|
||||
opt(&options)
|
||||
}
|
||||
|
||||
var rpcOpts []jsonrpc.Option
|
||||
if options.ethSubHandler != nil {
|
||||
rpcOpts = append(rpcOpts, jsonrpc.WithClientHandler("Filecoin", options.ethSubHandler), jsonrpc.WithClientHandlerAlias("eth_subscription", "Filecoin.EthSubscription"))
|
||||
}
|
||||
|
||||
heads, err := GetRawAPIMulti(ctx, repo.FullNode, "v1")
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -337,7 +359,7 @@ func GetFullNodeAPIV1(ctx *cli.Context) (v1api.FullNode, jsonrpc.ClientCloser, e
|
||||
var closers []jsonrpc.ClientCloser
|
||||
|
||||
for _, head := range heads {
|
||||
v1api, closer, err := client.NewFullNodeRPCV1(ctx.Context, head.addr, head.header)
|
||||
v1api, closer, err := client.NewFullNodeRPCV1(ctx.Context, head.addr, head.header, rpcOpts...)
|
||||
if err != nil {
|
||||
log.Warnf("Not able to establish connection to node with addr: ", head.addr)
|
||||
continue
|
||||
|
||||
@@ -162,7 +162,9 @@ var runCmd = &cli.Command{
|
||||
log.Fatalf("Cannot register the view: %v", err)
|
||||
}
|
||||
|
||||
api, closer, err := lcli.GetFullNodeAPIV1(cctx)
|
||||
subHnd := gateway.NewEthSubHandler()
|
||||
|
||||
api, closer, err := lcli.GetFullNodeAPIV1(cctx, cliutil.FullNodeWithEthSubscribtionHandler(subHnd))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -195,7 +197,7 @@ var runCmd = &cli.Command{
|
||||
return xerrors.Errorf("failed to convert endpoint address to multiaddr: %w", err)
|
||||
}
|
||||
|
||||
gwapi := gateway.NewNode(api, lookbackCap, waitLookback, rateLimit, rateLimitTimeout)
|
||||
gwapi := gateway.NewNode(api, subHnd, lookbackCap, waitLookback, rateLimit, rateLimitTimeout)
|
||||
h, err := gateway.Handler(gwapi, api, perConnRateLimit, connPerMinute, serverOptions...)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to set up gateway HTTP handler")
|
||||
|
||||
@@ -291,6 +291,8 @@
|
||||
* [WalletSignMessage](#WalletSignMessage)
|
||||
* [WalletValidateAddress](#WalletValidateAddress)
|
||||
* [WalletVerify](#WalletVerify)
|
||||
* [Web3](#Web3)
|
||||
* [Web3ClientVersion](#Web3ClientVersion)
|
||||
##
|
||||
|
||||
|
||||
@@ -2518,40 +2520,7 @@ Perms: write
|
||||
Inputs:
|
||||
```json
|
||||
[
|
||||
[
|
||||
55,
|
||||
105,
|
||||
12,
|
||||
254,
|
||||
198,
|
||||
193,
|
||||
191,
|
||||
76,
|
||||
59,
|
||||
146,
|
||||
136,
|
||||
199,
|
||||
165,
|
||||
215,
|
||||
131,
|
||||
233,
|
||||
135,
|
||||
49,
|
||||
233,
|
||||
11,
|
||||
10,
|
||||
76,
|
||||
23,
|
||||
124,
|
||||
42,
|
||||
55,
|
||||
76,
|
||||
122,
|
||||
148,
|
||||
39,
|
||||
53,
|
||||
94
|
||||
]
|
||||
"0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e"
|
||||
]
|
||||
```
|
||||
|
||||
@@ -2572,40 +2541,7 @@ Perms: write
|
||||
Inputs:
|
||||
```json
|
||||
[
|
||||
[
|
||||
55,
|
||||
105,
|
||||
12,
|
||||
254,
|
||||
198,
|
||||
193,
|
||||
191,
|
||||
76,
|
||||
59,
|
||||
146,
|
||||
136,
|
||||
199,
|
||||
165,
|
||||
215,
|
||||
131,
|
||||
233,
|
||||
135,
|
||||
49,
|
||||
233,
|
||||
11,
|
||||
10,
|
||||
76,
|
||||
23,
|
||||
124,
|
||||
42,
|
||||
55,
|
||||
76,
|
||||
122,
|
||||
148,
|
||||
39,
|
||||
53,
|
||||
94
|
||||
]
|
||||
"0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e"
|
||||
]
|
||||
```
|
||||
|
||||
@@ -2879,43 +2815,7 @@ Perms: write
|
||||
|
||||
Inputs: `null`
|
||||
|
||||
Response:
|
||||
```json
|
||||
[
|
||||
55,
|
||||
105,
|
||||
12,
|
||||
254,
|
||||
198,
|
||||
193,
|
||||
191,
|
||||
76,
|
||||
59,
|
||||
146,
|
||||
136,
|
||||
199,
|
||||
165,
|
||||
215,
|
||||
131,
|
||||
233,
|
||||
135,
|
||||
49,
|
||||
233,
|
||||
11,
|
||||
10,
|
||||
76,
|
||||
23,
|
||||
124,
|
||||
42,
|
||||
55,
|
||||
76,
|
||||
122,
|
||||
148,
|
||||
39,
|
||||
53,
|
||||
94
|
||||
]
|
||||
```
|
||||
Response: `"0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e"`
|
||||
|
||||
### EthNewFilter
|
||||
Installs a persistent filter based on given filter spec.
|
||||
@@ -2936,43 +2836,7 @@ Inputs:
|
||||
]
|
||||
```
|
||||
|
||||
Response:
|
||||
```json
|
||||
[
|
||||
55,
|
||||
105,
|
||||
12,
|
||||
254,
|
||||
198,
|
||||
193,
|
||||
191,
|
||||
76,
|
||||
59,
|
||||
146,
|
||||
136,
|
||||
199,
|
||||
165,
|
||||
215,
|
||||
131,
|
||||
233,
|
||||
135,
|
||||
49,
|
||||
233,
|
||||
11,
|
||||
10,
|
||||
76,
|
||||
23,
|
||||
124,
|
||||
42,
|
||||
55,
|
||||
76,
|
||||
122,
|
||||
148,
|
||||
39,
|
||||
53,
|
||||
94
|
||||
]
|
||||
```
|
||||
Response: `"0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e"`
|
||||
|
||||
### EthNewPendingTransactionFilter
|
||||
Installs a persistent filter to notify when new messages arrive in the message pool.
|
||||
@@ -2982,43 +2846,7 @@ Perms: write
|
||||
|
||||
Inputs: `null`
|
||||
|
||||
Response:
|
||||
```json
|
||||
[
|
||||
55,
|
||||
105,
|
||||
12,
|
||||
254,
|
||||
198,
|
||||
193,
|
||||
191,
|
||||
76,
|
||||
59,
|
||||
146,
|
||||
136,
|
||||
199,
|
||||
165,
|
||||
215,
|
||||
131,
|
||||
233,
|
||||
135,
|
||||
49,
|
||||
233,
|
||||
11,
|
||||
10,
|
||||
76,
|
||||
23,
|
||||
124,
|
||||
42,
|
||||
55,
|
||||
76,
|
||||
122,
|
||||
148,
|
||||
39,
|
||||
53,
|
||||
94
|
||||
]
|
||||
```
|
||||
Response: `"0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e"`
|
||||
|
||||
### EthProtocolVersion
|
||||
|
||||
@@ -3058,57 +2886,11 @@ Perms: write
|
||||
Inputs:
|
||||
```json
|
||||
[
|
||||
"string value",
|
||||
{
|
||||
"topics": [
|
||||
[
|
||||
"0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e"
|
||||
]
|
||||
]
|
||||
}
|
||||
"Bw=="
|
||||
]
|
||||
```
|
||||
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"subscription": [
|
||||
55,
|
||||
105,
|
||||
12,
|
||||
254,
|
||||
198,
|
||||
193,
|
||||
191,
|
||||
76,
|
||||
59,
|
||||
146,
|
||||
136,
|
||||
199,
|
||||
165,
|
||||
215,
|
||||
131,
|
||||
233,
|
||||
135,
|
||||
49,
|
||||
233,
|
||||
11,
|
||||
10,
|
||||
76,
|
||||
23,
|
||||
124,
|
||||
42,
|
||||
55,
|
||||
76,
|
||||
122,
|
||||
148,
|
||||
39,
|
||||
53,
|
||||
94
|
||||
],
|
||||
"result": {}
|
||||
}
|
||||
```
|
||||
Response: `"0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e"`
|
||||
|
||||
### EthUninstallFilter
|
||||
Uninstalls a filter with given id.
|
||||
@@ -3119,40 +2901,7 @@ Perms: write
|
||||
Inputs:
|
||||
```json
|
||||
[
|
||||
[
|
||||
55,
|
||||
105,
|
||||
12,
|
||||
254,
|
||||
198,
|
||||
193,
|
||||
191,
|
||||
76,
|
||||
59,
|
||||
146,
|
||||
136,
|
||||
199,
|
||||
165,
|
||||
215,
|
||||
131,
|
||||
233,
|
||||
135,
|
||||
49,
|
||||
233,
|
||||
11,
|
||||
10,
|
||||
76,
|
||||
23,
|
||||
124,
|
||||
42,
|
||||
55,
|
||||
76,
|
||||
122,
|
||||
148,
|
||||
39,
|
||||
53,
|
||||
94
|
||||
]
|
||||
"0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e"
|
||||
]
|
||||
```
|
||||
|
||||
@@ -3167,40 +2916,7 @@ Perms: write
|
||||
Inputs:
|
||||
```json
|
||||
[
|
||||
[
|
||||
55,
|
||||
105,
|
||||
12,
|
||||
254,
|
||||
198,
|
||||
193,
|
||||
191,
|
||||
76,
|
||||
59,
|
||||
146,
|
||||
136,
|
||||
199,
|
||||
165,
|
||||
215,
|
||||
131,
|
||||
233,
|
||||
135,
|
||||
49,
|
||||
233,
|
||||
11,
|
||||
10,
|
||||
76,
|
||||
23,
|
||||
124,
|
||||
42,
|
||||
55,
|
||||
76,
|
||||
122,
|
||||
148,
|
||||
39,
|
||||
53,
|
||||
94
|
||||
]
|
||||
"0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e"
|
||||
]
|
||||
```
|
||||
|
||||
@@ -9207,3 +8923,16 @@ Inputs:
|
||||
|
||||
Response: `true`
|
||||
|
||||
## Web3
|
||||
|
||||
|
||||
### Web3ClientVersion
|
||||
Returns the client version
|
||||
|
||||
|
||||
Perms: read
|
||||
|
||||
Inputs: `null`
|
||||
|
||||
Response: `"string value"`
|
||||
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
package gateway
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/filecoin-project/go-jsonrpc"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain/types/ethtypes"
|
||||
)
|
||||
|
||||
type EthSubHandler struct {
|
||||
queued map[ethtypes.EthSubscriptionID][]ethtypes.EthSubscriptionResponse
|
||||
sinks map[ethtypes.EthSubscriptionID]func(context.Context, *ethtypes.EthSubscriptionResponse) error
|
||||
|
||||
lk sync.Mutex
|
||||
}
|
||||
|
||||
func NewEthSubHandler() *EthSubHandler {
|
||||
return &EthSubHandler{
|
||||
queued: make(map[ethtypes.EthSubscriptionID][]ethtypes.EthSubscriptionResponse),
|
||||
sinks: make(map[ethtypes.EthSubscriptionID]func(context.Context, *ethtypes.EthSubscriptionResponse) error),
|
||||
}
|
||||
}
|
||||
|
||||
func (e *EthSubHandler) AddSub(ctx context.Context, id ethtypes.EthSubscriptionID, sink func(context.Context, *ethtypes.EthSubscriptionResponse) error) error {
|
||||
e.lk.Lock()
|
||||
defer e.lk.Unlock()
|
||||
|
||||
for _, p := range e.queued[id] {
|
||||
p := p // copy
|
||||
if err := sink(ctx, &p); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
delete(e.queued, id)
|
||||
e.sinks[id] = sink
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *EthSubHandler) RemoveSub(id ethtypes.EthSubscriptionID) {
|
||||
e.lk.Lock()
|
||||
defer e.lk.Unlock()
|
||||
|
||||
delete(e.sinks, id)
|
||||
delete(e.queued, id)
|
||||
}
|
||||
|
||||
func (e *EthSubHandler) EthSubscription(ctx context.Context, r jsonrpc.RawParams) error {
|
||||
p, err := jsonrpc.DecodeParams[ethtypes.EthSubscriptionResponse](r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
e.lk.Lock()
|
||||
|
||||
sink := e.sinks[p.SubscriptionID]
|
||||
|
||||
if sink == nil {
|
||||
e.queued[p.SubscriptionID] = append(e.queued[p.SubscriptionID], p)
|
||||
e.lk.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
e.lk.Unlock()
|
||||
|
||||
return sink(ctx, &p) // todo track errors and auto-unsubscribe on rpc conn close?
|
||||
}
|
||||
|
||||
var _ api.EthSubscriber = (*EthSubHandler)(nil)
|
||||
+3
-3
@@ -27,14 +27,14 @@ const perConnLimiterKey perConnLimiterKeyType = "limiter"
|
||||
|
||||
type filterTrackerKeyType string
|
||||
|
||||
const filterTrackerKey filterTrackerKeyType = "filterTracker"
|
||||
const statefulCallTrackerKey filterTrackerKeyType = "statefulCallTracker"
|
||||
|
||||
// Handler returns a gateway http.Handler, to be mounted as-is on the server.
|
||||
func Handler(gwapi lapi.Gateway, api lapi.FullNode, rateLimit int64, connPerMinute int64, opts ...jsonrpc.ServerOption) (http.Handler, error) {
|
||||
m := mux.NewRouter()
|
||||
|
||||
serveRpc := func(path string, hnd interface{}) {
|
||||
rpcServer := jsonrpc.NewServer(append(opts, jsonrpc.WithServerErrors(lapi.RPCErrors))...)
|
||||
rpcServer := jsonrpc.NewServer(append(opts, jsonrpc.WithReverseClient[lapi.EthSubscriberMethods]("Filecoin"), jsonrpc.WithServerErrors(lapi.RPCErrors))...)
|
||||
rpcServer.Register("Filecoin", hnd)
|
||||
rpcServer.AliasMethod("rpc.discover", "Filecoin.Discover")
|
||||
|
||||
@@ -90,7 +90,7 @@ func (h RateLimiterHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
r = r.WithContext(context.WithValue(r.Context(), perConnLimiterKey, h.limiter))
|
||||
|
||||
// also add a filter tracker to the context
|
||||
r = r.WithContext(context.WithValue(r.Context(), filterTrackerKey, newFilterTracker()))
|
||||
r = r.WithContext(context.WithValue(r.Context(), statefulCallTrackerKey, newStatefulCallTracker()))
|
||||
|
||||
h.handler.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
+5
-2
@@ -12,6 +12,7 @@ import (
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-bitfield"
|
||||
"github.com/filecoin-project/go-jsonrpc"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/dline"
|
||||
"github.com/filecoin-project/go-state-types/network"
|
||||
@@ -117,7 +118,7 @@ type TargetAPI interface {
|
||||
EthNewBlockFilter(ctx context.Context) (ethtypes.EthFilterID, error)
|
||||
EthNewPendingTransactionFilter(ctx context.Context) (ethtypes.EthFilterID, error)
|
||||
EthUninstallFilter(ctx context.Context, id ethtypes.EthFilterID) (bool, error)
|
||||
EthSubscribe(ctx context.Context, eventType string, params *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error)
|
||||
EthSubscribe(ctx context.Context, params jsonrpc.RawParams) (ethtypes.EthSubscriptionID, error)
|
||||
EthUnsubscribe(ctx context.Context, id ethtypes.EthSubscriptionID) (bool, error)
|
||||
}
|
||||
|
||||
@@ -125,6 +126,7 @@ var _ TargetAPI = *new(api.FullNode) // gateway depends on latest
|
||||
|
||||
type Node struct {
|
||||
target TargetAPI
|
||||
subHnd *EthSubHandler
|
||||
lookbackCap time.Duration
|
||||
stateWaitLookbackLimit abi.ChainEpoch
|
||||
rateLimiter *rate.Limiter
|
||||
@@ -141,7 +143,7 @@ var (
|
||||
)
|
||||
|
||||
// NewNode creates a new gateway node.
|
||||
func NewNode(api TargetAPI, lookbackCap time.Duration, stateWaitLookbackLimit abi.ChainEpoch, rateLimit int64, rateLimitTimeout time.Duration) *Node {
|
||||
func NewNode(api TargetAPI, sHnd *EthSubHandler, lookbackCap time.Duration, stateWaitLookbackLimit abi.ChainEpoch, rateLimit int64, rateLimitTimeout time.Duration) *Node {
|
||||
var limit rate.Limit
|
||||
if rateLimit == 0 {
|
||||
limit = rate.Inf
|
||||
@@ -150,6 +152,7 @@ func NewNode(api TargetAPI, lookbackCap time.Duration, stateWaitLookbackLimit ab
|
||||
}
|
||||
return &Node{
|
||||
target: api,
|
||||
subHnd: sHnd,
|
||||
lookbackCap: lookbackCap,
|
||||
stateWaitLookbackLimit: stateWaitLookbackLimit,
|
||||
rateLimiter: rate.NewLimiter(limit, stateRateLimitTokens),
|
||||
|
||||
@@ -89,7 +89,7 @@ func TestGatewayAPIChainGetTipSetByHeight(t *testing.T) {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
mock := &mockGatewayDepsAPI{}
|
||||
a := NewNode(mock, DefaultLookbackCap, DefaultStateWaitLookbackLimit, 0, time.Minute)
|
||||
a := NewNode(mock, nil, DefaultLookbackCap, DefaultStateWaitLookbackLimit, 0, time.Minute)
|
||||
|
||||
// Create tipsets from genesis up to tskh and return the highest
|
||||
ts := mock.createTipSets(tt.args.tskh, tt.args.genesisTS)
|
||||
@@ -245,7 +245,7 @@ func TestGatewayVersion(t *testing.T) {
|
||||
//stm: @GATEWAY_NODE_GET_VERSION_001
|
||||
ctx := context.Background()
|
||||
mock := &mockGatewayDepsAPI{}
|
||||
a := NewNode(mock, DefaultLookbackCap, DefaultStateWaitLookbackLimit, 0, time.Minute)
|
||||
a := NewNode(mock, nil, DefaultLookbackCap, DefaultStateWaitLookbackLimit, 0, time.Minute)
|
||||
|
||||
v, err := a.Version(ctx)
|
||||
require.NoError(t, err)
|
||||
@@ -256,7 +256,7 @@ func TestGatewayLimitTokensAvailable(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
mock := &mockGatewayDepsAPI{}
|
||||
tokens := 3
|
||||
a := NewNode(mock, DefaultLookbackCap, DefaultStateWaitLookbackLimit, int64(tokens), time.Minute)
|
||||
a := NewNode(mock, nil, DefaultLookbackCap, DefaultStateWaitLookbackLimit, int64(tokens), time.Minute)
|
||||
require.NoError(t, a.limit(ctx, tokens), "requests should not be limited when there are enough tokens available")
|
||||
}
|
||||
|
||||
@@ -264,7 +264,7 @@ func TestGatewayLimitTokensNotAvailable(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
mock := &mockGatewayDepsAPI{}
|
||||
tokens := 3
|
||||
a := NewNode(mock, DefaultLookbackCap, DefaultStateWaitLookbackLimit, int64(1), time.Millisecond)
|
||||
a := NewNode(mock, nil, DefaultLookbackCap, DefaultStateWaitLookbackLimit, int64(1), time.Millisecond)
|
||||
var err error
|
||||
// try to be rate limited
|
||||
for i := 0; i <= 1000; i++ {
|
||||
|
||||
+88
-14
@@ -3,12 +3,14 @@ package gateway
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-jsonrpc"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
|
||||
@@ -352,7 +354,7 @@ func (gw *Node) EthGetFilterChanges(ctx context.Context, id ethtypes.EthFilterID
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ft := filterTrackerFromContext(ctx)
|
||||
ft := statefulCallFromContext(ctx)
|
||||
ft.lk.Lock()
|
||||
_, ok := ft.userFilters[id]
|
||||
ft.lk.Unlock()
|
||||
@@ -369,7 +371,7 @@ func (gw *Node) EthGetFilterLogs(ctx context.Context, id ethtypes.EthFilterID) (
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ft := filterTrackerFromContext(ctx)
|
||||
ft := statefulCallFromContext(ctx)
|
||||
ft.lk.Lock()
|
||||
_, ok := ft.userFilters[id]
|
||||
ft.lk.Unlock()
|
||||
@@ -417,7 +419,7 @@ func (gw *Node) EthUninstallFilter(ctx context.Context, id ethtypes.EthFilterID)
|
||||
}
|
||||
|
||||
// check if the filter belongs to this connection
|
||||
ft := filterTrackerFromContext(ctx)
|
||||
ft := statefulCallFromContext(ctx)
|
||||
ft.lk.Lock()
|
||||
defer ft.lk.Unlock()
|
||||
|
||||
@@ -434,18 +436,88 @@ func (gw *Node) EthUninstallFilter(ctx context.Context, id ethtypes.EthFilterID)
|
||||
return ok, nil
|
||||
}
|
||||
|
||||
func (gw *Node) EthSubscribe(ctx context.Context, eventType string, params *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error) {
|
||||
return nil, xerrors.Errorf("not implemented")
|
||||
func (gw *Node) EthSubscribe(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthSubscriptionID, error) {
|
||||
// validate params
|
||||
_, err := jsonrpc.DecodeParams[ethtypes.EthSubscribeParams](p)
|
||||
if err != nil {
|
||||
return ethtypes.EthSubscriptionID{}, xerrors.Errorf("decoding params: %w", err)
|
||||
}
|
||||
|
||||
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||
return ethtypes.EthSubscriptionID{}, err
|
||||
}
|
||||
|
||||
if gw.subHnd == nil {
|
||||
return ethtypes.EthSubscriptionID{}, xerrors.New("subscription support not enabled")
|
||||
}
|
||||
|
||||
ethCb, ok := jsonrpc.ExtractReverseClient[api.EthSubscriberMethods](ctx)
|
||||
if !ok {
|
||||
return ethtypes.EthSubscriptionID{}, xerrors.Errorf("connection doesn't support callbacks")
|
||||
}
|
||||
|
||||
ft := statefulCallFromContext(ctx)
|
||||
ft.lk.Lock()
|
||||
defer ft.lk.Unlock()
|
||||
|
||||
if len(ft.userSubscriptions) >= EthMaxFiltersPerConn {
|
||||
return ethtypes.EthSubscriptionID{}, fmt.Errorf("too many subscriptions")
|
||||
}
|
||||
|
||||
sub, err := gw.target.EthSubscribe(ctx, p)
|
||||
if err != nil {
|
||||
return ethtypes.EthSubscriptionID{}, err
|
||||
}
|
||||
|
||||
err = gw.subHnd.AddSub(ctx, sub, func(ctx context.Context, response *ethtypes.EthSubscriptionResponse) error {
|
||||
outParam, err := json.Marshal(response)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ethCb.EthSubscription(ctx, outParam)
|
||||
})
|
||||
if err != nil {
|
||||
return ethtypes.EthSubscriptionID{}, err
|
||||
}
|
||||
|
||||
ft.userSubscriptions[sub] = time.Now()
|
||||
|
||||
return sub, err
|
||||
}
|
||||
|
||||
func (gw *Node) EthUnsubscribe(ctx context.Context, id ethtypes.EthSubscriptionID) (bool, error) {
|
||||
return false, xerrors.Errorf("not implemented")
|
||||
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// check if the filter belongs to this connection
|
||||
ft := statefulCallFromContext(ctx)
|
||||
ft.lk.Lock()
|
||||
defer ft.lk.Unlock()
|
||||
|
||||
if _, ok := ft.userSubscriptions[id]; !ok {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
ok, err := gw.target.EthUnsubscribe(ctx, id)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
delete(ft.userSubscriptions, id)
|
||||
|
||||
if gw.subHnd != nil {
|
||||
gw.subHnd.RemoveSub(id)
|
||||
}
|
||||
|
||||
return ok, nil
|
||||
}
|
||||
|
||||
var EthMaxFiltersPerConn = 16 // todo make this configurable
|
||||
|
||||
func addUserFilterLimited(ctx context.Context, cb func() (ethtypes.EthFilterID, error)) (ethtypes.EthFilterID, error) {
|
||||
ft := filterTrackerFromContext(ctx)
|
||||
ft := statefulCallFromContext(ctx)
|
||||
ft.lk.Lock()
|
||||
defer ft.lk.Unlock()
|
||||
|
||||
@@ -463,19 +535,21 @@ func addUserFilterLimited(ctx context.Context, cb func() (ethtypes.EthFilterID,
|
||||
return id, nil
|
||||
}
|
||||
|
||||
func filterTrackerFromContext(ctx context.Context) *filterTracker {
|
||||
return ctx.Value(filterTrackerKey).(*filterTracker)
|
||||
func statefulCallFromContext(ctx context.Context) *statefulCallTracker {
|
||||
return ctx.Value(statefulCallTrackerKey).(*statefulCallTracker)
|
||||
}
|
||||
|
||||
type filterTracker struct {
|
||||
type statefulCallTracker struct {
|
||||
lk sync.Mutex
|
||||
|
||||
userFilters map[ethtypes.EthFilterID]time.Time
|
||||
userFilters map[ethtypes.EthFilterID]time.Time
|
||||
userSubscriptions map[ethtypes.EthSubscriptionID]time.Time
|
||||
}
|
||||
|
||||
// called per request (ws connection)
|
||||
func newFilterTracker() *filterTracker {
|
||||
return &filterTracker{
|
||||
userFilters: make(map[ethtypes.EthFilterID]time.Time),
|
||||
func newStatefulCallTracker() *statefulCallTracker {
|
||||
return &statefulCallTracker{
|
||||
userFilters: make(map[ethtypes.EthFilterID]time.Time),
|
||||
userSubscriptions: make(map[ethtypes.EthSubscriptionID]time.Time),
|
||||
}
|
||||
}
|
||||
|
||||
+5
-3
@@ -259,7 +259,7 @@ func generate(path, pkg, outpkg, outfile string) error {
|
||||
if len(tf) != 2 {
|
||||
continue
|
||||
}
|
||||
if tf[0] != "perm" { // todo: allow more tag types
|
||||
if tf[0] != "perm" && tf[0] != "rpc_method" && tf[0] != "notify" { // todo: allow more tag types
|
||||
continue
|
||||
}
|
||||
info.Methods[mname].Tags[tf[0]] = tf
|
||||
@@ -302,12 +302,14 @@ type {{.Num}}Struct struct {
|
||||
{{range .Include}}
|
||||
{{.}}Struct
|
||||
{{end}}
|
||||
Internal struct {
|
||||
Internal {{.Num}}Methods
|
||||
}
|
||||
|
||||
type {{.Num}}Methods struct {
|
||||
{{range .Methods}}
|
||||
{{.Num}} func({{.NamedParams}}) ({{.Results}}) `+"`"+`{{range .Tags}}{{index . 0}}:"{{index . 1}}"{{end}}`+"`"+`
|
||||
{{end}}
|
||||
}
|
||||
}
|
||||
|
||||
type {{.Num}}Stub struct {
|
||||
{{range .Include}}
|
||||
|
||||
@@ -40,7 +40,7 @@ require (
|
||||
github.com/filecoin-project/go-fil-commcid v0.1.0
|
||||
github.com/filecoin-project/go-fil-commp-hashhash v0.1.0
|
||||
github.com/filecoin-project/go-fil-markets v1.25.2
|
||||
github.com/filecoin-project/go-jsonrpc v0.1.9
|
||||
github.com/filecoin-project/go-jsonrpc v0.2.0
|
||||
github.com/filecoin-project/go-legs v0.4.4
|
||||
github.com/filecoin-project/go-padreader v0.0.1
|
||||
github.com/filecoin-project/go-paramfetch v0.0.4
|
||||
|
||||
@@ -340,8 +340,8 @@ github.com/filecoin-project/go-hamt-ipld/v2 v2.0.0/go.mod h1:7aWZdaQ1b16BVoQUYR+
|
||||
github.com/filecoin-project/go-hamt-ipld/v3 v3.0.1/go.mod h1:gXpNmr3oQx8l3o7qkGyDjJjYSRX7hp/FGOStdqrWyDI=
|
||||
github.com/filecoin-project/go-hamt-ipld/v3 v3.1.0 h1:rVVNq0x6RGQIzCo1iiJlGFm9AGIZzeifggxtKMU7zmI=
|
||||
github.com/filecoin-project/go-hamt-ipld/v3 v3.1.0/go.mod h1:bxmzgT8tmeVQA1/gvBwFmYdT8SOFUwB3ovSUfG1Ux0g=
|
||||
github.com/filecoin-project/go-jsonrpc v0.1.9 h1:HRWLxo7HAWzI3xZGeFG4LZJoYpms+Q+8kwmMTLnyS3A=
|
||||
github.com/filecoin-project/go-jsonrpc v0.1.9/go.mod h1:XBBpuKIMaXIIzeqzO1iucq4GvbF8CxmXRFoezRh+Cx4=
|
||||
github.com/filecoin-project/go-jsonrpc v0.2.0 h1:lhcu0Oa7xxwdclU4EyBPgnZihiZOaTFiAnW6P3NRqko=
|
||||
github.com/filecoin-project/go-jsonrpc v0.2.0/go.mod h1:jBSvPTl8V1N7gSTuCR4bis8wnQnIjHbRPpROol6iQKM=
|
||||
github.com/filecoin-project/go-legs v0.4.4 h1:mpMmAOOnamaz0CV9rgeKhEWA8j9kMC+f+UGCGrxKaZo=
|
||||
github.com/filecoin-project/go-legs v0.4.4/go.mod h1:JQ3hA6xpJdbR8euZ2rO0jkxaMxeidXf0LDnVuqPAe9s=
|
||||
github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20/go.mod h1:mPn+LRRd5gEKNAtc+r3ScpW2JRU/pj4NBKdADYWHiak=
|
||||
@@ -824,7 +824,6 @@ github.com/ipfs/go-log/v2 v2.0.1/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBW
|
||||
github.com/ipfs/go-log/v2 v2.0.2/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0=
|
||||
github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0=
|
||||
github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw=
|
||||
github.com/ipfs/go-log/v2 v2.0.8/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw=
|
||||
github.com/ipfs/go-log/v2 v2.1.1/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM=
|
||||
github.com/ipfs/go-log/v2 v2.1.2-0.20200626104915-0016c0b4b3e4/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM=
|
||||
github.com/ipfs/go-log/v2 v2.1.2/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM=
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
608060405234801561001057600080fd5b5061025b806100206000396000f3fe60806040526004361061001e5760003560e01c8063cb7786d714610023575b600080fd5b61003d60048036038101906100389190610129565b61003f565b005b600083036100d15760008111156100cc573073ffffffffffffffffffffffffffffffffffffffff1663cb7786d7838460018561007b91906101ab565b6040518463ffffffff1660e01b8152600401610099939291906101ee565b600060405180830381600087803b1580156100b357600080fd5b505af11580156100c7573d6000803e3d6000fd5b505050505b6100e9565b6100e86001846100e191906101ab565b838361003f565b5b505050565b600080fd5b6000819050919050565b610106816100f3565b811461011157600080fd5b50565b600081359050610123816100fd565b92915050565b600080600060608486031215610142576101416100ee565b5b600061015086828701610114565b935050602061016186828701610114565b925050604061017286828701610114565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006101b6826100f3565b91506101c1836100f3565b92508282039050818111156101d9576101d861017c565b5b92915050565b6101e8816100f3565b82525050565b600060608201905061020360008301866101df565b61021060208301856101df565b61021d60408301846101df565b94935050505056fea26469706673582212209a21ff59c642e2970917c07bf498271c2a6df8e3929677952c0c2d8031db15cc64736f6c63430008110033
|
||||
@@ -0,0 +1,16 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.17;
|
||||
|
||||
contract StackRecCall {
|
||||
function exec1(uint256 n, uint256 m, uint256 r) public payable {
|
||||
if(n == 0) {
|
||||
if(r > 0) {
|
||||
StackRecCall(address(this)).exec1(m, m, r-1);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
exec1(n-1, m, r);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
608060405234801561001057600080fd5b50610162806100206000396000f3fe60806040526004361061001e5760003560e01c8063c38e07dd14610023575b600080fd5b61003d6004803603810190610038919061009c565b61003f565b005b600081031561005e5761005d60018261005891906100f8565b61003f565b5b50565b600080fd5b6000819050919050565b61007981610066565b811461008457600080fd5b50565b60008135905061009681610070565b92915050565b6000602082840312156100b2576100b1610061565b5b60006100c084828501610087565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061010382610066565b915061010e83610066565b9250828203905081811115610126576101256100c9565b5b9291505056fea2646970667358221220ee8f18bfd33b1e0156cfe68e9071dd32960b370c7e63ec53c62dd48e28cb5d3b64736f6c63430008110033
|
||||
@@ -0,0 +1,12 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.17;
|
||||
|
||||
contract StackSelf {
|
||||
function exec1(uint256 n) public payable {
|
||||
if(n == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
exec1(n-1);
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,8 @@ import (
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
builtin2 "github.com/filecoin-project/go-state-types/builtin"
|
||||
"github.com/filecoin-project/go-state-types/builtin/v10/eam"
|
||||
"github.com/filecoin-project/go-state-types/exitcode"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
@@ -70,7 +72,7 @@ func TestEthAccountAbstraction(t *testing.T) {
|
||||
msgFromPlaceholder, err = client.GasEstimateMessageGas(ctx, msgFromPlaceholder, nil, types.EmptyTSK)
|
||||
require.NoError(t, err)
|
||||
|
||||
txArgs, err := ethtypes.EthTxArgsFromMessage(msgFromPlaceholder)
|
||||
txArgs, err := ethtypes.EthTxArgsFromUnsignedEthMessage(msgFromPlaceholder)
|
||||
require.NoError(t, err)
|
||||
|
||||
digest, err := txArgs.ToRlpUnsignedMsg()
|
||||
@@ -106,7 +108,7 @@ func TestEthAccountAbstraction(t *testing.T) {
|
||||
msgFromPlaceholder, err = client.GasEstimateMessageGas(ctx, msgFromPlaceholder, nil, types.EmptyTSK)
|
||||
require.NoError(t, err)
|
||||
|
||||
txArgs, err = ethtypes.EthTxArgsFromMessage(msgFromPlaceholder)
|
||||
txArgs, err = ethtypes.EthTxArgsFromUnsignedEthMessage(msgFromPlaceholder)
|
||||
require.NoError(t, err)
|
||||
|
||||
digest, err = txArgs.ToRlpUnsignedMsg()
|
||||
@@ -178,7 +180,7 @@ func TestEthAccountAbstractionFailure(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
msgFromPlaceholder.Value = abi.TokenAmount(types.MustParseFIL("1000"))
|
||||
txArgs, err := ethtypes.EthTxArgsFromMessage(msgFromPlaceholder)
|
||||
txArgs, err := ethtypes.EthTxArgsFromUnsignedEthMessage(msgFromPlaceholder)
|
||||
require.NoError(t, err)
|
||||
|
||||
digest, err := txArgs.ToRlpUnsignedMsg()
|
||||
@@ -216,7 +218,7 @@ func TestEthAccountAbstractionFailure(t *testing.T) {
|
||||
msgFromPlaceholder, err = client.GasEstimateMessageGas(ctx, msgFromPlaceholder, nil, types.EmptyTSK)
|
||||
require.NoError(t, err)
|
||||
|
||||
txArgs, err = ethtypes.EthTxArgsFromMessage(msgFromPlaceholder)
|
||||
txArgs, err = ethtypes.EthTxArgsFromUnsignedEthMessage(msgFromPlaceholder)
|
||||
require.NoError(t, err)
|
||||
|
||||
digest, err = txArgs.ToRlpUnsignedMsg()
|
||||
@@ -313,3 +315,51 @@ func TestEthAccountAbstractionFailsFromEvmActor(t *testing.T) {
|
||||
require.Error(t, err, "expected gas estimation to fail")
|
||||
require.Contains(t, err.Error(), "SysErrSenderInvalid")
|
||||
}
|
||||
|
||||
func TestEthAccountManagerPermissions(t *testing.T) {
|
||||
kit.QuietMiningLogs()
|
||||
|
||||
client, _, ens := kit.EnsembleMinimal(t, kit.MockProofs(), kit.ThroughRPC())
|
||||
ens.InterconnectAll().BeginMining(10 * time.Millisecond)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
||||
defer cancel()
|
||||
|
||||
// setup f1/f3/f4 accounts
|
||||
|
||||
wsp, err := client.WalletNew(ctx, types.KTSecp256k1)
|
||||
require.NoError(t, err)
|
||||
|
||||
wbl, err := client.WalletNew(ctx, types.KTBLS)
|
||||
require.NoError(t, err)
|
||||
|
||||
wdl, err := client.WalletNew(ctx, types.KTDelegated)
|
||||
require.NoError(t, err)
|
||||
|
||||
def := client.DefaultKey.Address
|
||||
|
||||
// send some funds
|
||||
client.ExpectSend(ctx, def, wsp, types.FromFil(10), "")
|
||||
client.ExpectSend(ctx, def, wbl, types.FromFil(10), "")
|
||||
client.ExpectSend(ctx, def, wdl, types.FromFil(10), "")
|
||||
require.NoError(t, err)
|
||||
|
||||
// make sure that EAM only allows CreateExternal to be called by accounts
|
||||
client.ExpectSend(ctx, wsp, builtin2.EthereumAddressManagerActorAddr, big.Zero(), "not one of supported (18)", client.MakeSendCall(builtin2.MethodsEAM.Create, &eam.CreateParams{Nonce: 0}))
|
||||
client.ExpectSend(ctx, wbl, builtin2.EthereumAddressManagerActorAddr, big.Zero(), "not one of supported (18)", client.MakeSendCall(builtin2.MethodsEAM.Create, &eam.CreateParams{Nonce: 0}))
|
||||
client.ExpectSend(ctx, wdl, builtin2.EthereumAddressManagerActorAddr, big.Zero(), "not one of supported (18)", client.MakeSendCall(builtin2.MethodsEAM.Create, &eam.CreateParams{Nonce: 0}))
|
||||
|
||||
client.ExpectSend(ctx, wsp, builtin2.EthereumAddressManagerActorAddr, big.Zero(), "not one of supported (18)", client.MakeSendCall(builtin2.MethodsEAM.Create2, &eam.Create2Params{}))
|
||||
client.ExpectSend(ctx, wbl, builtin2.EthereumAddressManagerActorAddr, big.Zero(), "not one of supported (18)", client.MakeSendCall(builtin2.MethodsEAM.Create2, &eam.Create2Params{}))
|
||||
client.ExpectSend(ctx, wdl, builtin2.EthereumAddressManagerActorAddr, big.Zero(), "not one of supported (18)", client.MakeSendCall(builtin2.MethodsEAM.Create2, &eam.Create2Params{}))
|
||||
|
||||
contractHex, err := os.ReadFile("contracts/SimpleCoin.hex")
|
||||
require.NoError(t, err)
|
||||
contract, err := hex.DecodeString(string(contractHex))
|
||||
require.NoError(t, err)
|
||||
contractParams := abi.CborBytes(contract)
|
||||
|
||||
client.ExpectSend(ctx, wsp, builtin2.EthereumAddressManagerActorAddr, big.Zero(), "", client.MakeSendCall(builtin2.MethodsEAM.CreateExternal, &contractParams))
|
||||
client.ExpectSend(ctx, wbl, builtin2.EthereumAddressManagerActorAddr, big.Zero(), "", client.MakeSendCall(builtin2.MethodsEAM.CreateExternal, &contractParams))
|
||||
client.ExpectSend(ctx, wdl, builtin2.EthereumAddressManagerActorAddr, big.Zero(), "", client.MakeSendCall(builtin2.MethodsEAM.CreateExternal, &contractParams))
|
||||
}
|
||||
|
||||
+846
-584
File diff suppressed because it is too large
Load Diff
@@ -83,6 +83,11 @@ func TestValueTransferValidSignature(t *testing.T) {
|
||||
|
||||
// Success.
|
||||
require.EqualValues(t, ethtypes.EthUint64(0x1), receipt.Status)
|
||||
|
||||
ethTx, err := client.EthGetTransactionByHash(ctx, &hash)
|
||||
require.Nil(t, err)
|
||||
require.EqualValues(t, ethAddr, ethTx.From)
|
||||
|
||||
}
|
||||
|
||||
func TestLegacyTransaction(t *testing.T) {
|
||||
|
||||
+79
-2
@@ -2,6 +2,7 @@ package itests
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -10,6 +11,7 @@ import (
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
builtintypes "github.com/filecoin-project/go-state-types/builtin"
|
||||
"github.com/filecoin-project/go-state-types/exitcode"
|
||||
"github.com/filecoin-project/go-state-types/manifest"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
@@ -38,9 +40,9 @@ func inputDataFromFrom(ctx context.Context, t *testing.T, client *kit.TestFullNo
|
||||
|
||||
func setupFEVMTest(t *testing.T) (context.Context, context.CancelFunc, *kit.TestFullNode) {
|
||||
kit.QuietMiningLogs()
|
||||
blockTime := 100 * time.Millisecond
|
||||
blockTime := 5 * time.Millisecond
|
||||
client, _, ens := kit.EnsembleMinimal(t, kit.MockProofs(), kit.ThroughRPC())
|
||||
ens.InterconnectAll().BeginMining(blockTime)
|
||||
ens.InterconnectAll().BeginMiningMustPost(blockTime)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
||||
return ctx, cancel, client
|
||||
}
|
||||
@@ -139,3 +141,78 @@ func TestEVMRpcDisable(t *testing.T) {
|
||||
_, err := client.EthBlockNumber(context.Background())
|
||||
require.ErrorContains(t, err, "module disabled, enable with Fevm.EnableEthRPC")
|
||||
}
|
||||
|
||||
// TestFEVMRecursiveFuncCall deploys a contract and makes a recursive function calls
|
||||
func TestFEVMRecursiveFuncCall(t *testing.T) {
|
||||
ctx, cancel, client := setupFEVMTest(t)
|
||||
defer cancel()
|
||||
|
||||
//install contract Actor
|
||||
filenameActor := "contracts/StackFunc.hex"
|
||||
fromAddr, actorAddr := client.EVM().DeployContractFromFilename(ctx, filenameActor)
|
||||
|
||||
testN := func(n int, ex exitcode.ExitCode) func(t *testing.T) {
|
||||
return func(t *testing.T) {
|
||||
inputData := make([]byte, 32)
|
||||
binary.BigEndian.PutUint64(inputData[24:], uint64(n))
|
||||
|
||||
client.EVM().InvokeContractByFuncNameExpectExit(ctx, fromAddr, actorAddr, "exec1(uint256)", inputData, ex)
|
||||
}
|
||||
}
|
||||
|
||||
t.Run("n=0", testN(0, exitcode.Ok))
|
||||
t.Run("n=1", testN(1, exitcode.Ok))
|
||||
t.Run("n=20", testN(20, exitcode.Ok))
|
||||
t.Run("n=200", testN(200, exitcode.Ok))
|
||||
t.Run("n=507", testN(507, exitcode.Ok))
|
||||
t.Run("n=508", testN(508, exitcode.ExitCode(23))) // 23 means stack overflow
|
||||
}
|
||||
|
||||
// TestFEVMRecursiveActorCall deploys a contract and makes a recursive actor calls
|
||||
func TestFEVMRecursiveActorCall(t *testing.T) {
|
||||
ctx, cancel, client := setupFEVMTest(t)
|
||||
defer cancel()
|
||||
|
||||
//install contract Actor
|
||||
filenameActor := "contracts/RecCall.hex"
|
||||
fromAddr, actorAddr := client.EVM().DeployContractFromFilename(ctx, filenameActor)
|
||||
|
||||
testN := func(n, r int, ex exitcode.ExitCode) func(t *testing.T) {
|
||||
return func(t *testing.T) {
|
||||
inputData := make([]byte, 32*3)
|
||||
binary.BigEndian.PutUint64(inputData[24:], uint64(n))
|
||||
binary.BigEndian.PutUint64(inputData[32+24:], uint64(n))
|
||||
binary.BigEndian.PutUint64(inputData[32+32+24:], uint64(r))
|
||||
|
||||
client.EVM().InvokeContractByFuncNameExpectExit(ctx, fromAddr, actorAddr, "exec1(uint256,uint256,uint256)", inputData, ex)
|
||||
}
|
||||
}
|
||||
|
||||
t.Run("n=0,r=1", testN(0, 1, exitcode.Ok))
|
||||
t.Run("n=1,r=1", testN(1, 1, exitcode.Ok))
|
||||
t.Run("n=20,r=1", testN(20, 1, exitcode.Ok))
|
||||
t.Run("n=200,r=1", testN(200, 1, exitcode.Ok))
|
||||
t.Run("n=251,r=1", testN(251, 1, exitcode.Ok))
|
||||
|
||||
t.Run("n=252,r=1-fails", testN(252, 1, exitcode.ExitCode(23))) // 23 means stack overflow
|
||||
|
||||
t.Run("n=0,r=10", testN(0, 10, exitcode.Ok))
|
||||
t.Run("n=1,r=10", testN(1, 10, exitcode.Ok))
|
||||
t.Run("n=20,r=10", testN(20, 10, exitcode.Ok))
|
||||
t.Run("n=200,r=10", testN(200, 10, exitcode.Ok))
|
||||
t.Run("n=251,r=10", testN(251, 10, exitcode.Ok))
|
||||
|
||||
t.Run("n=252,r=10-fails", testN(252, 10, exitcode.ExitCode(23)))
|
||||
|
||||
t.Run("n=0,r=32", testN(0, 32, exitcode.Ok))
|
||||
t.Run("n=1,r=32", testN(1, 32, exitcode.Ok))
|
||||
t.Run("n=20,r=32", testN(20, 32, exitcode.Ok))
|
||||
t.Run("n=200,r=32", testN(200, 32, exitcode.Ok))
|
||||
t.Run("n=251,r=32", testN(251, 32, exitcode.Ok))
|
||||
|
||||
t.Run("n=0,r=254", testN(0, 254, exitcode.Ok))
|
||||
t.Run("n=251,r=170", testN(251, 170, exitcode.Ok))
|
||||
|
||||
t.Run("n=0,r=255-fails", testN(0, 255, exitcode.ExitCode(33))) // 33 means transaction reverted
|
||||
t.Run("n=251,r=171-fails", testN(251, 171, exitcode.ExitCode(33)))
|
||||
}
|
||||
|
||||
@@ -290,7 +290,7 @@ func startNodes(
|
||||
ens.InterconnectAll().BeginMining(blocktime)
|
||||
|
||||
// Create a gateway server in front of the full node
|
||||
gwapi := gateway.NewNode(full, lookbackCap, stateWaitLookbackLimit, 0, time.Minute)
|
||||
gwapi := gateway.NewNode(full, nil, lookbackCap, stateWaitLookbackLimit, 0, time.Minute)
|
||||
handler, err := gateway.Handler(gwapi, full, 0, 0)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ import (
|
||||
"github.com/filecoin-project/lotus/chain/wallet/key"
|
||||
"github.com/filecoin-project/lotus/cmd/lotus-seed/seed"
|
||||
"github.com/filecoin-project/lotus/cmd/lotus-worker/sealworker"
|
||||
"github.com/filecoin-project/lotus/gateway"
|
||||
"github.com/filecoin-project/lotus/genesis"
|
||||
"github.com/filecoin-project/lotus/markets/idxprov"
|
||||
"github.com/filecoin-project/lotus/markets/idxprov/idxprov_test"
|
||||
@@ -210,7 +211,7 @@ func (n *Ensemble) FullNode(full *TestFullNode, opts ...NodeOpt) *Ensemble {
|
||||
n.genesis.accounts = append(n.genesis.accounts, genacc)
|
||||
}
|
||||
|
||||
*full = TestFullNode{t: n.t, options: options, DefaultKey: key}
|
||||
*full = TestFullNode{t: n.t, options: options, DefaultKey: key, EthSubRouter: gateway.NewEthSubHandler()}
|
||||
|
||||
n.inactive.fullnodes = append(n.inactive.fullnodes, full)
|
||||
return n
|
||||
|
||||
+15
-6
@@ -21,8 +21,10 @@ import (
|
||||
builtintypes "github.com/filecoin-project/go-state-types/builtin"
|
||||
"github.com/filecoin-project/go-state-types/builtin/v10/eam"
|
||||
"github.com/filecoin-project/go-state-types/crypto"
|
||||
"github.com/filecoin-project/go-state-types/exitcode"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/build"
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/types/ethtypes"
|
||||
@@ -109,11 +111,12 @@ func (e *EVM) InvokeSolidity(ctx context.Context, sender address.Address, target
|
||||
params = buffer.Bytes()
|
||||
|
||||
msg := &types.Message{
|
||||
To: target,
|
||||
From: sender,
|
||||
Value: big.Zero(),
|
||||
Method: builtintypes.MethodsEVM.InvokeContract,
|
||||
Params: params,
|
||||
To: target,
|
||||
From: sender,
|
||||
Value: big.Zero(),
|
||||
Method: builtintypes.MethodsEVM.InvokeContract,
|
||||
GasLimit: build.BlockGasLimit, // note: we hardcode block gas limit due to slightly broken gas estimation - https://github.com/filecoin-project/lotus/issues/10041
|
||||
Params: params,
|
||||
}
|
||||
|
||||
e.t.Log("sending invoke message")
|
||||
@@ -237,12 +240,18 @@ func (e *EVM) ComputeContractAddress(deployer ethtypes.EthAddress, nonce uint64)
|
||||
func (e *EVM) InvokeContractByFuncName(ctx context.Context, fromAddr address.Address, idAddr address.Address, funcSignature string, inputData []byte) []byte {
|
||||
entryPoint := CalcFuncSignature(funcSignature)
|
||||
wait := e.InvokeSolidity(ctx, fromAddr, idAddr, entryPoint, inputData)
|
||||
require.True(e.t, wait.Receipt.ExitCode.IsSuccess(), "contract execution failed")
|
||||
require.True(e.t, wait.Receipt.ExitCode.IsSuccess(), "contract execution failed: %d", wait.Receipt.ExitCode)
|
||||
result, err := cbg.ReadByteArray(bytes.NewBuffer(wait.Receipt.Return), uint64(len(wait.Receipt.Return)))
|
||||
require.NoError(e.t, err)
|
||||
return result
|
||||
}
|
||||
|
||||
func (e *EVM) InvokeContractByFuncNameExpectExit(ctx context.Context, fromAddr address.Address, idAddr address.Address, funcSignature string, inputData []byte, exit exitcode.ExitCode) {
|
||||
entryPoint := CalcFuncSignature(funcSignature)
|
||||
wait := e.InvokeSolidity(ctx, fromAddr, idAddr, entryPoint, inputData)
|
||||
require.Equal(e.t, exit, wait.Receipt.ExitCode)
|
||||
}
|
||||
|
||||
// function signatures are the first 4 bytes of the hash of the function name and types
|
||||
func CalcFuncSignature(funcName string) []byte {
|
||||
hasher := sha3.NewLegacyKeccak256()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package kit
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
@@ -10,15 +11,18 @@ import (
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
"github.com/stretchr/testify/require"
|
||||
cbg "github.com/whyrusleeping/cbor-gen"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/exitcode"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/api/v1api"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
"github.com/filecoin-project/lotus/chain/wallet/key"
|
||||
cliutil "github.com/filecoin-project/lotus/cli/util"
|
||||
"github.com/filecoin-project/lotus/gateway"
|
||||
"github.com/filecoin-project/lotus/node"
|
||||
)
|
||||
|
||||
@@ -43,6 +47,10 @@ type TestFullNode struct {
|
||||
|
||||
Stop node.StopFunc
|
||||
|
||||
// gateway handler makes it convenient to register callbalks per topic, so we
|
||||
// also use it for tests
|
||||
EthSubRouter *gateway.EthSubHandler
|
||||
|
||||
options nodeOpts
|
||||
}
|
||||
|
||||
@@ -124,6 +132,50 @@ func (f *TestFullNode) AssignPrivKey(pkey *Libp2p) {
|
||||
f.Pkey = pkey
|
||||
}
|
||||
|
||||
type SendCall struct {
|
||||
Method abi.MethodNum
|
||||
Params []byte
|
||||
}
|
||||
|
||||
func (f *TestFullNode) MakeSendCall(m abi.MethodNum, params cbg.CBORMarshaler) SendCall {
|
||||
var b bytes.Buffer
|
||||
err := params.MarshalCBOR(&b)
|
||||
require.NoError(f.t, err)
|
||||
return SendCall{
|
||||
Method: m,
|
||||
Params: b.Bytes(),
|
||||
}
|
||||
}
|
||||
|
||||
func (f *TestFullNode) ExpectSend(ctx context.Context, from, to address.Address, value types.BigInt, errContains string, sc ...SendCall) *types.SignedMessage {
|
||||
msg := &types.Message{From: from, To: to, Value: value}
|
||||
|
||||
if len(sc) == 1 {
|
||||
msg.Method = sc[0].Method
|
||||
msg.Params = sc[0].Params
|
||||
}
|
||||
|
||||
_, err := f.GasEstimateMessageGas(ctx, msg, nil, types.EmptyTSK)
|
||||
if errContains != "" {
|
||||
require.ErrorContains(f.t, err, errContains)
|
||||
return nil
|
||||
}
|
||||
require.NoError(f.t, err)
|
||||
|
||||
if errContains == "" {
|
||||
m, err := f.MpoolPushMessage(ctx, msg, nil)
|
||||
require.NoError(f.t, err)
|
||||
|
||||
r, err := f.StateWaitMsg(ctx, m.Cid(), 1, api.LookbackNoLimit, true)
|
||||
require.NoError(f.t, err)
|
||||
|
||||
require.Equal(f.t, exitcode.Ok, r.Receipt.ExitCode)
|
||||
return m
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ChainPredicate encapsulates a chain condition.
|
||||
type ChainPredicate func(set *types.TipSet) bool
|
||||
|
||||
|
||||
+8
-1
@@ -13,6 +13,8 @@ import (
|
||||
manet "github.com/multiformats/go-multiaddr/net"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/filecoin-project/go-jsonrpc"
|
||||
|
||||
"github.com/filecoin-project/lotus/api/client"
|
||||
"github.com/filecoin-project/lotus/cmd/lotus-worker/sealworker"
|
||||
"github.com/filecoin-project/lotus/node"
|
||||
@@ -52,7 +54,12 @@ func fullRpc(t *testing.T, f *TestFullNode) (*TestFullNode, Closer) {
|
||||
fmt.Printf("FULLNODE RPC ENV FOR CLI DEBUGGING `export FULLNODE_API_INFO=%s`\n", "ws://"+srv.Listener.Addr().String())
|
||||
sendItestdNotif("FULLNODE_API_INFO", t.Name(), "ws://"+srv.Listener.Addr().String())
|
||||
|
||||
cl, stop, err := client.NewFullNodeRPCV1(context.Background(), "ws://"+srv.Listener.Addr().String()+"/rpc/v1", nil)
|
||||
rpcOpts := []jsonrpc.Option{
|
||||
jsonrpc.WithClientHandler("Filecoin", f.EthSubRouter),
|
||||
jsonrpc.WithClientHandlerAlias("eth_subscription", "Filecoin.EthSubscription"),
|
||||
}
|
||||
|
||||
cl, stop, err := client.NewFullNodeRPCV1(context.Background(), "ws://"+srv.Listener.Addr().String()+"/rpc/v1", nil, rpcOpts...)
|
||||
require.NoError(t, err)
|
||||
f.ListenAddr, f.ListenURL, f.FullNode = maddr, srv.URL, cl
|
||||
|
||||
|
||||
@@ -30,6 +30,12 @@ func Wrap[T any](value T, err error) Result[T] {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Result[T]) Unwrap() (T, error) {
|
||||
func (r Result[T]) Unwrap() (T, error) {
|
||||
return r.Value, r.Error
|
||||
}
|
||||
|
||||
func (r Result[T]) Assert(noErrFn func(err error, msgAndArgs ...interface{})) T {
|
||||
noErrFn(r.Error)
|
||||
|
||||
return r.Value
|
||||
}
|
||||
|
||||
@@ -118,4 +118,8 @@ func (e *EthModuleDummy) EthSendRawTransaction(ctx context.Context, rawTx ethtyp
|
||||
return ethtypes.EthHash{}, ErrModuleDisabled
|
||||
}
|
||||
|
||||
func (e *EthModuleDummy) Web3ClientVersion(ctx context.Context) (string, error) {
|
||||
return "", ErrModuleDisabled
|
||||
}
|
||||
|
||||
var _ EthModuleAPI = &EthModuleDummy{}
|
||||
|
||||
+210
-183
@@ -3,6 +3,7 @@ package full
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
@@ -16,6 +17,7 @@ import (
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-address"
|
||||
"github.com/filecoin-project/go-jsonrpc"
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
"github.com/filecoin-project/go-state-types/big"
|
||||
builtintypes "github.com/filecoin-project/go-state-types/builtin"
|
||||
@@ -64,6 +66,7 @@ type EthModuleAPI interface {
|
||||
EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam string) (ethtypes.EthBytes, error)
|
||||
EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, error)
|
||||
EthSendRawTransaction(ctx context.Context, rawTx ethtypes.EthBytes) (ethtypes.EthHash, error)
|
||||
Web3ClientVersion(ctx context.Context) (string, error)
|
||||
}
|
||||
|
||||
type EthEventAPI interface {
|
||||
@@ -74,7 +77,7 @@ type EthEventAPI interface {
|
||||
EthNewBlockFilter(ctx context.Context) (ethtypes.EthFilterID, error)
|
||||
EthNewPendingTransactionFilter(ctx context.Context) (ethtypes.EthFilterID, error)
|
||||
EthUninstallFilter(ctx context.Context, id ethtypes.EthFilterID) (bool, error)
|
||||
EthSubscribe(ctx context.Context, eventType string, params *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error)
|
||||
EthSubscribe(ctx context.Context, params jsonrpc.RawParams) (ethtypes.EthSubscriptionID, error)
|
||||
EthUnsubscribe(ctx context.Context, id ethtypes.EthSubscriptionID) (bool, error)
|
||||
}
|
||||
|
||||
@@ -131,6 +134,7 @@ type EthEvent struct {
|
||||
FilterStore filter.FilterStore
|
||||
SubManager *EthSubscriptionManager
|
||||
MaxFilterHeightRange abi.ChainEpoch
|
||||
SubscribtionCtx context.Context
|
||||
}
|
||||
|
||||
var _ EthEventAPI = (*EthEvent)(nil)
|
||||
@@ -211,7 +215,7 @@ func (a *EthModule) EthGetBlockByHash(ctx context.Context, blkHash ethtypes.EthH
|
||||
if err != nil {
|
||||
return ethtypes.EthBlock{}, xerrors.Errorf("error loading tipset %s: %w", ts, err)
|
||||
}
|
||||
return newEthBlockFromFilecoinTipSet(ctx, ts, fullTxInfo, a.Chain, a.ChainAPI, a.StateAPI)
|
||||
return newEthBlockFromFilecoinTipSet(ctx, ts, fullTxInfo, a.Chain, a.StateAPI)
|
||||
}
|
||||
|
||||
func (a *EthModule) parseBlkParam(ctx context.Context, blkParam string) (tipset *types.TipSet, err error) {
|
||||
@@ -248,7 +252,7 @@ func (a *EthModule) EthGetBlockByNumber(ctx context.Context, blkParam string, fu
|
||||
if err != nil {
|
||||
return ethtypes.EthBlock{}, err
|
||||
}
|
||||
return newEthBlockFromFilecoinTipSet(ctx, ts, fullTxInfo, a.Chain, a.ChainAPI, a.StateAPI)
|
||||
return newEthBlockFromFilecoinTipSet(ctx, ts, fullTxInfo, a.Chain, a.StateAPI)
|
||||
}
|
||||
|
||||
func (a *EthModule) EthGetTransactionByHash(ctx context.Context, txHash *ethtypes.EthHash) (*ethtypes.EthTx, error) {
|
||||
@@ -269,8 +273,8 @@ func (a *EthModule) EthGetTransactionByHash(ctx context.Context, txHash *ethtype
|
||||
|
||||
// first, try to get the cid from mined transactions
|
||||
msgLookup, err := a.StateAPI.StateSearchMsg(ctx, types.EmptyTSK, c, api.LookbackNoLimit, true)
|
||||
if err == nil {
|
||||
tx, err := newEthTxFromFilecoinMessageLookup(ctx, msgLookup, -1, a.Chain, a.StateAPI)
|
||||
if err == nil && msgLookup != nil {
|
||||
tx, err := newEthTxFromMessageLookup(ctx, msgLookup, -1, a.Chain, a.StateAPI)
|
||||
if err == nil {
|
||||
return &tx, nil
|
||||
}
|
||||
@@ -286,7 +290,7 @@ func (a *EthModule) EthGetTransactionByHash(ctx context.Context, txHash *ethtype
|
||||
|
||||
for _, p := range pending {
|
||||
if p.Cid() == c {
|
||||
tx, err := NewEthTxFromFilecoinMessage(ctx, p, a.StateAPI)
|
||||
tx, err := newEthTxFromSignedMessage(ctx, p, a.StateAPI)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not convert Filecoin message into tx: %s", err)
|
||||
}
|
||||
@@ -335,7 +339,7 @@ func (a *EthModule) EthGetMessageCidByTransactionHash(ctx context.Context, txHas
|
||||
}
|
||||
|
||||
func (a *EthModule) EthGetTransactionHashByCid(ctx context.Context, cid cid.Cid) (*ethtypes.EthHash, error) {
|
||||
hash, err := EthTxHashFromFilecoinMessageCid(ctx, cid, a.StateAPI)
|
||||
hash, err := EthTxHashFromMessageCid(ctx, cid, a.StateAPI)
|
||||
if hash == ethtypes.EmptyEthHash {
|
||||
// not found
|
||||
return nil, nil
|
||||
@@ -378,7 +382,7 @@ func (a *EthModule) EthGetTransactionReceipt(ctx context.Context, txHash ethtype
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
tx, err := newEthTxFromFilecoinMessageLookup(ctx, msgLookup, -1, a.Chain, a.StateAPI)
|
||||
tx, err := newEthTxFromMessageLookup(ctx, msgLookup, -1, a.Chain, a.StateAPI)
|
||||
if err != nil {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -500,18 +504,8 @@ func (a *EthModule) EthGetStorageAt(ctx context.Context, ethAddr ethtypes.EthAdd
|
||||
return nil, fmt.Errorf("failed to construct system sender address: %w", err)
|
||||
}
|
||||
|
||||
// TODO super duper hack (raulk). The EVM runtime actor uses the U256 parameter type in
|
||||
// GetStorageAtParams, which serializes as a hex-encoded string. It should serialize
|
||||
// as bytes. We didn't get to fix in time for Iron, so for now we just pass
|
||||
// through the hex-encoded value passed through the Eth JSON-RPC API, by remarshalling it.
|
||||
// We don't fix this at origin (builtin-actors) because we are not updating the bundle
|
||||
// for Iron.
|
||||
tmp, err := position.MarshalJSON()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
params, err := actors.SerializeParams(&evm.GetStorageAtParams{
|
||||
StorageKey: tmp[1 : len(tmp)-1], // TODO strip the JSON-encoding quotes -- yuck
|
||||
StorageKey: position,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to serialize parameters: %w", err)
|
||||
@@ -614,7 +608,7 @@ func (a *EthModule) EthFeeHistory(ctx context.Context, blkCount ethtypes.EthUint
|
||||
for ts.Height() >= abi.ChainEpoch(oldestBlkHeight) {
|
||||
// Unfortunately we need to rebuild the full message view so we can
|
||||
// totalize gas used in the tipset.
|
||||
block, err := newEthBlockFromFilecoinTipSet(ctx, ts, false, a.Chain, a.ChainAPI, a.StateAPI)
|
||||
block, err := newEthBlockFromFilecoinTipSet(ctx, ts, false, a.Chain, a.StateAPI)
|
||||
if err != nil {
|
||||
return ethtypes.EthFeeHistory{}, fmt.Errorf("cannot create eth block: %v", err)
|
||||
}
|
||||
@@ -699,13 +693,6 @@ func (a *EthModule) EthSendRawTransaction(ctx context.Context, rawTx ethtypes.Et
|
||||
return ethtypes.EmptyEthHash, err
|
||||
}
|
||||
|
||||
_, err = a.StateAPI.StateGetActor(ctx, smsg.Message.To, types.EmptyTSK)
|
||||
if err != nil {
|
||||
// if actor does not exist on chain yet, set the method to 0 because
|
||||
// placeholders only implement method 0
|
||||
smsg.Message.Method = builtinactors.MethodSend
|
||||
}
|
||||
|
||||
_, err = a.MpoolAPI.MpoolPush(ctx, smsg)
|
||||
if err != nil {
|
||||
return ethtypes.EmptyEthHash, err
|
||||
@@ -714,6 +701,10 @@ func (a *EthModule) EthSendRawTransaction(ctx context.Context, rawTx ethtypes.Et
|
||||
return ethtypes.EthHashFromTxBytes(rawTx), nil
|
||||
}
|
||||
|
||||
func (a *EthModule) Web3ClientVersion(ctx context.Context) (string, error) {
|
||||
return build.UserVersion(), nil
|
||||
}
|
||||
|
||||
func (a *EthModule) ethCallToFilecoinMessage(ctx context.Context, tx ethtypes.EthCall) (*types.Message, error) {
|
||||
var from address.Address
|
||||
if tx.From == nil || *tx.From == (ethtypes.EthAddress{}) {
|
||||
@@ -827,8 +818,9 @@ func (a *EthModule) EthEstimateGas(ctx context.Context, tx ethtypes.EthCall) (et
|
||||
func (a *EthModule) EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam string) (ethtypes.EthBytes, error) {
|
||||
msg, err := a.ethCallToFilecoinMessage(ctx, tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, xerrors.Errorf("failed to convert ethcall to filecoin message: %w", err)
|
||||
}
|
||||
|
||||
ts, err := a.parseBlkParam(ctx, blkParam)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("cannot parse block param: %s", blkParam)
|
||||
@@ -836,11 +828,17 @@ func (a *EthModule) EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam s
|
||||
|
||||
invokeResult, err := a.applyMessage(ctx, msg, ts.Key())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, xerrors.Errorf("failed to apply message: %w", err)
|
||||
}
|
||||
if len(invokeResult.MsgRct.Return) > 0 {
|
||||
|
||||
if msg.To == builtintypes.EthereumAddressManagerActorAddr {
|
||||
// As far as I can tell, the Eth API always returns empty on contract deployment
|
||||
return ethtypes.EthBytes{}, nil
|
||||
|
||||
} else if len(invokeResult.MsgRct.Return) > 0 {
|
||||
return cbg.ReadByteArray(bytes.NewReader(invokeResult.MsgRct.Return), uint64(len(invokeResult.MsgRct.Return)))
|
||||
}
|
||||
|
||||
return ethtypes.EthBytes{}, nil
|
||||
}
|
||||
|
||||
@@ -980,17 +978,9 @@ func (e *EthEvent) installEthFilterSpec(ctx context.Context, filterSpec *ethtype
|
||||
addresses = append(addresses, a)
|
||||
}
|
||||
|
||||
for idx, vals := range filterSpec.Topics {
|
||||
if len(vals) == 0 {
|
||||
continue
|
||||
}
|
||||
// Ethereum topics are emitted using `LOG{0..4}` opcodes resulting in topics1..4
|
||||
key := fmt.Sprintf("topic%d", idx+1)
|
||||
for _, v := range vals {
|
||||
buf := make([]byte, len(v[:]))
|
||||
copy(buf, v[:])
|
||||
keys[key] = append(keys[key], buf)
|
||||
}
|
||||
keys, err := parseEthTopics(filterSpec.Topics)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return e.EventFilterManager.Install(ctx, minHeight, maxHeight, tipsetCid, addresses, keys)
|
||||
@@ -1015,7 +1005,6 @@ func (e *EthEvent) EthNewFilter(ctx context.Context, filterSpec *ethtypes.EthFil
|
||||
|
||||
return ethtypes.EthFilterID{}, err
|
||||
}
|
||||
|
||||
return ethtypes.EthFilterID(f.ID()), nil
|
||||
}
|
||||
|
||||
@@ -1114,39 +1103,45 @@ const (
|
||||
EthSubscribeEventTypeLogs = "logs"
|
||||
)
|
||||
|
||||
func (e *EthEvent) EthSubscribe(ctx context.Context, eventType string, params *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error) {
|
||||
if e.SubManager == nil {
|
||||
return nil, api.ErrNotSupported
|
||||
}
|
||||
// Note that go-jsonrpc will set the method field of the response to "xrpc.ch.val" but the ethereum api expects the name of the
|
||||
// method to be "eth_subscription". This probably doesn't matter in practice.
|
||||
|
||||
sub, err := e.SubManager.StartSubscription(ctx)
|
||||
func (e *EthEvent) EthSubscribe(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthSubscriptionID, error) {
|
||||
params, err := jsonrpc.DecodeParams[ethtypes.EthSubscribeParams](p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return ethtypes.EthSubscriptionID{}, xerrors.Errorf("decoding params: %w", err)
|
||||
}
|
||||
|
||||
switch eventType {
|
||||
if e.SubManager == nil {
|
||||
return ethtypes.EthSubscriptionID{}, api.ErrNotSupported
|
||||
}
|
||||
|
||||
ethCb, ok := jsonrpc.ExtractReverseClient[api.EthSubscriberMethods](ctx)
|
||||
if !ok {
|
||||
return ethtypes.EthSubscriptionID{}, xerrors.Errorf("connection doesn't support callbacks")
|
||||
}
|
||||
|
||||
sub, err := e.SubManager.StartSubscription(e.SubscribtionCtx, ethCb.EthSubscription)
|
||||
if err != nil {
|
||||
return ethtypes.EthSubscriptionID{}, err
|
||||
}
|
||||
|
||||
switch params.EventType {
|
||||
case EthSubscribeEventTypeHeads:
|
||||
f, err := e.TipSetFilterManager.Install(ctx)
|
||||
if err != nil {
|
||||
// clean up any previous filters added and stop the sub
|
||||
_, _ = e.EthUnsubscribe(ctx, sub.id)
|
||||
return nil, err
|
||||
return ethtypes.EthSubscriptionID{}, err
|
||||
}
|
||||
sub.addFilter(ctx, f)
|
||||
|
||||
case EthSubscribeEventTypeLogs:
|
||||
keys := map[string][][]byte{}
|
||||
if params != nil {
|
||||
for idx, vals := range params.Topics {
|
||||
// Ethereum topics are emitted using `LOG{0..4}` opcodes resulting in topics1..4
|
||||
key := fmt.Sprintf("topic%d", idx+1)
|
||||
keyvals := make([][]byte, len(vals))
|
||||
for i, v := range vals {
|
||||
keyvals[i] = v[:]
|
||||
}
|
||||
keys[key] = keyvals
|
||||
if params.Params != nil {
|
||||
var err error
|
||||
keys, err = parseEthTopics(params.Params.Topics)
|
||||
if err != nil {
|
||||
// clean up any previous filters added and stop the sub
|
||||
_, _ = e.EthUnsubscribe(ctx, sub.id)
|
||||
return ethtypes.EthSubscriptionID{}, err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1154,14 +1149,14 @@ func (e *EthEvent) EthSubscribe(ctx context.Context, eventType string, params *e
|
||||
if err != nil {
|
||||
// clean up any previous filters added and stop the sub
|
||||
_, _ = e.EthUnsubscribe(ctx, sub.id)
|
||||
return nil, err
|
||||
return ethtypes.EthSubscriptionID{}, err
|
||||
}
|
||||
sub.addFilter(ctx, f)
|
||||
default:
|
||||
return nil, xerrors.Errorf("unsupported event type: %s", eventType)
|
||||
return ethtypes.EthSubscriptionID{}, xerrors.Errorf("unsupported event type: %s", params.EventType)
|
||||
}
|
||||
|
||||
return sub.out, nil
|
||||
return sub.id, nil
|
||||
}
|
||||
|
||||
func (e *EthEvent) EthUnsubscribe(ctx context.Context, id ethtypes.EthSubscriptionID) (bool, error) {
|
||||
@@ -1233,7 +1228,10 @@ func ethFilterResultFromEvents(evs []*filter.CollectedEvent, sa StateAPI) (*etht
|
||||
var err error
|
||||
|
||||
for _, entry := range ev.Entries {
|
||||
value := ethtypes.EthBytes(leftpad32(entry.Value)) // value has already been cbor-decoded but see https://github.com/filecoin-project/ref-fvm/issues/1345
|
||||
value, err := cborDecodeTopicValue(entry.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if entry.Key == ethtypes.EthTopic1 || entry.Key == ethtypes.EthTopic2 || entry.Key == ethtypes.EthTopic3 || entry.Key == ethtypes.EthTopic4 {
|
||||
log.Topics = append(log.Topics, value)
|
||||
} else {
|
||||
@@ -1246,7 +1244,7 @@ func ethFilterResultFromEvents(evs []*filter.CollectedEvent, sa StateAPI) (*etht
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.TransactionHash, err = EthTxHashFromFilecoinMessageCid(context.TODO(), ev.MsgCid, sa)
|
||||
log.TransactionHash, err = EthTxHashFromMessageCid(context.TODO(), ev.MsgCid, sa)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1288,7 +1286,7 @@ func ethFilterResultFromMessages(cs []*types.SignedMessage, sa StateAPI) (*ethty
|
||||
res := ðtypes.EthFilterResult{}
|
||||
|
||||
for _, c := range cs {
|
||||
hash, err := EthTxHashFromSignedFilecoinMessage(context.TODO(), c, sa)
|
||||
hash, err := EthTxHashFromSignedMessage(context.TODO(), c, sa)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1307,7 +1305,7 @@ type EthSubscriptionManager struct {
|
||||
subs map[ethtypes.EthSubscriptionID]*ethSubscription
|
||||
}
|
||||
|
||||
func (e *EthSubscriptionManager) StartSubscription(ctx context.Context) (*ethSubscription, error) { // nolint
|
||||
func (e *EthSubscriptionManager) StartSubscription(ctx context.Context, out ethSubscriptionCallback) (*ethSubscription, error) { // nolint
|
||||
rawid, err := uuid.NewRandom()
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("new uuid: %w", err)
|
||||
@@ -1323,7 +1321,7 @@ func (e *EthSubscriptionManager) StartSubscription(ctx context.Context) (*ethSub
|
||||
ChainAPI: e.ChainAPI,
|
||||
id: id,
|
||||
in: make(chan interface{}, 200),
|
||||
out: make(chan ethtypes.EthSubscriptionResponse, 20),
|
||||
out: out,
|
||||
quit: quit,
|
||||
}
|
||||
|
||||
@@ -1353,13 +1351,15 @@ func (e *EthSubscriptionManager) StopSubscription(ctx context.Context, id ethtyp
|
||||
return sub.filters, nil
|
||||
}
|
||||
|
||||
type ethSubscriptionCallback func(context.Context, jsonrpc.RawParams) error
|
||||
|
||||
type ethSubscription struct {
|
||||
Chain *store.ChainStore
|
||||
StateAPI StateAPI
|
||||
ChainAPI ChainAPI
|
||||
id ethtypes.EthSubscriptionID
|
||||
in chan interface{}
|
||||
out chan ethtypes.EthSubscriptionResponse
|
||||
out ethSubscriptionCallback
|
||||
|
||||
mu sync.Mutex
|
||||
filters []filter.Filter
|
||||
@@ -1389,7 +1389,7 @@ func (e *ethSubscription) start(ctx context.Context) {
|
||||
case *filter.CollectedEvent:
|
||||
resp.Result, err = ethFilterResultFromEvents([]*filter.CollectedEvent{vt}, e.StateAPI)
|
||||
case *types.TipSet:
|
||||
eb, err := newEthBlockFromFilecoinTipSet(ctx, vt, true, e.Chain, e.ChainAPI, e.StateAPI)
|
||||
eb, err := newEthBlockFromFilecoinTipSet(ctx, vt, true, e.Chain, e.StateAPI)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
@@ -1403,10 +1403,15 @@ func (e *ethSubscription) start(ctx context.Context) {
|
||||
continue
|
||||
}
|
||||
|
||||
select {
|
||||
case e.out <- resp:
|
||||
default:
|
||||
// Skip if client is not reading responses
|
||||
outParam, err := json.Marshal(resp)
|
||||
if err != nil {
|
||||
log.Warnw("marshaling subscription response", "sub", e.id, "error", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if err := e.out(ctx, outParam); err != nil {
|
||||
log.Warnw("sending subscription response", "sub", e.id, "error", err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1418,12 +1423,11 @@ func (e *ethSubscription) stop() {
|
||||
|
||||
if e.quit != nil {
|
||||
e.quit()
|
||||
close(e.out)
|
||||
e.quit = nil
|
||||
}
|
||||
}
|
||||
|
||||
func newEthBlockFromFilecoinTipSet(ctx context.Context, ts *types.TipSet, fullTxInfo bool, cs *store.ChainStore, ca ChainAPI, sa StateAPI) (ethtypes.EthBlock, error) {
|
||||
func newEthBlockFromFilecoinTipSet(ctx context.Context, ts *types.TipSet, fullTxInfo bool, cs *store.ChainStore, sa StateAPI) (ethtypes.EthBlock, error) {
|
||||
parent, err := cs.LoadTipSet(ctx, ts.Parents())
|
||||
if err != nil {
|
||||
return ethtypes.EthBlock{}, err
|
||||
@@ -1462,7 +1466,7 @@ func newEthBlockFromFilecoinTipSet(ctx context.Context, ts *types.TipSet, fullTx
|
||||
}
|
||||
gasUsed += msgLookup.Receipt.GasUsed
|
||||
|
||||
tx, err := newEthTxFromFilecoinMessageLookup(ctx, msgLookup, txIdx, cs, sa)
|
||||
tx, err := newEthTxFromMessageLookup(ctx, msgLookup, txIdx, cs, sa)
|
||||
if err != nil {
|
||||
return ethtypes.EthBlock{}, nil
|
||||
}
|
||||
@@ -1522,11 +1526,11 @@ func lookupEthAddress(ctx context.Context, addr address.Address, sa StateAPI) (e
|
||||
return ethtypes.EthAddressFromFilecoinAddress(idAddr)
|
||||
}
|
||||
|
||||
func EthTxHashFromFilecoinMessageCid(ctx context.Context, c cid.Cid, sa StateAPI) (ethtypes.EthHash, error) {
|
||||
func EthTxHashFromMessageCid(ctx context.Context, c cid.Cid, sa StateAPI) (ethtypes.EthHash, error) {
|
||||
smsg, err := sa.Chain.GetSignedMessage(ctx, c)
|
||||
if err == nil {
|
||||
// This is an Eth Tx, Secp message, Or BLS message in the mpool
|
||||
return EthTxHashFromSignedFilecoinMessage(ctx, smsg, sa)
|
||||
return EthTxHashFromSignedMessage(ctx, smsg, sa)
|
||||
}
|
||||
|
||||
_, err = sa.Chain.GetMessage(ctx, c)
|
||||
@@ -1538,93 +1542,51 @@ func EthTxHashFromFilecoinMessageCid(ctx context.Context, c cid.Cid, sa StateAPI
|
||||
return ethtypes.EmptyEthHash, nil
|
||||
}
|
||||
|
||||
func EthTxHashFromSignedFilecoinMessage(ctx context.Context, smsg *types.SignedMessage, sa StateAPI) (ethtypes.EthHash, error) {
|
||||
func EthTxHashFromSignedMessage(ctx context.Context, smsg *types.SignedMessage, sa StateAPI) (ethtypes.EthHash, error) {
|
||||
if smsg.Signature.Type == crypto.SigTypeDelegated {
|
||||
ethTx, err := NewEthTxFromFilecoinMessage(ctx, smsg, sa)
|
||||
ethTx, err := newEthTxFromSignedMessage(ctx, smsg, sa)
|
||||
if err != nil {
|
||||
return ethtypes.EmptyEthHash, err
|
||||
}
|
||||
return ethTx.Hash, nil
|
||||
} else if smsg.Signature.Type == crypto.SigTypeSecp256k1 {
|
||||
return ethtypes.EthHashFromCid(smsg.Cid())
|
||||
} else { // BLS message
|
||||
return ethtypes.EthHashFromCid(smsg.Message.Cid())
|
||||
}
|
||||
|
||||
return ethtypes.EthHashFromCid(smsg.Cid())
|
||||
}
|
||||
|
||||
func NewEthTxFromFilecoinMessage(ctx context.Context, smsg *types.SignedMessage, sa StateAPI) (ethtypes.EthTx, error) {
|
||||
// Ignore errors here so we can still parse non-eth messages
|
||||
fromEthAddr, _ := lookupEthAddress(ctx, smsg.Message.From, sa)
|
||||
toEthAddr, _ := lookupEthAddress(ctx, smsg.Message.To, sa)
|
||||
|
||||
toAddr := &toEthAddr
|
||||
input := smsg.Message.Params
|
||||
func newEthTxFromSignedMessage(ctx context.Context, smsg *types.SignedMessage, sa StateAPI) (ethtypes.EthTx, error) {
|
||||
var tx ethtypes.EthTx
|
||||
var err error
|
||||
// Check to see if we need to decode as contract deployment.
|
||||
// We don't need to resolve the to address, because there's only one form (an ID).
|
||||
if smsg.Message.To == builtintypes.EthereumAddressManagerActorAddr {
|
||||
switch smsg.Message.Method {
|
||||
case builtintypes.MethodsEAM.Create:
|
||||
toAddr = nil
|
||||
var params eam.CreateParams
|
||||
err = params.UnmarshalCBOR(bytes.NewReader(smsg.Message.Params))
|
||||
input = params.Initcode
|
||||
case builtintypes.MethodsEAM.Create2:
|
||||
toAddr = nil
|
||||
var params eam.Create2Params
|
||||
err = params.UnmarshalCBOR(bytes.NewReader(smsg.Message.Params))
|
||||
input = params.Initcode
|
||||
case builtintypes.MethodsEAM.CreateExternal:
|
||||
toAddr = nil
|
||||
var params abi.CborBytes
|
||||
err = params.UnmarshalCBOR(bytes.NewReader(smsg.Message.Params))
|
||||
input = []byte(params)
|
||||
}
|
||||
if err != nil {
|
||||
return ethtypes.EthTx{}, err
|
||||
}
|
||||
}
|
||||
// Otherwise, try to decode as a cbor byte array.
|
||||
// TODO: Actually check if this is an ethereum call. This code will work for demo purposes, but is not correct.
|
||||
if toAddr != nil {
|
||||
if decodedParams, err := cbg.ReadByteArray(bytes.NewReader(smsg.Message.Params), uint64(len(smsg.Message.Params))); err == nil {
|
||||
input = decodedParams
|
||||
}
|
||||
}
|
||||
|
||||
r, s, v, err := ethtypes.RecoverSignature(smsg.Signature)
|
||||
if err != nil {
|
||||
// we don't want to return error if the message is not an Eth tx
|
||||
r, s, v = ethtypes.EthBigIntZero, ethtypes.EthBigIntZero, ethtypes.EthBigIntZero
|
||||
}
|
||||
|
||||
tx := ethtypes.EthTx{
|
||||
Nonce: ethtypes.EthUint64(smsg.Message.Nonce),
|
||||
ChainID: ethtypes.EthUint64(build.Eip155ChainId),
|
||||
From: fromEthAddr,
|
||||
To: toAddr,
|
||||
Value: ethtypes.EthBigInt(smsg.Message.Value),
|
||||
Type: ethtypes.EthUint64(2),
|
||||
Input: input,
|
||||
Gas: ethtypes.EthUint64(smsg.Message.GasLimit),
|
||||
MaxFeePerGas: ethtypes.EthBigInt(smsg.Message.GasFeeCap),
|
||||
MaxPriorityFeePerGas: ethtypes.EthBigInt(smsg.Message.GasPremium),
|
||||
V: v,
|
||||
R: r,
|
||||
S: s,
|
||||
}
|
||||
|
||||
// This is an eth tx
|
||||
if smsg.Signature.Type == crypto.SigTypeDelegated {
|
||||
tx, err = ethtypes.EthTxFromSignedEthMessage(smsg)
|
||||
if err != nil {
|
||||
return ethtypes.EthTx{}, xerrors.Errorf("failed to convert from signed message: %w", err)
|
||||
}
|
||||
|
||||
tx.Hash, err = tx.TxHash()
|
||||
if err != nil {
|
||||
return tx, err
|
||||
return ethtypes.EthTx{}, xerrors.Errorf("failed to calculate hash for ethTx: %w", err)
|
||||
}
|
||||
} else if smsg.Signature.Type == crypto.SigTypeUnknown { // BLS Filecoin message
|
||||
tx.Hash, err = ethtypes.EthHashFromCid(smsg.Message.Cid())
|
||||
|
||||
fromAddr, err := lookupEthAddress(ctx, smsg.Message.From, sa)
|
||||
if err != nil {
|
||||
return ethtypes.EthTx{}, xerrors.Errorf("failed to resolve Ethereum address: %w", err)
|
||||
}
|
||||
|
||||
tx.From = fromAddr
|
||||
} else if smsg.Signature.Type == crypto.SigTypeSecp256k1 { // Secp Filecoin Message
|
||||
tx = ethTxFromNativeMessage(ctx, smsg.VMMessage(), sa)
|
||||
tx.Hash, err = ethtypes.EthHashFromCid(smsg.Cid())
|
||||
if err != nil {
|
||||
return tx, err
|
||||
}
|
||||
} else { // Secp Filecoin Message
|
||||
tx.Hash, err = ethtypes.EthHashFromCid(smsg.Cid())
|
||||
} else { // BLS Filecoin message
|
||||
tx = ethTxFromNativeMessage(ctx, smsg.VMMessage(), sa)
|
||||
tx.Hash, err = ethtypes.EthHashFromCid(smsg.Message.Cid())
|
||||
if err != nil {
|
||||
return tx, err
|
||||
}
|
||||
@@ -1633,14 +1595,32 @@ func NewEthTxFromFilecoinMessage(ctx context.Context, smsg *types.SignedMessage,
|
||||
return tx, nil
|
||||
}
|
||||
|
||||
// newEthTxFromFilecoinMessageLookup creates an ethereum transaction from filecoin message lookup. If a negative txIdx is passed
|
||||
// into the function, it looksup the transaction index of the message in the tipset, otherwise it uses the txIdx passed into the
|
||||
// function
|
||||
func newEthTxFromFilecoinMessageLookup(ctx context.Context, msgLookup *api.MsgLookup, txIdx int, cs *store.ChainStore, sa StateAPI) (ethtypes.EthTx, error) {
|
||||
if msgLookup == nil {
|
||||
return ethtypes.EthTx{}, fmt.Errorf("msg does not exist")
|
||||
// ethTxFromNativeMessage does NOT populate:
|
||||
// - BlockHash
|
||||
// - BlockNumber
|
||||
// - TransactionIndex
|
||||
// - Hash
|
||||
func ethTxFromNativeMessage(ctx context.Context, msg *types.Message, sa StateAPI) ethtypes.EthTx {
|
||||
// We don't care if we error here, conversion is best effort for non-eth transactions
|
||||
from, _ := lookupEthAddress(ctx, msg.From, sa)
|
||||
to, _ := lookupEthAddress(ctx, msg.To, sa)
|
||||
return ethtypes.EthTx{
|
||||
To: &to,
|
||||
From: from,
|
||||
Nonce: ethtypes.EthUint64(msg.Nonce),
|
||||
ChainID: ethtypes.EthUint64(build.Eip155ChainId),
|
||||
Value: ethtypes.EthBigInt(msg.Value),
|
||||
Type: ethtypes.Eip1559TxType,
|
||||
Gas: ethtypes.EthUint64(msg.GasLimit),
|
||||
MaxFeePerGas: ethtypes.EthBigInt(msg.GasFeeCap),
|
||||
MaxPriorityFeePerGas: ethtypes.EthBigInt(msg.GasPremium),
|
||||
}
|
||||
}
|
||||
|
||||
// newEthTxFromMessageLookup creates an ethereum transaction from filecoin message lookup. If a negative txIdx is passed
|
||||
// into the function, it looks up the transaction index of the message in the tipset, otherwise it uses the txIdx passed into the
|
||||
// function
|
||||
func newEthTxFromMessageLookup(ctx context.Context, msgLookup *api.MsgLookup, txIdx int, cs *store.ChainStore, sa StateAPI) (ethtypes.EthTx, error) {
|
||||
ts, err := cs.LoadTipSet(ctx, msgLookup.TipSet)
|
||||
if err != nil {
|
||||
return ethtypes.EthTx{}, err
|
||||
@@ -1689,13 +1669,13 @@ func newEthTxFromFilecoinMessageLookup(ctx context.Context, msgLookup *api.MsgLo
|
||||
smsg = &types.SignedMessage{
|
||||
Message: *msg,
|
||||
Signature: crypto.Signature{
|
||||
Type: crypto.SigTypeUnknown,
|
||||
Type: crypto.SigTypeBLS,
|
||||
Data: nil,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
tx, err := NewEthTxFromFilecoinMessage(ctx, smsg, sa)
|
||||
tx, err := newEthTxFromSignedMessage(ctx, smsg, sa)
|
||||
if err != nil {
|
||||
return ethtypes.EthTx{}, err
|
||||
}
|
||||
@@ -1741,16 +1721,6 @@ func newEthTxReceipt(ctx context.Context, tx ethtypes.EthTx, lookup *api.MsgLook
|
||||
LogsBloom: ethtypes.EmptyEthBloom[:],
|
||||
}
|
||||
|
||||
if receipt.To == nil && lookup.Receipt.ExitCode.IsSuccess() {
|
||||
// Create and Create2 return the same things.
|
||||
var ret eam.CreateReturn
|
||||
if err := ret.UnmarshalCBOR(bytes.NewReader(lookup.Receipt.Return)); err != nil {
|
||||
return api.EthTxReceipt{}, xerrors.Errorf("failed to parse contract creation result: %w", err)
|
||||
}
|
||||
addr := ethtypes.EthAddress(ret.EthAddress)
|
||||
receipt.ContractAddress = &addr
|
||||
}
|
||||
|
||||
if lookup.Receipt.ExitCode.IsSuccess() {
|
||||
receipt.Status = 1
|
||||
}
|
||||
@@ -1758,6 +1728,24 @@ func newEthTxReceipt(ctx context.Context, tx ethtypes.EthTx, lookup *api.MsgLook
|
||||
receipt.Status = 0
|
||||
}
|
||||
|
||||
receipt.GasUsed = ethtypes.EthUint64(lookup.Receipt.GasUsed)
|
||||
|
||||
// TODO: handle CumulativeGasUsed
|
||||
receipt.CumulativeGasUsed = ethtypes.EmptyEthInt
|
||||
|
||||
effectiveGasPrice := big.Div(replay.GasCost.TotalCost, big.NewInt(lookup.Receipt.GasUsed))
|
||||
receipt.EffectiveGasPrice = ethtypes.EthBigInt(effectiveGasPrice)
|
||||
|
||||
if receipt.To == nil && lookup.Receipt.ExitCode.IsSuccess() {
|
||||
// Create and Create2 return the same things.
|
||||
var ret eam.CreateExternalReturn
|
||||
if err := ret.UnmarshalCBOR(bytes.NewReader(lookup.Receipt.Return)); err != nil {
|
||||
return api.EthTxReceipt{}, xerrors.Errorf("failed to parse contract creation result: %w", err)
|
||||
}
|
||||
addr := ethtypes.EthAddress(ret.EthAddress)
|
||||
receipt.ContractAddress = &addr
|
||||
}
|
||||
|
||||
if len(events) > 0 {
|
||||
// TODO return a dummy non-zero bloom to signal that there are logs
|
||||
// need to figure out how worth it is to populate with a real bloom
|
||||
@@ -1776,7 +1764,10 @@ func newEthTxReceipt(ctx context.Context, tx ethtypes.EthTx, lookup *api.MsgLook
|
||||
}
|
||||
|
||||
for _, entry := range evt.Entries {
|
||||
value := ethtypes.EthBytes(leftpad32(entry.Value)) // value has already been cbor-decoded but see https://github.com/filecoin-project/ref-fvm/issues/1345
|
||||
value, err := cborDecodeTopicValue(entry.Value)
|
||||
if err != nil {
|
||||
return api.EthTxReceipt{}, xerrors.Errorf("failed to decode event log value: %w", err)
|
||||
}
|
||||
if entry.Key == ethtypes.EthTopic1 || entry.Key == ethtypes.EthTopic2 || entry.Key == ethtypes.EthTopic3 || entry.Key == ethtypes.EthTopic4 {
|
||||
l.Topics = append(l.Topics, value)
|
||||
} else {
|
||||
@@ -1798,14 +1789,6 @@ func newEthTxReceipt(ctx context.Context, tx ethtypes.EthTx, lookup *api.MsgLook
|
||||
}
|
||||
}
|
||||
|
||||
receipt.GasUsed = ethtypes.EthUint64(lookup.Receipt.GasUsed)
|
||||
|
||||
// TODO: handle CumulativeGasUsed
|
||||
receipt.CumulativeGasUsed = ethtypes.EmptyEthInt
|
||||
|
||||
effectiveGasPrice := big.Div(replay.GasCost.TotalCost, big.NewInt(lookup.Receipt.GasUsed))
|
||||
receipt.EffectiveGasPrice = ethtypes.EthBigInt(effectiveGasPrice)
|
||||
|
||||
return receipt, nil
|
||||
}
|
||||
|
||||
@@ -1821,7 +1804,7 @@ func (m *EthTxHashManager) Apply(ctx context.Context, from, to *types.TipSet) er
|
||||
continue
|
||||
}
|
||||
|
||||
hash, err := EthTxHashFromSignedFilecoinMessage(ctx, smsg, m.StateAPI)
|
||||
hash, err := EthTxHashFromSignedMessage(ctx, smsg, m.StateAPI)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1858,7 +1841,7 @@ func WaitForMpoolUpdates(ctx context.Context, ch <-chan api.MpoolUpdate, manager
|
||||
continue
|
||||
}
|
||||
|
||||
ethTx, err := NewEthTxFromFilecoinMessage(ctx, u.Message, manager.StateAPI)
|
||||
ethTx, err := newEthTxFromSignedMessage(ctx, u.Message, manager.StateAPI)
|
||||
if err != nil {
|
||||
log.Errorf("error converting filecoin message to eth tx: %s", err)
|
||||
}
|
||||
@@ -1887,10 +1870,6 @@ func EthTxHashGC(ctx context.Context, retentionDays int, manager *EthTxHashManag
|
||||
}
|
||||
}
|
||||
|
||||
// TODO we could also emit full EVM words from the EVM runtime, but not doing so
|
||||
// makes the contract slightly cheaper (and saves storage bytes), at the expense
|
||||
// of having to left pad in the API, which is a pretty acceptable tradeoff at
|
||||
// face value. There may be other protocol implications to consider.
|
||||
func leftpad32(orig []byte) []byte {
|
||||
needed := 32 - len(orig)
|
||||
if needed <= 0 {
|
||||
@@ -1900,3 +1879,51 @@ func leftpad32(orig []byte) []byte {
|
||||
copy(ret[needed:], orig)
|
||||
return ret
|
||||
}
|
||||
|
||||
func trimLeadingZeros(b []byte) []byte {
|
||||
for i := range b {
|
||||
if b[i] != 0 {
|
||||
return b[i:]
|
||||
}
|
||||
}
|
||||
return []byte{}
|
||||
}
|
||||
|
||||
func cborEncodeTopicValue(orig []byte) ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
err := cbg.WriteByteArray(&buf, trimLeadingZeros(orig))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
func cborDecodeTopicValue(orig []byte) ([]byte, error) {
|
||||
if len(orig) == 0 {
|
||||
return orig, nil
|
||||
}
|
||||
decoded, err := cbg.ReadByteArray(bytes.NewReader(orig), uint64(len(orig)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return leftpad32(decoded), nil
|
||||
}
|
||||
|
||||
func parseEthTopics(topics ethtypes.EthTopicSpec) (map[string][][]byte, error) {
|
||||
keys := map[string][][]byte{}
|
||||
for idx, vals := range topics {
|
||||
if len(vals) == 0 {
|
||||
continue
|
||||
}
|
||||
// Ethereum topics are emitted using `LOG{0..4}` opcodes resulting in topics1..4
|
||||
key := fmt.Sprintf("topic%d", idx+1)
|
||||
for _, v := range vals {
|
||||
encodedVal, err := cborEncodeTopicValue(v[:])
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to encode topic value")
|
||||
}
|
||||
keys[key] = append(keys[key], encodedVal)
|
||||
}
|
||||
}
|
||||
return keys, nil
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ func EthEventAPI(cfg config.FevmConfig) func(helpers.MetricsCtx, repo.LockedRepo
|
||||
ee := &full.EthEvent{
|
||||
Chain: cs,
|
||||
MaxFilterHeightRange: abi.ChainEpoch(cfg.Events.MaxFilterHeightRange),
|
||||
SubscribtionCtx: ctx,
|
||||
}
|
||||
|
||||
if !cfg.EnableEthRPC || cfg.Events.DisableRealTimeFilterAPI {
|
||||
|
||||
+3
-2
@@ -75,7 +75,7 @@ func FullNodeHandler(a v1api.FullNode, permissioned bool, opts ...jsonrpc.Server
|
||||
m := mux.NewRouter()
|
||||
|
||||
serveRpc := func(path string, hnd interface{}) {
|
||||
rpcServer := jsonrpc.NewServer(append(opts, jsonrpc.WithServerErrors(api.RPCErrors))...)
|
||||
rpcServer := jsonrpc.NewServer(append(opts, jsonrpc.WithReverseClient[api.EthSubscriberMethods]("Filecoin"), jsonrpc.WithServerErrors(api.RPCErrors))...)
|
||||
rpcServer.Register("Filecoin", hnd)
|
||||
rpcServer.AliasMethod("rpc.discover", "Filecoin.Discover")
|
||||
|
||||
@@ -94,8 +94,9 @@ func FullNodeHandler(a v1api.FullNode, permissioned bool, opts ...jsonrpc.Server
|
||||
fnapi = api.PermissionedFullAPI(fnapi)
|
||||
}
|
||||
|
||||
var v0 v0api.FullNode = &(struct{ v0api.FullNode }{&v0api.WrapperV1Full{FullNode: fnapi}})
|
||||
serveRpc("/rpc/v1", fnapi)
|
||||
serveRpc("/rpc/v0", &v0api.WrapperV1Full{FullNode: fnapi})
|
||||
serveRpc("/rpc/v0", v0)
|
||||
|
||||
// Import handler
|
||||
handleImportFunc := handleImport(a.(*impl.FullNodeAPI))
|
||||
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
set -e
|
||||
|
||||
if [ -z "$(git status --porcelain)" ]; then
|
||||
echo "PASSED: Working directory clean"
|
||||
else
|
||||
echo "FAILED: Working directory not clean."
|
||||
echo "This is likely because the .dockerignore file has removed something checked into git."
|
||||
echo "Add the missing files listed below to the .dockerignore to fix this issue:"
|
||||
echo "$(git status)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" viewBox="0 0 127 127" xml:space="preserve" enable-background="new 0 0 127 127"><style type="text/css">.st0{fill:#00d2d6}.st1{fill:#fff}</style><g><path class="st0" d="M63.5,127C28.5,127.1-0.2,98.4,0,63.2C0.2,28.3,28.6-0.2,63.9,0c34.8,0.2,63.3,28.7,63.1,64 C126.7,98.7,98.5,127.1,63.5,127z M71.4,57.6c5.5,0.8,11,1.5,16.5,2.3c0.5-1.7,0.9-3.1,1.3-4.7c-5.7-0.8-11.2-1.7-17.1-2.5 c2-7,3.7-13.7,5.8-20.2c0.7-2.2,2.3-4.2,3.9-5.9c2.1-2.2,5-1.7,6.8,0.7c0.7,1,1.4,2.1,2.3,2.9c1.1,1.1,2.8,1.6,4,0.6 c0.8-0.7,0.7-2.4,0.8-3.6c0-0.5-0.6-1.1-1-1.6c-2-2.3-4.7-3.1-7.5-3.2c-6.3-0.3-10.9,3-14.5,7.8c-3.5,4.8-5.1,10.5-6.8,16.2 c-0.5,1.6-0.9,3.3-1.4,5.1c-6.2-0.9-12.1-1.7-18.2-2.6c-0.2,1.6-0.4,3.2-0.6,4.8c6,0.9,11.8,1.8,17.8,2.7c-0.8,3.4-1.5,6.5-2.3,9.7 c-5.8-0.8-11.4-1.6-17-2.4c-0.2,1.8-0.4,3.2-0.6,4.8c5.6,0.9,11,1.7,16.5,2.5c0,0.6,0.1,1,0,1.3c-1.7,7.4-3.4,14.8-5.3,22.2 c-0.9,3.5-2.4,6.9-5.3,9.3c-2.4,2-5,1.7-6.8-0.8c-0.8-1.1-1.5-2.5-2.6-3.3c-0.8-0.6-2.5-0.9-3.1-0.5c-0.9,0.7-1.5,2.2-1.4,3.3 c0.1,1,1,2.2,1.9,2.8c3,2.3,6.5,2.6,10,1.9c5.9-1.2,10.1-4.9,12.7-10.1c2-4.1,3.6-8.5,5-12.9c1.3-4,2.2-8,3.3-12.2 c5.8,0.8,11.5,1.7,17.3,2.5c0.5-1.7,0.9-3.2,1.4-4.8c-6.1-0.9-11.9-1.7-17.7-2.6C70.1,64,70.7,60.9,71.4,57.6z"/><path class="st1" d="M71.4,57.6c-0.7,3.3-1.3,6.4-2,9.8c5.9,0.9,11.7,1.7,17.7,2.6c-0.5,1.6-0.9,3.1-1.4,4.8 c-5.8-0.8-11.5-1.7-17.3-2.5c-1.1,4.2-2,8.3-3.3,12.2c-1.4,4.4-3,8.7-5,12.9c-2.6,5.2-6.8,8.9-12.7,10.1c-3.5,0.7-7,0.4-10-1.9 c-0.9-0.7-1.8-1.8-1.9-2.8c-0.1-1.1,0.5-2.7,1.4-3.3c0.6-0.5,2.3-0.1,3.1,0.5c1.1,0.8,1.8,2.1,2.6,3.3c1.8,2.5,4.4,2.9,6.8,0.8 c2.9-2.5,4.4-5.8,5.3-9.3c1.9-7.3,3.6-14.8,5.3-22.2c0.1-0.3,0-0.7,0-1.3c-5.4-0.8-10.8-1.7-16.5-2.5c0.2-1.6,0.4-3,0.6-4.8 c5.6,0.8,11.1,1.6,17,2.4c0.8-3.2,1.5-6.4,2.3-9.7c-6-0.9-11.7-1.8-17.8-2.7c0.2-1.6,0.4-3.2,0.6-4.8c6.1,0.9,12,1.7,18.2,2.6 c0.5-1.8,0.9-3.5,1.4-5.1c1.7-5.6,3.2-11.3,6.8-16.2c3.6-4.9,8.1-8.1,14.5-7.8c2.8,0.1,5.5,0.9,7.5,3.2c0.4,0.5,1,1.1,1,1.6 c-0.1,1.2,0,2.9-0.8,3.6c-1.1,1.1-2.8,0.5-4-0.6c-0.9-0.9-1.6-1.9-2.3-2.9c-1.8-2.4-4.7-2.9-6.8-0.7c-1.6,1.7-3.2,3.7-3.9,5.9 C75.7,39.4,74,46,72,53c5.9,0.9,11.4,1.7,17.1,2.5c-0.5,1.6-0.9,3.1-1.3,4.7C82.3,59.1,76.9,58.3,71.4,57.6z"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 2.2 KiB |
@@ -1,96 +0,0 @@
|
||||
name: lotus-filecoin
|
||||
base: core20
|
||||
version: latest
|
||||
summary: filecoin daemon/client
|
||||
icon: snap/local/icon.svg
|
||||
description: |
|
||||
Filecoin is a peer-to-peer network that stores files on the internet
|
||||
with built-in economic incentives to ensure files are stored reliably over time
|
||||
|
||||
For documentation and additional information, please see the following resources
|
||||
|
||||
https://filecoin.io
|
||||
|
||||
https://fil.org
|
||||
|
||||
https://lotus.filecoin.io
|
||||
|
||||
https://github.com/filecoin-project/lotus
|
||||
|
||||
confinement: strict
|
||||
|
||||
parts:
|
||||
lotus:
|
||||
plugin: make
|
||||
source: ./
|
||||
build-snaps:
|
||||
- go
|
||||
- rustup
|
||||
build-packages:
|
||||
- git
|
||||
- jq
|
||||
- libhwloc-dev
|
||||
- ocl-icd-opencl-dev
|
||||
- pkg-config
|
||||
stage-packages:
|
||||
- libhwloc15
|
||||
- ocl-icd-libopencl1
|
||||
override-build: |
|
||||
LDFLAGS="" make lotus lotus-miner lotus-worker
|
||||
cp lotus lotus-miner lotus-worker $SNAPCRAFT_PART_INSTALL
|
||||
cp scripts/snap-lotus-entrypoint.sh $SNAPCRAFT_PART_INSTALL
|
||||
|
||||
layout:
|
||||
/var/lib/lotus:
|
||||
symlink: $SNAP_COMMON/lotus
|
||||
/var/lib/lotus-miner:
|
||||
symlink: $SNAP_COMMON/lotus-miner
|
||||
/var/lib/lotus-worker:
|
||||
symlink: $SNAP_COMMON/lotus-worker
|
||||
|
||||
apps:
|
||||
lotus:
|
||||
command: lotus
|
||||
plugs:
|
||||
- network
|
||||
- network-bind
|
||||
- home
|
||||
environment:
|
||||
FIL_PROOFS_PARAMETER_CACHE: $SNAP_USER_COMMON/filecoin-proof-parameters
|
||||
LOTUS_PATH: $SNAP_COMMON/lotus
|
||||
LOTUS_MINER_PATH: $SNAP_COMMON/lotus-miner
|
||||
LOTUS_WORKER_PATH: $SNAP_COMMON/lotus-worker
|
||||
lotus-miner:
|
||||
command: lotus-miner
|
||||
plugs:
|
||||
- network
|
||||
- network-bind
|
||||
- opengl
|
||||
environment:
|
||||
FIL_PROOFS_PARAMETER_CACHE: $SNAP_USER_COMMON/filecoin-proof-parameters
|
||||
LOTUS_PATH: $SNAP_COMMON/lotus
|
||||
LOTUS_MINER_PATH: $SNAP_COMMON/lotus-miner
|
||||
LOTUS_WORKER_PATH: $SNAP_COMMON/lotus-worker
|
||||
lotus-worker:
|
||||
command: lotus-worker
|
||||
plugs:
|
||||
- network
|
||||
- network-bind
|
||||
- opengl
|
||||
environment:
|
||||
FIL_PROOFS_PARAMETER_CACHE: $SNAP_USER_COMMON/filecoin-proof-parameters
|
||||
LOTUS_PATH: $SNAP_COMMON/lotus
|
||||
LOTUS_MINER_PATH: $SNAP_COMMON/lotus-miner
|
||||
LOTUS_WORKER_PATH: $SNAP_COMMON/lotus-worker
|
||||
lotus-daemon:
|
||||
command: snap-lotus-entrypoint.sh
|
||||
daemon: simple
|
||||
install-mode: disable
|
||||
plugs:
|
||||
- network
|
||||
- network-bind
|
||||
environment:
|
||||
FIL_PROOFS_PARAMETER_CACHE: $SNAP_COMMON/filecoin-proof-parameters
|
||||
LOTUS_PATH: $SNAP_COMMON/lotus
|
||||
LOTUS_MINER_PATH: $SNAP_COMMON/lotus-miner
|
||||
LOTUS_WORKER_PATH: $SNAP_COMMON/lotus-worker
|
||||
Reference in New Issue
Block a user