diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index e2a5d2f0a..0059fb55b 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -9,10 +9,10 @@ jobs: steps: - uses: actions/checkout@master - - name: Set up Go 1.15 + - name: Set up Go 1.16 uses: actions/setup-go@v1 with: - go-version: 1.15 + go-version: 1.16 id: go - name: Set up GolangCI-Lint diff --git a/Makefile b/Makefile index 45687bc4f..d0539555a 100644 --- a/Makefile +++ b/Makefile @@ -32,7 +32,7 @@ gotest: go test -cover ./... fmtcheck: - @gofmt -l -s $(SOURCE_DIRS) | grep ".*\.go" | grep -v ".*bn254/.*\.go"; if [ "$$?" = "0" ]; then exit 1; fi + @gofmt -l -s $(SOURCE_DIRS) | grep ".*\.go" | grep -v "compiler_helpers.go" | grep -v ".*bn254/.*\.go"; if [ "$$?" = "0" ]; then exit 1; fi mod-clean: go mod tidy diff --git a/go.mod b/go.mod index 928e95077..7fde6aa33 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/wavesplatform/gowaves -go 1.15 +go 1.16 require ( github.com/OneOfOne/xxhash v1.2.5 // indirect @@ -11,6 +11,7 @@ require ( github.com/coocood/freecache v1.1.0 github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc // indirect github.com/ericlagergren/decimal v0.0.0-20190912144844-2c3e3e1ef942 + github.com/frozen/immutable_map v0.1.0 github.com/fxamacker/cbor/v2 v2.2.0 github.com/go-chi/chi v4.0.3+incompatible github.com/golang/mock v1.4.3 @@ -35,7 +36,7 @@ require ( github.com/spf13/pflag v1.0.5 github.com/starius/emsort v0.0.0-20191221202443-6f2fbdee4781 github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 - github.com/stretchr/testify v1.6.1 + github.com/stretchr/testify v1.7.0 github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d github.com/valyala/bytebufferpool v1.0.0 github.com/xenolf/lego v2.7.2+incompatible diff --git a/go.sum b/go.sum index 974cfae70..dfcce0cb5 100644 --- a/go.sum +++ b/go.sum @@ -81,6 +81,8 @@ github.com/ericlagergren/decimal v0.0.0-20190912144844-2c3e3e1ef942/go.mod h1:ZW github.com/ethereum/go-ethereum v1.9.15/go.mod h1:slT8bPPRhXsyNTwHQxrOnjuTZ1sDXRajW11EkJ84QJ0= github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= +github.com/frozen/immutable_map v0.1.0 h1:JvDI2+lE4+5UJ8QJwxesBl4RuAEOmCJCZDXiAQXXIcY= +github.com/frozen/immutable_map v0.1.0/go.mod h1:wIufmkixG0KtX1l5NNbSwlp/GIHJ0tUnMO/uXKUs9LU= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fxamacker/cbor/v2 v2.2.0 h1:6eXqdDDe588rSYAi1HfZKbx6YYQO4mxQ9eC6xYpU/JQ= @@ -252,8 +254,9 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d h1:gZZadD8H+fF+n9CmNhYL1Y0dJB+kLOmKd7FbPJLeGHs= github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA= github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= diff --git a/pkg/miner/utxpool/mock.go b/pkg/miner/utxpool/mock.go index d3c9c13cf..b00dc648d 100644 --- a/pkg/miner/utxpool/mock.go +++ b/pkg/miner/utxpool/mock.go @@ -5,36 +5,37 @@ package utxpool import ( + reflect "reflect" + gomock "github.com/golang/mock/gomock" proto "github.com/wavesplatform/gowaves/pkg/proto" state "github.com/wavesplatform/gowaves/pkg/state" - reflect "reflect" ) -// MockstateWrapper is a mock of stateWrapper interface +// MockstateWrapper is a mock of stateWrapper interface. type MockstateWrapper struct { ctrl *gomock.Controller recorder *MockstateWrapperMockRecorder } -// MockstateWrapperMockRecorder is the mock recorder for MockstateWrapper +// MockstateWrapperMockRecorder is the mock recorder for MockstateWrapper. type MockstateWrapperMockRecorder struct { mock *MockstateWrapper } -// NewMockstateWrapper creates a new mock instance +// NewMockstateWrapper creates a new mock instance. func NewMockstateWrapper(ctrl *gomock.Controller) *MockstateWrapper { mock := &MockstateWrapper{ctrl: ctrl} mock.recorder = &MockstateWrapperMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockstateWrapper) EXPECT() *MockstateWrapperMockRecorder { return m.recorder } -// Height mocks base method +// Height mocks base method. func (m *MockstateWrapper) Height() (proto.Height, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Height") @@ -43,65 +44,65 @@ func (m *MockstateWrapper) Height() (proto.Height, error) { return ret0, ret1 } -// Height indicates an expected call of Height +// Height indicates an expected call of Height. func (mr *MockstateWrapperMockRecorder) Height() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Height", reflect.TypeOf((*MockstateWrapper)(nil).Height)) } -// TopBlock mocks base method -func (m *MockstateWrapper) TopBlock() *proto.Block { +// IsActivated mocks base method. +func (m *MockstateWrapper) IsActivated(featureID int16) (bool, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "TopBlock") - ret0, _ := ret[0].(*proto.Block) - return ret0 + ret := m.ctrl.Call(m, "IsActivated", featureID) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// TopBlock indicates an expected call of TopBlock -func (mr *MockstateWrapperMockRecorder) TopBlock() *gomock.Call { +// IsActivated indicates an expected call of IsActivated. +func (mr *MockstateWrapperMockRecorder) IsActivated(featureID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TopBlock", reflect.TypeOf((*MockstateWrapper)(nil).TopBlock)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsActivated", reflect.TypeOf((*MockstateWrapper)(nil).IsActivated), featureID) } -// TxValidation mocks base method -func (m *MockstateWrapper) TxValidation(arg0 func(state.TxValidation) error) error { +// Map mocks base method. +func (m *MockstateWrapper) Map(arg0 func(state.NonThreadSafeState) error) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "TxValidation", arg0) + ret := m.ctrl.Call(m, "Map", arg0) ret0, _ := ret[0].(error) return ret0 } -// TxValidation indicates an expected call of TxValidation -func (mr *MockstateWrapperMockRecorder) TxValidation(arg0 interface{}) *gomock.Call { +// Map indicates an expected call of Map. +func (mr *MockstateWrapperMockRecorder) Map(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TxValidation", reflect.TypeOf((*MockstateWrapper)(nil).TxValidation), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Map", reflect.TypeOf((*MockstateWrapper)(nil).Map), arg0) } -// Map mocks base method -func (m *MockstateWrapper) Map(arg0 func(state.NonThreadSafeState) error) error { +// TopBlock mocks base method. +func (m *MockstateWrapper) TopBlock() *proto.Block { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Map", arg0) - ret0, _ := ret[0].(error) + ret := m.ctrl.Call(m, "TopBlock") + ret0, _ := ret[0].(*proto.Block) return ret0 } -// Map indicates an expected call of Map -func (mr *MockstateWrapperMockRecorder) Map(arg0 interface{}) *gomock.Call { +// TopBlock indicates an expected call of TopBlock. +func (mr *MockstateWrapperMockRecorder) TopBlock() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Map", reflect.TypeOf((*MockstateWrapper)(nil).Map), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TopBlock", reflect.TypeOf((*MockstateWrapper)(nil).TopBlock)) } -// IsActivated mocks base method -func (m *MockstateWrapper) IsActivated(featureID int16) (bool, error) { +// TxValidation mocks base method. +func (m *MockstateWrapper) TxValidation(arg0 func(state.TxValidation) error) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IsActivated", featureID) - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 + ret := m.ctrl.Call(m, "TxValidation", arg0) + ret0, _ := ret[0].(error) + return ret0 } -// IsActivated indicates an expected call of IsActivated -func (mr *MockstateWrapperMockRecorder) IsActivated(featureID interface{}) *gomock.Call { +// TxValidation indicates an expected call of TxValidation. +func (mr *MockstateWrapperMockRecorder) TxValidation(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsActivated", reflect.TypeOf((*MockstateWrapper)(nil).IsActivated), featureID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TxValidation", reflect.TypeOf((*MockstateWrapper)(nil).TxValidation), arg0) } diff --git a/pkg/mock/grpc.go b/pkg/mock/grpc.go index a6b002add..a6a0a5bcf 100644 --- a/pkg/mock/grpc.go +++ b/pkg/mock/grpc.go @@ -6,67 +6,69 @@ package mock import ( context "context" + reflect "reflect" + gomock "github.com/golang/mock/gomock" empty "github.com/golang/protobuf/ptypes/empty" wrappers "github.com/golang/protobuf/ptypes/wrappers" waves "github.com/wavesplatform/gowaves/pkg/grpc/generated/waves" grpc "github.com/wavesplatform/gowaves/pkg/grpc/generated/waves/node/grpc" - reflect "reflect" ) -// MockGrpcHandlers is a mock of GrpcHandlers interface +// MockGrpcHandlers is a mock of GrpcHandlers interface. type MockGrpcHandlers struct { ctrl *gomock.Controller recorder *MockGrpcHandlersMockRecorder } -// MockGrpcHandlersMockRecorder is the mock recorder for MockGrpcHandlers +// MockGrpcHandlersMockRecorder is the mock recorder for MockGrpcHandlers. type MockGrpcHandlersMockRecorder struct { mock *MockGrpcHandlers } -// NewMockGrpcHandlers creates a new mock instance +// NewMockGrpcHandlers creates a new mock instance. func NewMockGrpcHandlers(ctrl *gomock.Controller) *MockGrpcHandlers { mock := &MockGrpcHandlers{ctrl: ctrl} mock.recorder = &MockGrpcHandlersMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockGrpcHandlers) EXPECT() *MockGrpcHandlersMockRecorder { return m.recorder } -// GetBalances mocks base method -func (m *MockGrpcHandlers) GetBalances(arg0 *grpc.BalancesRequest, arg1 grpc.AccountsApi_GetBalancesServer) error { +// Broadcast mocks base method. +func (m *MockGrpcHandlers) Broadcast(arg0 context.Context, arg1 *waves.SignedTransaction) (*waves.SignedTransaction, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBalances", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 + ret := m.ctrl.Call(m, "Broadcast", arg0, arg1) + ret0, _ := ret[0].(*waves.SignedTransaction) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// GetBalances indicates an expected call of GetBalances -func (mr *MockGrpcHandlersMockRecorder) GetBalances(arg0, arg1 interface{}) *gomock.Call { +// Broadcast indicates an expected call of Broadcast. +func (mr *MockGrpcHandlersMockRecorder) Broadcast(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBalances", reflect.TypeOf((*MockGrpcHandlers)(nil).GetBalances), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Broadcast", reflect.TypeOf((*MockGrpcHandlers)(nil).Broadcast), arg0, arg1) } -// GetScript mocks base method -func (m *MockGrpcHandlers) GetScript(arg0 context.Context, arg1 *grpc.AccountRequest) (*grpc.ScriptData, error) { +// GetActivationStatus mocks base method. +func (m *MockGrpcHandlers) GetActivationStatus(arg0 context.Context, arg1 *grpc.ActivationStatusRequest) (*grpc.ActivationStatusResponse, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetScript", arg0, arg1) - ret0, _ := ret[0].(*grpc.ScriptData) + ret := m.ctrl.Call(m, "GetActivationStatus", arg0, arg1) + ret0, _ := ret[0].(*grpc.ActivationStatusResponse) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetScript indicates an expected call of GetScript -func (mr *MockGrpcHandlersMockRecorder) GetScript(arg0, arg1 interface{}) *gomock.Call { +// GetActivationStatus indicates an expected call of GetActivationStatus. +func (mr *MockGrpcHandlersMockRecorder) GetActivationStatus(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetScript", reflect.TypeOf((*MockGrpcHandlers)(nil).GetScript), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetActivationStatus", reflect.TypeOf((*MockGrpcHandlers)(nil).GetActivationStatus), arg0, arg1) } -// GetActiveLeases mocks base method +// GetActiveLeases mocks base method. func (m *MockGrpcHandlers) GetActiveLeases(arg0 *grpc.AccountRequest, arg1 grpc.AccountsApi_GetActiveLeasesServer) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetActiveLeases", arg0, arg1) @@ -74,174 +76,159 @@ func (m *MockGrpcHandlers) GetActiveLeases(arg0 *grpc.AccountRequest, arg1 grpc. return ret0 } -// GetActiveLeases indicates an expected call of GetActiveLeases +// GetActiveLeases indicates an expected call of GetActiveLeases. func (mr *MockGrpcHandlersMockRecorder) GetActiveLeases(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetActiveLeases", reflect.TypeOf((*MockGrpcHandlers)(nil).GetActiveLeases), arg0, arg1) } -// GetDataEntries mocks base method -func (m *MockGrpcHandlers) GetDataEntries(arg0 *grpc.DataRequest, arg1 grpc.AccountsApi_GetDataEntriesServer) error { +// GetBalances mocks base method. +func (m *MockGrpcHandlers) GetBalances(arg0 *grpc.BalancesRequest, arg1 grpc.AccountsApi_GetBalancesServer) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetDataEntries", arg0, arg1) + ret := m.ctrl.Call(m, "GetBalances", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } -// GetDataEntries indicates an expected call of GetDataEntries -func (mr *MockGrpcHandlersMockRecorder) GetDataEntries(arg0, arg1 interface{}) *gomock.Call { +// GetBalances indicates an expected call of GetBalances. +func (mr *MockGrpcHandlersMockRecorder) GetBalances(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDataEntries", reflect.TypeOf((*MockGrpcHandlers)(nil).GetDataEntries), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBalances", reflect.TypeOf((*MockGrpcHandlers)(nil).GetBalances), arg0, arg1) } -// ResolveAlias mocks base method -func (m *MockGrpcHandlers) ResolveAlias(arg0 context.Context, arg1 *wrappers.StringValue) (*wrappers.BytesValue, error) { +// GetBaseTarget mocks base method. +func (m *MockGrpcHandlers) GetBaseTarget(arg0 context.Context, arg1 *empty.Empty) (*grpc.BaseTargetResponse, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ResolveAlias", arg0, arg1) - ret0, _ := ret[0].(*wrappers.BytesValue) + ret := m.ctrl.Call(m, "GetBaseTarget", arg0, arg1) + ret0, _ := ret[0].(*grpc.BaseTargetResponse) ret1, _ := ret[1].(error) return ret0, ret1 } -// ResolveAlias indicates an expected call of ResolveAlias -func (mr *MockGrpcHandlersMockRecorder) ResolveAlias(arg0, arg1 interface{}) *gomock.Call { +// GetBaseTarget indicates an expected call of GetBaseTarget. +func (mr *MockGrpcHandlersMockRecorder) GetBaseTarget(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResolveAlias", reflect.TypeOf((*MockGrpcHandlers)(nil).ResolveAlias), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBaseTarget", reflect.TypeOf((*MockGrpcHandlers)(nil).GetBaseTarget), arg0, arg1) } -// GetInfo mocks base method -func (m *MockGrpcHandlers) GetInfo(arg0 context.Context, arg1 *grpc.AssetRequest) (*grpc.AssetInfoResponse, error) { +// GetBlock mocks base method. +func (m *MockGrpcHandlers) GetBlock(arg0 context.Context, arg1 *grpc.BlockRequest) (*grpc.BlockWithHeight, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetInfo", arg0, arg1) - ret0, _ := ret[0].(*grpc.AssetInfoResponse) + ret := m.ctrl.Call(m, "GetBlock", arg0, arg1) + ret0, _ := ret[0].(*grpc.BlockWithHeight) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetInfo indicates an expected call of GetInfo -func (mr *MockGrpcHandlersMockRecorder) GetInfo(arg0, arg1 interface{}) *gomock.Call { +// GetBlock indicates an expected call of GetBlock. +func (mr *MockGrpcHandlersMockRecorder) GetBlock(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetInfo", reflect.TypeOf((*MockGrpcHandlers)(nil).GetInfo), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlock", reflect.TypeOf((*MockGrpcHandlers)(nil).GetBlock), arg0, arg1) } -// GetNFTList mocks base method -func (m *MockGrpcHandlers) GetNFTList(arg0 *grpc.NFTRequest, arg1 grpc.AssetsApi_GetNFTListServer) error { +// GetBlockRange mocks base method. +func (m *MockGrpcHandlers) GetBlockRange(arg0 *grpc.BlockRangeRequest, arg1 grpc.BlocksApi_GetBlockRangeServer) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetNFTList", arg0, arg1) + ret := m.ctrl.Call(m, "GetBlockRange", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } -// GetNFTList indicates an expected call of GetNFTList -func (mr *MockGrpcHandlersMockRecorder) GetNFTList(arg0, arg1 interface{}) *gomock.Call { +// GetBlockRange indicates an expected call of GetBlockRange. +func (mr *MockGrpcHandlersMockRecorder) GetBlockRange(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNFTList", reflect.TypeOf((*MockGrpcHandlers)(nil).GetNFTList), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockRange", reflect.TypeOf((*MockGrpcHandlers)(nil).GetBlockRange), arg0, arg1) } -// GetActivationStatus mocks base method -func (m *MockGrpcHandlers) GetActivationStatus(arg0 context.Context, arg1 *grpc.ActivationStatusRequest) (*grpc.ActivationStatusResponse, error) { +// GetCumulativeScore mocks base method. +func (m *MockGrpcHandlers) GetCumulativeScore(arg0 context.Context, arg1 *empty.Empty) (*grpc.ScoreResponse, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetActivationStatus", arg0, arg1) - ret0, _ := ret[0].(*grpc.ActivationStatusResponse) + ret := m.ctrl.Call(m, "GetCumulativeScore", arg0, arg1) + ret0, _ := ret[0].(*grpc.ScoreResponse) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetActivationStatus indicates an expected call of GetActivationStatus -func (mr *MockGrpcHandlersMockRecorder) GetActivationStatus(arg0, arg1 interface{}) *gomock.Call { +// GetCumulativeScore indicates an expected call of GetCumulativeScore. +func (mr *MockGrpcHandlersMockRecorder) GetCumulativeScore(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetActivationStatus", reflect.TypeOf((*MockGrpcHandlers)(nil).GetActivationStatus), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCumulativeScore", reflect.TypeOf((*MockGrpcHandlers)(nil).GetCumulativeScore), arg0, arg1) } -// GetBaseTarget mocks base method -func (m *MockGrpcHandlers) GetBaseTarget(arg0 context.Context, arg1 *empty.Empty) (*grpc.BaseTargetResponse, error) { +// GetCurrentHeight mocks base method. +func (m *MockGrpcHandlers) GetCurrentHeight(arg0 context.Context, arg1 *empty.Empty) (*wrappers.UInt32Value, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBaseTarget", arg0, arg1) - ret0, _ := ret[0].(*grpc.BaseTargetResponse) + ret := m.ctrl.Call(m, "GetCurrentHeight", arg0, arg1) + ret0, _ := ret[0].(*wrappers.UInt32Value) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetBaseTarget indicates an expected call of GetBaseTarget -func (mr *MockGrpcHandlersMockRecorder) GetBaseTarget(arg0, arg1 interface{}) *gomock.Call { +// GetCurrentHeight indicates an expected call of GetCurrentHeight. +func (mr *MockGrpcHandlersMockRecorder) GetCurrentHeight(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBaseTarget", reflect.TypeOf((*MockGrpcHandlers)(nil).GetBaseTarget), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentHeight", reflect.TypeOf((*MockGrpcHandlers)(nil).GetCurrentHeight), arg0, arg1) } -// GetCumulativeScore mocks base method -func (m *MockGrpcHandlers) GetCumulativeScore(arg0 context.Context, arg1 *empty.Empty) (*grpc.ScoreResponse, error) { +// GetDataEntries mocks base method. +func (m *MockGrpcHandlers) GetDataEntries(arg0 *grpc.DataRequest, arg1 grpc.AccountsApi_GetDataEntriesServer) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCumulativeScore", arg0, arg1) - ret0, _ := ret[0].(*grpc.ScoreResponse) - ret1, _ := ret[1].(error) - return ret0, ret1 + ret := m.ctrl.Call(m, "GetDataEntries", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 } -// GetCumulativeScore indicates an expected call of GetCumulativeScore -func (mr *MockGrpcHandlersMockRecorder) GetCumulativeScore(arg0, arg1 interface{}) *gomock.Call { +// GetDataEntries indicates an expected call of GetDataEntries. +func (mr *MockGrpcHandlersMockRecorder) GetDataEntries(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCumulativeScore", reflect.TypeOf((*MockGrpcHandlers)(nil).GetCumulativeScore), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDataEntries", reflect.TypeOf((*MockGrpcHandlers)(nil).GetDataEntries), arg0, arg1) } -// GetBlock mocks base method -func (m *MockGrpcHandlers) GetBlock(arg0 context.Context, arg1 *grpc.BlockRequest) (*grpc.BlockWithHeight, error) { +// GetInfo mocks base method. +func (m *MockGrpcHandlers) GetInfo(arg0 context.Context, arg1 *grpc.AssetRequest) (*grpc.AssetInfoResponse, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlock", arg0, arg1) - ret0, _ := ret[0].(*grpc.BlockWithHeight) + ret := m.ctrl.Call(m, "GetInfo", arg0, arg1) + ret0, _ := ret[0].(*grpc.AssetInfoResponse) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetBlock indicates an expected call of GetBlock -func (mr *MockGrpcHandlersMockRecorder) GetBlock(arg0, arg1 interface{}) *gomock.Call { +// GetInfo indicates an expected call of GetInfo. +func (mr *MockGrpcHandlersMockRecorder) GetInfo(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlock", reflect.TypeOf((*MockGrpcHandlers)(nil).GetBlock), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetInfo", reflect.TypeOf((*MockGrpcHandlers)(nil).GetInfo), arg0, arg1) } -// GetBlockRange mocks base method -func (m *MockGrpcHandlers) GetBlockRange(arg0 *grpc.BlockRangeRequest, arg1 grpc.BlocksApi_GetBlockRangeServer) error { +// GetNFTList mocks base method. +func (m *MockGrpcHandlers) GetNFTList(arg0 *grpc.NFTRequest, arg1 grpc.AssetsApi_GetNFTListServer) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlockRange", arg0, arg1) + ret := m.ctrl.Call(m, "GetNFTList", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } -// GetBlockRange indicates an expected call of GetBlockRange -func (mr *MockGrpcHandlersMockRecorder) GetBlockRange(arg0, arg1 interface{}) *gomock.Call { +// GetNFTList indicates an expected call of GetNFTList. +func (mr *MockGrpcHandlersMockRecorder) GetNFTList(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockRange", reflect.TypeOf((*MockGrpcHandlers)(nil).GetBlockRange), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNFTList", reflect.TypeOf((*MockGrpcHandlers)(nil).GetNFTList), arg0, arg1) } -// GetCurrentHeight mocks base method -func (m *MockGrpcHandlers) GetCurrentHeight(arg0 context.Context, arg1 *empty.Empty) (*wrappers.UInt32Value, error) { +// GetScript mocks base method. +func (m *MockGrpcHandlers) GetScript(arg0 context.Context, arg1 *grpc.AccountRequest) (*grpc.ScriptData, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetCurrentHeight", arg0, arg1) - ret0, _ := ret[0].(*wrappers.UInt32Value) + ret := m.ctrl.Call(m, "GetScript", arg0, arg1) + ret0, _ := ret[0].(*grpc.ScriptData) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetCurrentHeight indicates an expected call of GetCurrentHeight -func (mr *MockGrpcHandlersMockRecorder) GetCurrentHeight(arg0, arg1 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentHeight", reflect.TypeOf((*MockGrpcHandlers)(nil).GetCurrentHeight), arg0, arg1) -} - -// GetTransactions mocks base method -func (m *MockGrpcHandlers) GetTransactions(arg0 *grpc.TransactionsRequest, arg1 grpc.TransactionsApi_GetTransactionsServer) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetTransactions", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 -} - -// GetTransactions indicates an expected call of GetTransactions -func (mr *MockGrpcHandlersMockRecorder) GetTransactions(arg0, arg1 interface{}) *gomock.Call { +// GetScript indicates an expected call of GetScript. +func (mr *MockGrpcHandlersMockRecorder) GetScript(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTransactions", reflect.TypeOf((*MockGrpcHandlers)(nil).GetTransactions), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetScript", reflect.TypeOf((*MockGrpcHandlers)(nil).GetScript), arg0, arg1) } -// GetStateChanges mocks base method +// GetStateChanges mocks base method. func (m *MockGrpcHandlers) GetStateChanges(arg0 *grpc.TransactionsRequest, arg1 grpc.TransactionsApi_GetStateChangesServer) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetStateChanges", arg0, arg1) @@ -249,13 +236,13 @@ func (m *MockGrpcHandlers) GetStateChanges(arg0 *grpc.TransactionsRequest, arg1 return ret0 } -// GetStateChanges indicates an expected call of GetStateChanges +// GetStateChanges indicates an expected call of GetStateChanges. func (mr *MockGrpcHandlersMockRecorder) GetStateChanges(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStateChanges", reflect.TypeOf((*MockGrpcHandlers)(nil).GetStateChanges), arg0, arg1) } -// GetStatuses mocks base method +// GetStatuses mocks base method. func (m *MockGrpcHandlers) GetStatuses(arg0 *grpc.TransactionsByIdRequest, arg1 grpc.TransactionsApi_GetStatusesServer) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetStatuses", arg0, arg1) @@ -263,13 +250,27 @@ func (m *MockGrpcHandlers) GetStatuses(arg0 *grpc.TransactionsByIdRequest, arg1 return ret0 } -// GetStatuses indicates an expected call of GetStatuses +// GetStatuses indicates an expected call of GetStatuses. func (mr *MockGrpcHandlersMockRecorder) GetStatuses(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStatuses", reflect.TypeOf((*MockGrpcHandlers)(nil).GetStatuses), arg0, arg1) } -// GetUnconfirmed mocks base method +// GetTransactions mocks base method. +func (m *MockGrpcHandlers) GetTransactions(arg0 *grpc.TransactionsRequest, arg1 grpc.TransactionsApi_GetTransactionsServer) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetTransactions", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// GetTransactions indicates an expected call of GetTransactions. +func (mr *MockGrpcHandlersMockRecorder) GetTransactions(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTransactions", reflect.TypeOf((*MockGrpcHandlers)(nil).GetTransactions), arg0, arg1) +} + +// GetUnconfirmed mocks base method. func (m *MockGrpcHandlers) GetUnconfirmed(arg0 *grpc.TransactionsRequest, arg1 grpc.TransactionsApi_GetUnconfirmedServer) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetUnconfirmed", arg0, arg1) @@ -277,38 +278,38 @@ func (m *MockGrpcHandlers) GetUnconfirmed(arg0 *grpc.TransactionsRequest, arg1 g return ret0 } -// GetUnconfirmed indicates an expected call of GetUnconfirmed +// GetUnconfirmed indicates an expected call of GetUnconfirmed. func (mr *MockGrpcHandlersMockRecorder) GetUnconfirmed(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUnconfirmed", reflect.TypeOf((*MockGrpcHandlers)(nil).GetUnconfirmed), arg0, arg1) } -// Sign mocks base method -func (m *MockGrpcHandlers) Sign(arg0 context.Context, arg1 *grpc.SignRequest) (*waves.SignedTransaction, error) { +// ResolveAlias mocks base method. +func (m *MockGrpcHandlers) ResolveAlias(arg0 context.Context, arg1 *wrappers.StringValue) (*wrappers.BytesValue, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Sign", arg0, arg1) - ret0, _ := ret[0].(*waves.SignedTransaction) + ret := m.ctrl.Call(m, "ResolveAlias", arg0, arg1) + ret0, _ := ret[0].(*wrappers.BytesValue) ret1, _ := ret[1].(error) return ret0, ret1 } -// Sign indicates an expected call of Sign -func (mr *MockGrpcHandlersMockRecorder) Sign(arg0, arg1 interface{}) *gomock.Call { +// ResolveAlias indicates an expected call of ResolveAlias. +func (mr *MockGrpcHandlersMockRecorder) ResolveAlias(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Sign", reflect.TypeOf((*MockGrpcHandlers)(nil).Sign), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResolveAlias", reflect.TypeOf((*MockGrpcHandlers)(nil).ResolveAlias), arg0, arg1) } -// Broadcast mocks base method -func (m *MockGrpcHandlers) Broadcast(arg0 context.Context, arg1 *waves.SignedTransaction) (*waves.SignedTransaction, error) { +// Sign mocks base method. +func (m *MockGrpcHandlers) Sign(arg0 context.Context, arg1 *grpc.SignRequest) (*waves.SignedTransaction, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Broadcast", arg0, arg1) + ret := m.ctrl.Call(m, "Sign", arg0, arg1) ret0, _ := ret[0].(*waves.SignedTransaction) ret1, _ := ret[1].(error) return ret0, ret1 } -// Broadcast indicates an expected call of Broadcast -func (mr *MockGrpcHandlersMockRecorder) Broadcast(arg0, arg1 interface{}) *gomock.Call { +// Sign indicates an expected call of Sign. +func (mr *MockGrpcHandlersMockRecorder) Sign(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Broadcast", reflect.TypeOf((*MockGrpcHandlers)(nil).Broadcast), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Sign", reflect.TypeOf((*MockGrpcHandlers)(nil).Sign), arg0, arg1) } diff --git a/pkg/mock/peer.go b/pkg/mock/peer.go index 895e33d20..e6f5f412b 100644 --- a/pkg/mock/peer.go +++ b/pkg/mock/peer.go @@ -5,51 +5,38 @@ package mock import ( + reflect "reflect" + gomock "github.com/golang/mock/gomock" conn "github.com/wavesplatform/gowaves/pkg/p2p/conn" peer "github.com/wavesplatform/gowaves/pkg/p2p/peer" proto "github.com/wavesplatform/gowaves/pkg/proto" - reflect "reflect" ) -// MockPeer is a mock of Peer interface +// MockPeer is a mock of Peer interface. type MockPeer struct { ctrl *gomock.Controller recorder *MockPeerMockRecorder } -// MockPeerMockRecorder is the mock recorder for MockPeer +// MockPeerMockRecorder is the mock recorder for MockPeer. type MockPeerMockRecorder struct { mock *MockPeer } -// NewMockPeer creates a new mock instance +// NewMockPeer creates a new mock instance. func NewMockPeer(ctrl *gomock.Controller) *MockPeer { mock := &MockPeer{ctrl: ctrl} mock.recorder = &MockPeerMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockPeer) EXPECT() *MockPeerMockRecorder { return m.recorder } -// Direction mocks base method -func (m *MockPeer) Direction() peer.Direction { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Direction") - ret0, _ := ret[0].(peer.Direction) - return ret0 -} - -// Direction indicates an expected call of Direction -func (mr *MockPeerMockRecorder) Direction() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Direction", reflect.TypeOf((*MockPeer)(nil).Direction)) -} - -// Close mocks base method +// Close mocks base method. func (m *MockPeer) Close() error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Close") @@ -57,67 +44,69 @@ func (m *MockPeer) Close() error { return ret0 } -// Close indicates an expected call of Close +// Close indicates an expected call of Close. func (mr *MockPeerMockRecorder) Close() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockPeer)(nil).Close)) } -// SendMessage mocks base method -func (m *MockPeer) SendMessage(arg0 proto.Message) { +// Connection mocks base method. +func (m *MockPeer) Connection() conn.Connection { m.ctrl.T.Helper() - m.ctrl.Call(m, "SendMessage", arg0) + ret := m.ctrl.Call(m, "Connection") + ret0, _ := ret[0].(conn.Connection) + return ret0 } -// SendMessage indicates an expected call of SendMessage -func (mr *MockPeerMockRecorder) SendMessage(arg0 interface{}) *gomock.Call { +// Connection indicates an expected call of Connection. +func (mr *MockPeerMockRecorder) Connection() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMessage", reflect.TypeOf((*MockPeer)(nil).SendMessage), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Connection", reflect.TypeOf((*MockPeer)(nil).Connection)) } -// ID mocks base method -func (m *MockPeer) ID() string { +// Direction mocks base method. +func (m *MockPeer) Direction() peer.Direction { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ID") - ret0, _ := ret[0].(string) + ret := m.ctrl.Call(m, "Direction") + ret0, _ := ret[0].(peer.Direction) return ret0 } -// ID indicates an expected call of ID -func (mr *MockPeerMockRecorder) ID() *gomock.Call { +// Direction indicates an expected call of Direction. +func (mr *MockPeerMockRecorder) Direction() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ID", reflect.TypeOf((*MockPeer)(nil).ID)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Direction", reflect.TypeOf((*MockPeer)(nil).Direction)) } -// Connection mocks base method -func (m *MockPeer) Connection() conn.Connection { +// Handshake mocks base method. +func (m *MockPeer) Handshake() proto.Handshake { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Connection") - ret0, _ := ret[0].(conn.Connection) + ret := m.ctrl.Call(m, "Handshake") + ret0, _ := ret[0].(proto.Handshake) return ret0 } -// Connection indicates an expected call of Connection -func (mr *MockPeerMockRecorder) Connection() *gomock.Call { +// Handshake indicates an expected call of Handshake. +func (mr *MockPeerMockRecorder) Handshake() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Connection", reflect.TypeOf((*MockPeer)(nil).Connection)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Handshake", reflect.TypeOf((*MockPeer)(nil).Handshake)) } -// Handshake mocks base method -func (m *MockPeer) Handshake() proto.Handshake { +// ID mocks base method. +func (m *MockPeer) ID() string { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Handshake") - ret0, _ := ret[0].(proto.Handshake) + ret := m.ctrl.Call(m, "ID") + ret0, _ := ret[0].(string) return ret0 } -// Handshake indicates an expected call of Handshake -func (mr *MockPeerMockRecorder) Handshake() *gomock.Call { +// ID indicates an expected call of ID. +func (mr *MockPeerMockRecorder) ID() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Handshake", reflect.TypeOf((*MockPeer)(nil).Handshake)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ID", reflect.TypeOf((*MockPeer)(nil).ID)) } -// RemoteAddr mocks base method +// RemoteAddr mocks base method. func (m *MockPeer) RemoteAddr() proto.TCPAddr { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "RemoteAddr") @@ -125,8 +114,20 @@ func (m *MockPeer) RemoteAddr() proto.TCPAddr { return ret0 } -// RemoteAddr indicates an expected call of RemoteAddr +// RemoteAddr indicates an expected call of RemoteAddr. func (mr *MockPeerMockRecorder) RemoteAddr() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoteAddr", reflect.TypeOf((*MockPeer)(nil).RemoteAddr)) } + +// SendMessage mocks base method. +func (m *MockPeer) SendMessage(arg0 proto.Message) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SendMessage", arg0) +} + +// SendMessage indicates an expected call of SendMessage. +func (mr *MockPeerMockRecorder) SendMessage(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMessage", reflect.TypeOf((*MockPeer)(nil).SendMessage), arg0) +} diff --git a/pkg/mock/peer_manager.go b/pkg/mock/peer_manager.go index 60a069743..cda43493f 100644 --- a/pkg/mock/peer_manager.go +++ b/pkg/mock/peer_manager.go @@ -6,67 +6,104 @@ package mock import ( context "context" - gomock "github.com/golang/mock/gomock" - peer "github.com/wavesplatform/gowaves/pkg/p2p/peer" - proto "github.com/wavesplatform/gowaves/pkg/proto" big "math/big" net "net" reflect "reflect" + + gomock "github.com/golang/mock/gomock" + peer "github.com/wavesplatform/gowaves/pkg/p2p/peer" + proto "github.com/wavesplatform/gowaves/pkg/proto" ) -// MockPeerManager is a mock of PeerManager interface +// MockPeerManager is a mock of PeerManager interface. type MockPeerManager struct { ctrl *gomock.Controller recorder *MockPeerManagerMockRecorder } -// MockPeerManagerMockRecorder is the mock recorder for MockPeerManager +// MockPeerManagerMockRecorder is the mock recorder for MockPeerManager. type MockPeerManagerMockRecorder struct { mock *MockPeerManager } -// NewMockPeerManager creates a new mock instance +// NewMockPeerManager creates a new mock instance. func NewMockPeerManager(ctrl *gomock.Controller) *MockPeerManager { mock := &MockPeerManager{ctrl: ctrl} mock.recorder = &MockPeerManagerMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockPeerManager) EXPECT() *MockPeerManagerMockRecorder { return m.recorder } -// Connected mocks base method -func (m *MockPeerManager) Connected(arg0 peer.Peer) (peer.Peer, bool) { +// AddConnected mocks base method. +func (m *MockPeerManager) AddConnected(arg0 peer.Peer) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Connected", arg0) - ret0, _ := ret[0].(peer.Peer) - ret1, _ := ret[1].(bool) - return ret0, ret1 + m.ctrl.Call(m, "AddConnected", arg0) } -// Connected indicates an expected call of Connected -func (mr *MockPeerManagerMockRecorder) Connected(arg0 interface{}) *gomock.Call { +// AddConnected indicates an expected call of AddConnected. +func (mr *MockPeerManagerMockRecorder) AddConnected(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Connected", reflect.TypeOf((*MockPeerManager)(nil).Connected), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddConnected", reflect.TypeOf((*MockPeerManager)(nil).AddConnected), arg0) } -// NewConnection mocks base method -func (m *MockPeerManager) NewConnection(arg0 peer.Peer) error { +// AskPeers mocks base method. +func (m *MockPeerManager) AskPeers() { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewConnection", arg0) + m.ctrl.Call(m, "AskPeers") +} + +// AskPeers indicates an expected call of AskPeers. +func (mr *MockPeerManagerMockRecorder) AskPeers() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AskPeers", reflect.TypeOf((*MockPeerManager)(nil).AskPeers)) +} + +// Close mocks base method. +func (m *MockPeerManager) Close() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Close") +} + +// Close indicates an expected call of Close. +func (mr *MockPeerManagerMockRecorder) Close() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockPeerManager)(nil).Close)) +} + +// Connect mocks base method. +func (m *MockPeerManager) Connect(arg0 context.Context, arg1 proto.TCPAddr) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Connect", arg0, arg1) ret0, _ := ret[0].(error) return ret0 } -// NewConnection indicates an expected call of NewConnection -func (mr *MockPeerManagerMockRecorder) NewConnection(arg0 interface{}) *gomock.Call { +// Connect indicates an expected call of Connect. +func (mr *MockPeerManagerMockRecorder) Connect(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewConnection", reflect.TypeOf((*MockPeerManager)(nil).NewConnection), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Connect", reflect.TypeOf((*MockPeerManager)(nil).Connect), arg0, arg1) +} + +// Connected mocks base method. +func (m *MockPeerManager) Connected(arg0 peer.Peer) (peer.Peer, bool) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Connected", arg0) + ret0, _ := ret[0].(peer.Peer) + ret1, _ := ret[1].(bool) + return ret0, ret1 } -// ConnectedCount mocks base method +// Connected indicates an expected call of Connected. +func (mr *MockPeerManagerMockRecorder) Connected(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Connected", reflect.TypeOf((*MockPeerManager)(nil).Connected), arg0) +} + +// ConnectedCount mocks base method. func (m *MockPeerManager) ConnectedCount() int { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ConnectedCount") @@ -74,40 +111,52 @@ func (m *MockPeerManager) ConnectedCount() int { return ret0 } -// ConnectedCount indicates an expected call of ConnectedCount +// ConnectedCount indicates an expected call of ConnectedCount. func (mr *MockPeerManagerMockRecorder) ConnectedCount() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConnectedCount", reflect.TypeOf((*MockPeerManager)(nil).ConnectedCount)) } -// InOutCount mocks base method -func (m *MockPeerManager) InOutCount() (int, int) { +// Disconnect mocks base method. +func (m *MockPeerManager) Disconnect(arg0 peer.Peer) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "InOutCount") - ret0, _ := ret[0].(int) - ret1, _ := ret[1].(int) - return ret0, ret1 + m.ctrl.Call(m, "Disconnect", arg0) } -// InOutCount indicates an expected call of InOutCount -func (mr *MockPeerManagerMockRecorder) InOutCount() *gomock.Call { +// Disconnect indicates an expected call of Disconnect. +func (mr *MockPeerManagerMockRecorder) Disconnect(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InOutCount", reflect.TypeOf((*MockPeerManager)(nil).InOutCount)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Disconnect", reflect.TypeOf((*MockPeerManager)(nil).Disconnect), arg0) } -// EachConnected mocks base method +// EachConnected mocks base method. func (m *MockPeerManager) EachConnected(arg0 func(peer.Peer, *proto.Score)) { m.ctrl.T.Helper() m.ctrl.Call(m, "EachConnected", arg0) } -// EachConnected indicates an expected call of EachConnected +// EachConnected indicates an expected call of EachConnected. func (mr *MockPeerManagerMockRecorder) EachConnected(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EachConnected", reflect.TypeOf((*MockPeerManager)(nil).EachConnected), arg0) } -// IsSuspended mocks base method +// InOutCount mocks base method. +func (m *MockPeerManager) InOutCount() (int, int) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "InOutCount") + ret0, _ := ret[0].(int) + ret1, _ := ret[1].(int) + return ret0, ret1 +} + +// InOutCount indicates an expected call of InOutCount. +func (mr *MockPeerManagerMockRecorder) InOutCount() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InOutCount", reflect.TypeOf((*MockPeerManager)(nil).InOutCount)) +} + +// IsSuspended mocks base method. func (m *MockPeerManager) IsSuspended(arg0 peer.Peer) bool { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IsSuspended", arg0) @@ -115,51 +164,42 @@ func (m *MockPeerManager) IsSuspended(arg0 peer.Peer) bool { return ret0 } -// IsSuspended indicates an expected call of IsSuspended +// IsSuspended indicates an expected call of IsSuspended. func (mr *MockPeerManagerMockRecorder) IsSuspended(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsSuspended", reflect.TypeOf((*MockPeerManager)(nil).IsSuspended), arg0) } -// Suspend mocks base method -func (m *MockPeerManager) Suspend(arg0 peer.Peer, arg1 string) { +// KnownPeers mocks base method. +func (m *MockPeerManager) KnownPeers() ([]proto.TCPAddr, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "Suspend", arg0, arg1) + ret := m.ctrl.Call(m, "KnownPeers") + ret0, _ := ret[0].([]proto.TCPAddr) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// Suspend indicates an expected call of Suspend -func (mr *MockPeerManagerMockRecorder) Suspend(arg0, arg1 interface{}) *gomock.Call { +// KnownPeers indicates an expected call of KnownPeers. +func (mr *MockPeerManagerMockRecorder) KnownPeers() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Suspend", reflect.TypeOf((*MockPeerManager)(nil).Suspend), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "KnownPeers", reflect.TypeOf((*MockPeerManager)(nil).KnownPeers)) } -// Suspended mocks base method -func (m *MockPeerManager) Suspended() []string { +// NewConnection mocks base method. +func (m *MockPeerManager) NewConnection(arg0 peer.Peer) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Suspended") - ret0, _ := ret[0].([]string) + ret := m.ctrl.Call(m, "NewConnection", arg0) + ret0, _ := ret[0].(error) return ret0 } -// Suspended indicates an expected call of Suspended -func (mr *MockPeerManagerMockRecorder) Suspended() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Suspended", reflect.TypeOf((*MockPeerManager)(nil).Suspended)) -} - -// AddConnected mocks base method -func (m *MockPeerManager) AddConnected(arg0 peer.Peer) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddConnected", arg0) -} - -// AddConnected indicates an expected call of AddConnected -func (mr *MockPeerManagerMockRecorder) AddConnected(arg0 interface{}) *gomock.Call { +// NewConnection indicates an expected call of NewConnection. +func (mr *MockPeerManagerMockRecorder) NewConnection(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddConnected", reflect.TypeOf((*MockPeerManager)(nil).AddConnected), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewConnection", reflect.TypeOf((*MockPeerManager)(nil).NewConnection), arg0) } -// PeerWithHighestScore mocks base method +// PeerWithHighestScore mocks base method. func (m *MockPeerManager) PeerWithHighestScore() (peer.Peer, *big.Int, bool) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PeerWithHighestScore") @@ -169,94 +209,54 @@ func (m *MockPeerManager) PeerWithHighestScore() (peer.Peer, *big.Int, bool) { return ret0, ret1, ret2 } -// PeerWithHighestScore indicates an expected call of PeerWithHighestScore +// PeerWithHighestScore indicates an expected call of PeerWithHighestScore. func (mr *MockPeerManagerMockRecorder) PeerWithHighestScore() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PeerWithHighestScore", reflect.TypeOf((*MockPeerManager)(nil).PeerWithHighestScore)) } -// UpdateScore mocks base method -func (m *MockPeerManager) UpdateScore(p peer.Peer, score *proto.Score) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateScore", p, score) - ret0, _ := ret[0].(error) - return ret0 -} - -// UpdateScore indicates an expected call of UpdateScore -func (mr *MockPeerManagerMockRecorder) UpdateScore(p, score interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateScore", reflect.TypeOf((*MockPeerManager)(nil).UpdateScore), p, score) -} - -// UpdateKnownPeers mocks base method -func (m *MockPeerManager) UpdateKnownPeers(arg0 []proto.TCPAddr) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateKnownPeers", arg0) - ret0, _ := ret[0].(error) - return ret0 -} - -// UpdateKnownPeers indicates an expected call of UpdateKnownPeers -func (mr *MockPeerManagerMockRecorder) UpdateKnownPeers(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateKnownPeers", reflect.TypeOf((*MockPeerManager)(nil).UpdateKnownPeers), arg0) -} - -// KnownPeers mocks base method -func (m *MockPeerManager) KnownPeers() ([]proto.TCPAddr, error) { +// Score mocks base method. +func (m *MockPeerManager) Score(p peer.Peer) (*proto.Score, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "KnownPeers") - ret0, _ := ret[0].([]proto.TCPAddr) + ret := m.ctrl.Call(m, "Score", p) + ret0, _ := ret[0].(*proto.Score) ret1, _ := ret[1].(error) return ret0, ret1 } -// KnownPeers indicates an expected call of KnownPeers -func (mr *MockPeerManagerMockRecorder) KnownPeers() *gomock.Call { +// Score indicates an expected call of Score. +func (mr *MockPeerManagerMockRecorder) Score(p interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "KnownPeers", reflect.TypeOf((*MockPeerManager)(nil).KnownPeers)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Score", reflect.TypeOf((*MockPeerManager)(nil).Score), p) } -// Close mocks base method -func (m *MockPeerManager) Close() { +// SpawnIncomingConnection mocks base method. +func (m *MockPeerManager) SpawnIncomingConnection(ctx context.Context, conn net.Conn) error { m.ctrl.T.Helper() - m.ctrl.Call(m, "Close") + ret := m.ctrl.Call(m, "SpawnIncomingConnection", ctx, conn) + ret0, _ := ret[0].(error) + return ret0 } -// Close indicates an expected call of Close -func (mr *MockPeerManagerMockRecorder) Close() *gomock.Call { +// SpawnIncomingConnection indicates an expected call of SpawnIncomingConnection. +func (mr *MockPeerManagerMockRecorder) SpawnIncomingConnection(ctx, conn interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockPeerManager)(nil).Close)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SpawnIncomingConnection", reflect.TypeOf((*MockPeerManager)(nil).SpawnIncomingConnection), ctx, conn) } -// SpawnOutgoingConnections mocks base method +// SpawnOutgoingConnections mocks base method. func (m *MockPeerManager) SpawnOutgoingConnections(arg0 context.Context) { m.ctrl.T.Helper() m.ctrl.Call(m, "SpawnOutgoingConnections", arg0) } -// SpawnOutgoingConnections indicates an expected call of SpawnOutgoingConnections +// SpawnOutgoingConnections indicates an expected call of SpawnOutgoingConnections. func (mr *MockPeerManagerMockRecorder) SpawnOutgoingConnections(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SpawnOutgoingConnections", reflect.TypeOf((*MockPeerManager)(nil).SpawnOutgoingConnections), arg0) } -// SpawnIncomingConnection mocks base method -func (m *MockPeerManager) SpawnIncomingConnection(ctx context.Context, conn net.Conn) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SpawnIncomingConnection", ctx, conn) - ret0, _ := ret[0].(error) - return ret0 -} - -// SpawnIncomingConnection indicates an expected call of SpawnIncomingConnection -func (mr *MockPeerManagerMockRecorder) SpawnIncomingConnection(ctx, conn interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SpawnIncomingConnection", reflect.TypeOf((*MockPeerManager)(nil).SpawnIncomingConnection), ctx, conn) -} - -// Spawned mocks base method +// Spawned mocks base method. func (m *MockPeerManager) Spawned() []proto.IpPort { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Spawned") @@ -264,61 +264,62 @@ func (m *MockPeerManager) Spawned() []proto.IpPort { return ret0 } -// Spawned indicates an expected call of Spawned +// Spawned indicates an expected call of Spawned. func (mr *MockPeerManagerMockRecorder) Spawned() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Spawned", reflect.TypeOf((*MockPeerManager)(nil).Spawned)) } -// Connect mocks base method -func (m *MockPeerManager) Connect(arg0 context.Context, arg1 proto.TCPAddr) error { +// Suspend mocks base method. +func (m *MockPeerManager) Suspend(arg0 peer.Peer, arg1 string) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Connect", arg0, arg1) - ret0, _ := ret[0].(error) - return ret0 + m.ctrl.Call(m, "Suspend", arg0, arg1) } -// Connect indicates an expected call of Connect -func (mr *MockPeerManagerMockRecorder) Connect(arg0, arg1 interface{}) *gomock.Call { +// Suspend indicates an expected call of Suspend. +func (mr *MockPeerManagerMockRecorder) Suspend(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Connect", reflect.TypeOf((*MockPeerManager)(nil).Connect), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Suspend", reflect.TypeOf((*MockPeerManager)(nil).Suspend), arg0, arg1) } -// Score mocks base method -func (m *MockPeerManager) Score(p peer.Peer) (*proto.Score, error) { +// Suspended mocks base method. +func (m *MockPeerManager) Suspended() []string { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Score", p) - ret0, _ := ret[0].(*proto.Score) - ret1, _ := ret[1].(error) - return ret0, ret1 + ret := m.ctrl.Call(m, "Suspended") + ret0, _ := ret[0].([]string) + return ret0 } -// Score indicates an expected call of Score -func (mr *MockPeerManagerMockRecorder) Score(p interface{}) *gomock.Call { +// Suspended indicates an expected call of Suspended. +func (mr *MockPeerManagerMockRecorder) Suspended() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Score", reflect.TypeOf((*MockPeerManager)(nil).Score), p) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Suspended", reflect.TypeOf((*MockPeerManager)(nil).Suspended)) } -// AskPeers mocks base method -func (m *MockPeerManager) AskPeers() { +// UpdateKnownPeers mocks base method. +func (m *MockPeerManager) UpdateKnownPeers(arg0 []proto.TCPAddr) error { m.ctrl.T.Helper() - m.ctrl.Call(m, "AskPeers") + ret := m.ctrl.Call(m, "UpdateKnownPeers", arg0) + ret0, _ := ret[0].(error) + return ret0 } -// AskPeers indicates an expected call of AskPeers -func (mr *MockPeerManagerMockRecorder) AskPeers() *gomock.Call { +// UpdateKnownPeers indicates an expected call of UpdateKnownPeers. +func (mr *MockPeerManagerMockRecorder) UpdateKnownPeers(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AskPeers", reflect.TypeOf((*MockPeerManager)(nil).AskPeers)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateKnownPeers", reflect.TypeOf((*MockPeerManager)(nil).UpdateKnownPeers), arg0) } -// Disconnect mocks base method -func (m *MockPeerManager) Disconnect(arg0 peer.Peer) { +// UpdateScore mocks base method. +func (m *MockPeerManager) UpdateScore(p peer.Peer, score *proto.Score) error { m.ctrl.T.Helper() - m.ctrl.Call(m, "Disconnect", arg0) + ret := m.ctrl.Call(m, "UpdateScore", p, score) + ret0, _ := ret[0].(error) + return ret0 } -// Disconnect indicates an expected call of Disconnect -func (mr *MockPeerManagerMockRecorder) Disconnect(arg0 interface{}) *gomock.Call { +// UpdateScore indicates an expected call of UpdateScore. +func (mr *MockPeerManagerMockRecorder) UpdateScore(p, score interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Disconnect", reflect.TypeOf((*MockPeerManager)(nil).Disconnect), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateScore", reflect.TypeOf((*MockPeerManager)(nil).UpdateScore), p, score) } diff --git a/pkg/mock/state.go b/pkg/mock/state.go index d377cedcf..d6c109e0f 100644 --- a/pkg/mock/state.go +++ b/pkg/mock/state.go @@ -5,55 +5,55 @@ package mock import ( + big "math/big" + reflect "reflect" + gomock "github.com/golang/mock/gomock" crypto "github.com/wavesplatform/gowaves/pkg/crypto" proto "github.com/wavesplatform/gowaves/pkg/proto" settings "github.com/wavesplatform/gowaves/pkg/settings" state "github.com/wavesplatform/gowaves/pkg/state" - big "math/big" - reflect "reflect" + types "github.com/wavesplatform/gowaves/pkg/types" ) -// MockTransactionIterator is a mock of TransactionIterator interface +// MockTransactionIterator is a mock of TransactionIterator interface. type MockTransactionIterator struct { ctrl *gomock.Controller recorder *MockTransactionIteratorMockRecorder } -// MockTransactionIteratorMockRecorder is the mock recorder for MockTransactionIterator +// MockTransactionIteratorMockRecorder is the mock recorder for MockTransactionIterator. type MockTransactionIteratorMockRecorder struct { mock *MockTransactionIterator } -// NewMockTransactionIterator creates a new mock instance +// NewMockTransactionIterator creates a new mock instance. func NewMockTransactionIterator(ctrl *gomock.Controller) *MockTransactionIterator { mock := &MockTransactionIterator{ctrl: ctrl} mock.recorder = &MockTransactionIteratorMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockTransactionIterator) EXPECT() *MockTransactionIteratorMockRecorder { return m.recorder } -// Transaction mocks base method -func (m *MockTransactionIterator) Transaction() (proto.Transaction, bool, error) { +// Error mocks base method. +func (m *MockTransactionIterator) Error() error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Transaction") - ret0, _ := ret[0].(proto.Transaction) - ret1, _ := ret[1].(bool) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 + ret := m.ctrl.Call(m, "Error") + ret0, _ := ret[0].(error) + return ret0 } -// Transaction indicates an expected call of Transaction -func (mr *MockTransactionIteratorMockRecorder) Transaction() *gomock.Call { +// Error indicates an expected call of Error. +func (mr *MockTransactionIteratorMockRecorder) Error() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Transaction", reflect.TypeOf((*MockTransactionIterator)(nil).Transaction)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Error", reflect.TypeOf((*MockTransactionIterator)(nil).Error)) } -// Next mocks base method +// Next mocks base method. func (m *MockTransactionIterator) Next() bool { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Next") @@ -61,151 +61,199 @@ func (m *MockTransactionIterator) Next() bool { return ret0 } -// Next indicates an expected call of Next +// Next indicates an expected call of Next. func (mr *MockTransactionIteratorMockRecorder) Next() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Next", reflect.TypeOf((*MockTransactionIterator)(nil).Next)) } -// Release mocks base method +// Release mocks base method. func (m *MockTransactionIterator) Release() { m.ctrl.T.Helper() m.ctrl.Call(m, "Release") } -// Release indicates an expected call of Release +// Release indicates an expected call of Release. func (mr *MockTransactionIteratorMockRecorder) Release() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Release", reflect.TypeOf((*MockTransactionIterator)(nil).Release)) } -// Error mocks base method -func (m *MockTransactionIterator) Error() error { +// Transaction mocks base method. +func (m *MockTransactionIterator) Transaction() (proto.Transaction, bool, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Error") - ret0, _ := ret[0].(error) - return ret0 + ret := m.ctrl.Call(m, "Transaction") + ret0, _ := ret[0].(proto.Transaction) + ret1, _ := ret[1].(bool) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 } -// Error indicates an expected call of Error -func (mr *MockTransactionIteratorMockRecorder) Error() *gomock.Call { +// Transaction indicates an expected call of Transaction. +func (mr *MockTransactionIteratorMockRecorder) Transaction() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Error", reflect.TypeOf((*MockTransactionIterator)(nil).Error)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Transaction", reflect.TypeOf((*MockTransactionIterator)(nil).Transaction)) } -// MockStateInfo is a mock of StateInfo interface +// MockStateInfo is a mock of StateInfo interface. type MockStateInfo struct { ctrl *gomock.Controller recorder *MockStateInfoMockRecorder } -// MockStateInfoMockRecorder is the mock recorder for MockStateInfo +// MockStateInfoMockRecorder is the mock recorder for MockStateInfo. type MockStateInfoMockRecorder struct { mock *MockStateInfo } -// NewMockStateInfo creates a new mock instance +// NewMockStateInfo creates a new mock instance. func NewMockStateInfo(ctrl *gomock.Controller) *MockStateInfo { mock := &MockStateInfo{ctrl: ctrl} mock.recorder = &MockStateInfoMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockStateInfo) EXPECT() *MockStateInfoMockRecorder { return m.recorder } -// TopBlock mocks base method -func (m *MockStateInfo) TopBlock() *proto.Block { +// AccountBalance mocks base method. +func (m *MockStateInfo) AccountBalance(account proto.Recipient, asset []byte) (uint64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "TopBlock") - ret0, _ := ret[0].(*proto.Block) - return ret0 + ret := m.ctrl.Call(m, "AccountBalance", account, asset) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// TopBlock indicates an expected call of TopBlock -func (mr *MockStateInfoMockRecorder) TopBlock() *gomock.Call { +// AccountBalance indicates an expected call of AccountBalance. +func (mr *MockStateInfoMockRecorder) AccountBalance(account, asset interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TopBlock", reflect.TypeOf((*MockStateInfo)(nil).TopBlock)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AccountBalance", reflect.TypeOf((*MockStateInfo)(nil).AccountBalance), account, asset) } -// Block mocks base method -func (m *MockStateInfo) Block(blockID proto.BlockID) (*proto.Block, error) { +// ActivationHeight mocks base method. +func (m *MockStateInfo) ActivationHeight(featureID int16) (proto.Height, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Block", blockID) - ret0, _ := ret[0].(*proto.Block) + ret := m.ctrl.Call(m, "ActivationHeight", featureID) + ret0, _ := ret[0].(proto.Height) ret1, _ := ret[1].(error) return ret0, ret1 } -// Block indicates an expected call of Block -func (mr *MockStateInfoMockRecorder) Block(blockID interface{}) *gomock.Call { +// ActivationHeight indicates an expected call of ActivationHeight. +func (mr *MockStateInfoMockRecorder) ActivationHeight(featureID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Block", reflect.TypeOf((*MockStateInfo)(nil).Block), blockID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivationHeight", reflect.TypeOf((*MockStateInfo)(nil).ActivationHeight), featureID) } -// BlockByHeight mocks base method -func (m *MockStateInfo) BlockByHeight(height proto.Height) (*proto.Block, error) { +// AddrByAlias mocks base method. +func (m *MockStateInfo) AddrByAlias(alias proto.Alias) (proto.Address, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "BlockByHeight", height) - ret0, _ := ret[0].(*proto.Block) + ret := m.ctrl.Call(m, "AddrByAlias", alias) + ret0, _ := ret[0].(proto.Address) ret1, _ := ret[1].(error) return ret0, ret1 } -// BlockByHeight indicates an expected call of BlockByHeight -func (mr *MockStateInfoMockRecorder) BlockByHeight(height interface{}) *gomock.Call { +// AddrByAlias indicates an expected call of AddrByAlias. +func (mr *MockStateInfoMockRecorder) AddrByAlias(alias interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlockByHeight", reflect.TypeOf((*MockStateInfo)(nil).BlockByHeight), height) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddrByAlias", reflect.TypeOf((*MockStateInfo)(nil).AddrByAlias), alias) } -// Header mocks base method -func (m *MockStateInfo) Header(blockID proto.BlockID) (*proto.BlockHeader, error) { +// AllFeatures mocks base method. +func (m *MockStateInfo) AllFeatures() ([]int16, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Header", blockID) - ret0, _ := ret[0].(*proto.BlockHeader) + ret := m.ctrl.Call(m, "AllFeatures") + ret0, _ := ret[0].([]int16) ret1, _ := ret[1].(error) return ret0, ret1 } -// Header indicates an expected call of Header -func (mr *MockStateInfoMockRecorder) Header(blockID interface{}) *gomock.Call { +// AllFeatures indicates an expected call of AllFeatures. +func (mr *MockStateInfoMockRecorder) AllFeatures() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Header", reflect.TypeOf((*MockStateInfo)(nil).Header), blockID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AllFeatures", reflect.TypeOf((*MockStateInfo)(nil).AllFeatures)) } -// HeaderByHeight mocks base method -func (m *MockStateInfo) HeaderByHeight(height proto.Height) (*proto.BlockHeader, error) { +// ApprovalHeight mocks base method. +func (m *MockStateInfo) ApprovalHeight(featureID int16) (proto.Height, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "HeaderByHeight", height) - ret0, _ := ret[0].(*proto.BlockHeader) + ret := m.ctrl.Call(m, "ApprovalHeight", featureID) + ret0, _ := ret[0].(proto.Height) ret1, _ := ret[1].(error) return ret0, ret1 } -// HeaderByHeight indicates an expected call of HeaderByHeight -func (mr *MockStateInfoMockRecorder) HeaderByHeight(height interface{}) *gomock.Call { +// ApprovalHeight indicates an expected call of ApprovalHeight. +func (mr *MockStateInfoMockRecorder) ApprovalHeight(featureID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HeaderByHeight", reflect.TypeOf((*MockStateInfo)(nil).HeaderByHeight), height) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ApprovalHeight", reflect.TypeOf((*MockStateInfo)(nil).ApprovalHeight), featureID) } -// Height mocks base method -func (m *MockStateInfo) Height() (proto.Height, error) { +// AssetInfo mocks base method. +func (m *MockStateInfo) AssetInfo(assetID crypto.Digest) (*proto.AssetInfo, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Height") - ret0, _ := ret[0].(proto.Height) + ret := m.ctrl.Call(m, "AssetInfo", assetID) + ret0, _ := ret[0].(*proto.AssetInfo) ret1, _ := ret[1].(error) return ret0, ret1 } -// Height indicates an expected call of Height -func (mr *MockStateInfoMockRecorder) Height() *gomock.Call { +// AssetInfo indicates an expected call of AssetInfo. +func (mr *MockStateInfoMockRecorder) AssetInfo(assetID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Height", reflect.TypeOf((*MockStateInfo)(nil).Height)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AssetInfo", reflect.TypeOf((*MockStateInfo)(nil).AssetInfo), assetID) +} + +// AssetIsSponsored mocks base method. +func (m *MockStateInfo) AssetIsSponsored(assetID crypto.Digest) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AssetIsSponsored", assetID) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// AssetIsSponsored indicates an expected call of AssetIsSponsored. +func (mr *MockStateInfoMockRecorder) AssetIsSponsored(assetID interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AssetIsSponsored", reflect.TypeOf((*MockStateInfo)(nil).AssetIsSponsored), assetID) +} + +// Block mocks base method. +func (m *MockStateInfo) Block(blockID proto.BlockID) (*proto.Block, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Block", blockID) + ret0, _ := ret[0].(*proto.Block) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Block indicates an expected call of Block. +func (mr *MockStateInfoMockRecorder) Block(blockID interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Block", reflect.TypeOf((*MockStateInfo)(nil).Block), blockID) +} + +// BlockByHeight mocks base method. +func (m *MockStateInfo) BlockByHeight(height proto.Height) (*proto.Block, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BlockByHeight", height) + ret0, _ := ret[0].(*proto.Block) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// BlockByHeight indicates an expected call of BlockByHeight. +func (mr *MockStateInfoMockRecorder) BlockByHeight(height interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlockByHeight", reflect.TypeOf((*MockStateInfo)(nil).BlockByHeight), height) } -// BlockIDToHeight mocks base method +// BlockIDToHeight mocks base method. func (m *MockStateInfo) BlockIDToHeight(blockID proto.BlockID) (proto.Height, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "BlockIDToHeight", blockID) @@ -214,43 +262,43 @@ func (m *MockStateInfo) BlockIDToHeight(blockID proto.BlockID) (proto.Height, er return ret0, ret1 } -// BlockIDToHeight indicates an expected call of BlockIDToHeight +// BlockIDToHeight indicates an expected call of BlockIDToHeight. func (mr *MockStateInfoMockRecorder) BlockIDToHeight(blockID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlockIDToHeight", reflect.TypeOf((*MockStateInfo)(nil).BlockIDToHeight), blockID) } -// HeightToBlockID mocks base method -func (m *MockStateInfo) HeightToBlockID(height proto.Height) (proto.BlockID, error) { +// BlockchainSettings mocks base method. +func (m *MockStateInfo) BlockchainSettings() (*settings.BlockchainSettings, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "HeightToBlockID", height) - ret0, _ := ret[0].(proto.BlockID) + ret := m.ctrl.Call(m, "BlockchainSettings") + ret0, _ := ret[0].(*settings.BlockchainSettings) ret1, _ := ret[1].(error) return ret0, ret1 } -// HeightToBlockID indicates an expected call of HeightToBlockID -func (mr *MockStateInfoMockRecorder) HeightToBlockID(height interface{}) *gomock.Call { +// BlockchainSettings indicates an expected call of BlockchainSettings. +func (mr *MockStateInfoMockRecorder) BlockchainSettings() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HeightToBlockID", reflect.TypeOf((*MockStateInfo)(nil).HeightToBlockID), height) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlockchainSettings", reflect.TypeOf((*MockStateInfo)(nil).BlockchainSettings)) } -// FullWavesBalance mocks base method -func (m *MockStateInfo) FullWavesBalance(account proto.Recipient) (*proto.FullWavesBalance, error) { +// CurrentScore mocks base method. +func (m *MockStateInfo) CurrentScore() (*big.Int, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FullWavesBalance", account) - ret0, _ := ret[0].(*proto.FullWavesBalance) + ret := m.ctrl.Call(m, "CurrentScore") + ret0, _ := ret[0].(*big.Int) ret1, _ := ret[1].(error) return ret0, ret1 } -// FullWavesBalance indicates an expected call of FullWavesBalance -func (mr *MockStateInfoMockRecorder) FullWavesBalance(account interface{}) *gomock.Call { +// CurrentScore indicates an expected call of CurrentScore. +func (mr *MockStateInfoMockRecorder) CurrentScore() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FullWavesBalance", reflect.TypeOf((*MockStateInfo)(nil).FullWavesBalance), account) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CurrentScore", reflect.TypeOf((*MockStateInfo)(nil).CurrentScore)) } -// EffectiveBalance mocks base method +// EffectiveBalance mocks base method. func (m *MockStateInfo) EffectiveBalance(account proto.Recipient, startHeight, endHeight proto.Height) (uint64, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "EffectiveBalance", account, startHeight, endHeight) @@ -259,133 +307,148 @@ func (m *MockStateInfo) EffectiveBalance(account proto.Recipient, startHeight, e return ret0, ret1 } -// EffectiveBalance indicates an expected call of EffectiveBalance +// EffectiveBalance indicates an expected call of EffectiveBalance. func (mr *MockStateInfoMockRecorder) EffectiveBalance(account, startHeight, endHeight interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EffectiveBalance", reflect.TypeOf((*MockStateInfo)(nil).EffectiveBalance), account, startHeight, endHeight) } -// AccountBalance mocks base method -func (m *MockStateInfo) AccountBalance(account proto.Recipient, asset []byte) (uint64, error) { +// EstimatorVersion mocks base method. +func (m *MockStateInfo) EstimatorVersion() (int, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AccountBalance", account, asset) - ret0, _ := ret[0].(uint64) + ret := m.ctrl.Call(m, "EstimatorVersion") + ret0, _ := ret[0].(int) ret1, _ := ret[1].(error) return ret0, ret1 } -// AccountBalance indicates an expected call of AccountBalance -func (mr *MockStateInfoMockRecorder) AccountBalance(account, asset interface{}) *gomock.Call { +// EstimatorVersion indicates an expected call of EstimatorVersion. +func (mr *MockStateInfoMockRecorder) EstimatorVersion() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AccountBalance", reflect.TypeOf((*MockStateInfo)(nil).AccountBalance), account, asset) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EstimatorVersion", reflect.TypeOf((*MockStateInfo)(nil).EstimatorVersion)) } -// WavesAddressesNumber mocks base method -func (m *MockStateInfo) WavesAddressesNumber() (uint64, error) { +// FullAssetInfo mocks base method. +func (m *MockStateInfo) FullAssetInfo(assetID crypto.Digest) (*proto.FullAssetInfo, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "WavesAddressesNumber") - ret0, _ := ret[0].(uint64) + ret := m.ctrl.Call(m, "FullAssetInfo", assetID) + ret0, _ := ret[0].(*proto.FullAssetInfo) ret1, _ := ret[1].(error) return ret0, ret1 } -// WavesAddressesNumber indicates an expected call of WavesAddressesNumber -func (mr *MockStateInfoMockRecorder) WavesAddressesNumber() *gomock.Call { +// FullAssetInfo indicates an expected call of FullAssetInfo. +func (mr *MockStateInfoMockRecorder) FullAssetInfo(assetID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WavesAddressesNumber", reflect.TypeOf((*MockStateInfo)(nil).WavesAddressesNumber)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FullAssetInfo", reflect.TypeOf((*MockStateInfo)(nil).FullAssetInfo), assetID) } -// ScoreAtHeight mocks base method -func (m *MockStateInfo) ScoreAtHeight(height proto.Height) (*big.Int, error) { +// FullWavesBalance mocks base method. +func (m *MockStateInfo) FullWavesBalance(account proto.Recipient) (*proto.FullWavesBalance, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ScoreAtHeight", height) - ret0, _ := ret[0].(*big.Int) + ret := m.ctrl.Call(m, "FullWavesBalance", account) + ret0, _ := ret[0].(*proto.FullWavesBalance) ret1, _ := ret[1].(error) return ret0, ret1 } -// ScoreAtHeight indicates an expected call of ScoreAtHeight -func (mr *MockStateInfoMockRecorder) ScoreAtHeight(height interface{}) *gomock.Call { +// FullWavesBalance indicates an expected call of FullWavesBalance. +func (mr *MockStateInfoMockRecorder) FullWavesBalance(account interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ScoreAtHeight", reflect.TypeOf((*MockStateInfo)(nil).ScoreAtHeight), height) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FullWavesBalance", reflect.TypeOf((*MockStateInfo)(nil).FullWavesBalance), account) } -// CurrentScore mocks base method -func (m *MockStateInfo) CurrentScore() (*big.Int, error) { +// Header mocks base method. +func (m *MockStateInfo) Header(blockID proto.BlockID) (*proto.BlockHeader, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CurrentScore") - ret0, _ := ret[0].(*big.Int) + ret := m.ctrl.Call(m, "Header", blockID) + ret0, _ := ret[0].(*proto.BlockHeader) ret1, _ := ret[1].(error) return ret0, ret1 } -// CurrentScore indicates an expected call of CurrentScore -func (mr *MockStateInfoMockRecorder) CurrentScore() *gomock.Call { +// Header indicates an expected call of Header. +func (mr *MockStateInfoMockRecorder) Header(blockID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CurrentScore", reflect.TypeOf((*MockStateInfo)(nil).CurrentScore)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Header", reflect.TypeOf((*MockStateInfo)(nil).Header), blockID) } -// BlockchainSettings mocks base method -func (m *MockStateInfo) BlockchainSettings() (*settings.BlockchainSettings, error) { +// HeaderByHeight mocks base method. +func (m *MockStateInfo) HeaderByHeight(height proto.Height) (*proto.BlockHeader, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "BlockchainSettings") - ret0, _ := ret[0].(*settings.BlockchainSettings) + ret := m.ctrl.Call(m, "HeaderByHeight", height) + ret0, _ := ret[0].(*proto.BlockHeader) ret1, _ := ret[1].(error) return ret0, ret1 } -// BlockchainSettings indicates an expected call of BlockchainSettings -func (mr *MockStateInfoMockRecorder) BlockchainSettings() *gomock.Call { +// HeaderByHeight indicates an expected call of HeaderByHeight. +func (mr *MockStateInfoMockRecorder) HeaderByHeight(height interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlockchainSettings", reflect.TypeOf((*MockStateInfo)(nil).BlockchainSettings)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HeaderByHeight", reflect.TypeOf((*MockStateInfo)(nil).HeaderByHeight), height) } -// Peers mocks base method -func (m *MockStateInfo) Peers() ([]proto.TCPAddr, error) { +// Height mocks base method. +func (m *MockStateInfo) Height() (proto.Height, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Peers") - ret0, _ := ret[0].([]proto.TCPAddr) + ret := m.ctrl.Call(m, "Height") + ret0, _ := ret[0].(proto.Height) ret1, _ := ret[1].(error) return ret0, ret1 } -// Peers indicates an expected call of Peers -func (mr *MockStateInfoMockRecorder) Peers() *gomock.Call { +// Height indicates an expected call of Height. +func (mr *MockStateInfoMockRecorder) Height() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Peers", reflect.TypeOf((*MockStateInfo)(nil).Peers)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Height", reflect.TypeOf((*MockStateInfo)(nil).Height)) } -// VotesNum mocks base method -func (m *MockStateInfo) VotesNum(featureID int16) (uint64, error) { +// HeightToBlockID mocks base method. +func (m *MockStateInfo) HeightToBlockID(height proto.Height) (proto.BlockID, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "VotesNum", featureID) - ret0, _ := ret[0].(uint64) + ret := m.ctrl.Call(m, "HeightToBlockID", height) + ret0, _ := ret[0].(proto.BlockID) ret1, _ := ret[1].(error) return ret0, ret1 } -// VotesNum indicates an expected call of VotesNum -func (mr *MockStateInfoMockRecorder) VotesNum(featureID interface{}) *gomock.Call { +// HeightToBlockID indicates an expected call of HeightToBlockID. +func (mr *MockStateInfoMockRecorder) HeightToBlockID(height interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VotesNum", reflect.TypeOf((*MockStateInfo)(nil).VotesNum), featureID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HeightToBlockID", reflect.TypeOf((*MockStateInfo)(nil).HeightToBlockID), height) } -// VotesNumAtHeight mocks base method -func (m *MockStateInfo) VotesNumAtHeight(featureID int16, height proto.Height) (uint64, error) { +// HitSourceAtHeight mocks base method. +func (m *MockStateInfo) HitSourceAtHeight(height proto.Height) ([]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "VotesNumAtHeight", featureID, height) - ret0, _ := ret[0].(uint64) + ret := m.ctrl.Call(m, "HitSourceAtHeight", height) + ret0, _ := ret[0].([]byte) ret1, _ := ret[1].(error) return ret0, ret1 } -// VotesNumAtHeight indicates an expected call of VotesNumAtHeight -func (mr *MockStateInfoMockRecorder) VotesNumAtHeight(featureID, height interface{}) *gomock.Call { +// HitSourceAtHeight indicates an expected call of HitSourceAtHeight. +func (mr *MockStateInfoMockRecorder) HitSourceAtHeight(height interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VotesNumAtHeight", reflect.TypeOf((*MockStateInfo)(nil).VotesNumAtHeight), featureID, height) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HitSourceAtHeight", reflect.TypeOf((*MockStateInfo)(nil).HitSourceAtHeight), height) +} + +// InvokeResultByID mocks base method. +func (m *MockStateInfo) InvokeResultByID(invokeID crypto.Digest) (*proto.ScriptResult, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "InvokeResultByID", invokeID) + ret0, _ := ret[0].(*proto.ScriptResult) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// InvokeResultByID indicates an expected call of InvokeResultByID. +func (mr *MockStateInfoMockRecorder) InvokeResultByID(invokeID interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InvokeResultByID", reflect.TypeOf((*MockStateInfo)(nil).InvokeResultByID), invokeID) } -// IsActivated mocks base method +// IsActivated mocks base method. func (m *MockStateInfo) IsActivated(featureID int16) (bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IsActivated", featureID) @@ -394,13 +457,13 @@ func (m *MockStateInfo) IsActivated(featureID int16) (bool, error) { return ret0, ret1 } -// IsActivated indicates an expected call of IsActivated +// IsActivated indicates an expected call of IsActivated. func (mr *MockStateInfoMockRecorder) IsActivated(featureID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsActivated", reflect.TypeOf((*MockStateInfo)(nil).IsActivated), featureID) } -// IsActiveAtHeight mocks base method +// IsActiveAtHeight mocks base method. func (m *MockStateInfo) IsActiveAtHeight(featureID int16, height proto.Height) (bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IsActiveAtHeight", featureID, height) @@ -409,28 +472,28 @@ func (m *MockStateInfo) IsActiveAtHeight(featureID int16, height proto.Height) ( return ret0, ret1 } -// IsActiveAtHeight indicates an expected call of IsActiveAtHeight +// IsActiveAtHeight indicates an expected call of IsActiveAtHeight. func (mr *MockStateInfoMockRecorder) IsActiveAtHeight(featureID, height interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsActiveAtHeight", reflect.TypeOf((*MockStateInfo)(nil).IsActiveAtHeight), featureID, height) } -// ActivationHeight mocks base method -func (m *MockStateInfo) ActivationHeight(featureID int16) (proto.Height, error) { +// IsActiveLeasing mocks base method. +func (m *MockStateInfo) IsActiveLeasing(leaseID crypto.Digest) (bool, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ActivationHeight", featureID) - ret0, _ := ret[0].(proto.Height) + ret := m.ctrl.Call(m, "IsActiveLeasing", leaseID) + ret0, _ := ret[0].(bool) ret1, _ := ret[1].(error) return ret0, ret1 } -// ActivationHeight indicates an expected call of ActivationHeight -func (mr *MockStateInfoMockRecorder) ActivationHeight(featureID interface{}) *gomock.Call { +// IsActiveLeasing indicates an expected call of IsActiveLeasing. +func (mr *MockStateInfoMockRecorder) IsActiveLeasing(leaseID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivationHeight", reflect.TypeOf((*MockStateInfo)(nil).ActivationHeight), featureID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsActiveLeasing", reflect.TypeOf((*MockStateInfo)(nil).IsActiveLeasing), leaseID) } -// IsApproved mocks base method +// IsApproved mocks base method. func (m *MockStateInfo) IsApproved(featureID int16) (bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IsApproved", featureID) @@ -439,13 +502,13 @@ func (m *MockStateInfo) IsApproved(featureID int16) (bool, error) { return ret0, ret1 } -// IsApproved indicates an expected call of IsApproved +// IsApproved indicates an expected call of IsApproved. func (mr *MockStateInfoMockRecorder) IsApproved(featureID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsApproved", reflect.TypeOf((*MockStateInfo)(nil).IsApproved), featureID) } -// IsApprovedAtHeight mocks base method +// IsApprovedAtHeight mocks base method. func (m *MockStateInfo) IsApprovedAtHeight(featureID int16, height proto.Height) (bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IsApprovedAtHeight", featureID, height) @@ -454,118 +517,118 @@ func (m *MockStateInfo) IsApprovedAtHeight(featureID int16, height proto.Height) return ret0, ret1 } -// IsApprovedAtHeight indicates an expected call of IsApprovedAtHeight +// IsApprovedAtHeight indicates an expected call of IsApprovedAtHeight. func (mr *MockStateInfoMockRecorder) IsApprovedAtHeight(featureID, height interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsApprovedAtHeight", reflect.TypeOf((*MockStateInfo)(nil).IsApprovedAtHeight), featureID, height) } -// ApprovalHeight mocks base method -func (m *MockStateInfo) ApprovalHeight(featureID int16) (proto.Height, error) { +// MapR mocks base method. +func (m *MockStateInfo) MapR(arg0 func(state.StateInfo) (interface{}, error)) (interface{}, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ApprovalHeight", featureID) - ret0, _ := ret[0].(proto.Height) + ret := m.ctrl.Call(m, "MapR", arg0) + ret0, _ := ret[0].(interface{}) ret1, _ := ret[1].(error) return ret0, ret1 } -// ApprovalHeight indicates an expected call of ApprovalHeight -func (mr *MockStateInfoMockRecorder) ApprovalHeight(featureID interface{}) *gomock.Call { +// MapR indicates an expected call of MapR. +func (mr *MockStateInfoMockRecorder) MapR(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ApprovalHeight", reflect.TypeOf((*MockStateInfo)(nil).ApprovalHeight), featureID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MapR", reflect.TypeOf((*MockStateInfo)(nil).MapR), arg0) } -// AllFeatures mocks base method -func (m *MockStateInfo) AllFeatures() ([]int16, error) { +// NFTList mocks base method. +func (m *MockStateInfo) NFTList(account proto.Recipient, limit uint64, afterAssetID []byte) ([]*proto.FullAssetInfo, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AllFeatures") - ret0, _ := ret[0].([]int16) + ret := m.ctrl.Call(m, "NFTList", account, limit, afterAssetID) + ret0, _ := ret[0].([]*proto.FullAssetInfo) ret1, _ := ret[1].(error) return ret0, ret1 } -// AllFeatures indicates an expected call of AllFeatures -func (mr *MockStateInfoMockRecorder) AllFeatures() *gomock.Call { +// NFTList indicates an expected call of NFTList. +func (mr *MockStateInfoMockRecorder) NFTList(account, limit, afterAssetID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AllFeatures", reflect.TypeOf((*MockStateInfo)(nil).AllFeatures)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NFTList", reflect.TypeOf((*MockStateInfo)(nil).NFTList), account, limit, afterAssetID) } -// EstimatorVersion mocks base method -func (m *MockStateInfo) EstimatorVersion() (int, error) { +// NewAddrTransactionsIterator mocks base method. +func (m *MockStateInfo) NewAddrTransactionsIterator(addr proto.Address) (state.TransactionIterator, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "EstimatorVersion") - ret0, _ := ret[0].(int) + ret := m.ctrl.Call(m, "NewAddrTransactionsIterator", addr) + ret0, _ := ret[0].(state.TransactionIterator) ret1, _ := ret[1].(error) return ret0, ret1 } -// EstimatorVersion indicates an expected call of EstimatorVersion -func (mr *MockStateInfoMockRecorder) EstimatorVersion() *gomock.Call { +// NewAddrTransactionsIterator indicates an expected call of NewAddrTransactionsIterator. +func (mr *MockStateInfoMockRecorder) NewAddrTransactionsIterator(addr interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EstimatorVersion", reflect.TypeOf((*MockStateInfo)(nil).EstimatorVersion)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAddrTransactionsIterator", reflect.TypeOf((*MockStateInfo)(nil).NewAddrTransactionsIterator), addr) } -// AddrByAlias mocks base method -func (m *MockStateInfo) AddrByAlias(alias proto.Alias) (proto.Address, error) { +// Peers mocks base method. +func (m *MockStateInfo) Peers() ([]proto.TCPAddr, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AddrByAlias", alias) - ret0, _ := ret[0].(proto.Address) + ret := m.ctrl.Call(m, "Peers") + ret0, _ := ret[0].([]proto.TCPAddr) ret1, _ := ret[1].(error) return ret0, ret1 } -// AddrByAlias indicates an expected call of AddrByAlias -func (mr *MockStateInfoMockRecorder) AddrByAlias(alias interface{}) *gomock.Call { +// Peers indicates an expected call of Peers. +func (mr *MockStateInfoMockRecorder) Peers() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddrByAlias", reflect.TypeOf((*MockStateInfo)(nil).AddrByAlias), alias) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Peers", reflect.TypeOf((*MockStateInfo)(nil).Peers)) } -// RetrieveEntries mocks base method -func (m *MockStateInfo) RetrieveEntries(account proto.Recipient) ([]proto.DataEntry, error) { +// ProvidesExtendedApi mocks base method. +func (m *MockStateInfo) ProvidesExtendedApi() (bool, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RetrieveEntries", account) - ret0, _ := ret[0].([]proto.DataEntry) + ret := m.ctrl.Call(m, "ProvidesExtendedApi") + ret0, _ := ret[0].(bool) ret1, _ := ret[1].(error) return ret0, ret1 } -// RetrieveEntries indicates an expected call of RetrieveEntries -func (mr *MockStateInfoMockRecorder) RetrieveEntries(account interface{}) *gomock.Call { +// ProvidesExtendedApi indicates an expected call of ProvidesExtendedApi. +func (mr *MockStateInfoMockRecorder) ProvidesExtendedApi() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RetrieveEntries", reflect.TypeOf((*MockStateInfo)(nil).RetrieveEntries), account) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProvidesExtendedApi", reflect.TypeOf((*MockStateInfo)(nil).ProvidesExtendedApi)) } -// RetrieveEntry mocks base method -func (m *MockStateInfo) RetrieveEntry(account proto.Recipient, key string) (proto.DataEntry, error) { +// ProvidesStateHashes mocks base method. +func (m *MockStateInfo) ProvidesStateHashes() (bool, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RetrieveEntry", account, key) - ret0, _ := ret[0].(proto.DataEntry) + ret := m.ctrl.Call(m, "ProvidesStateHashes") + ret0, _ := ret[0].(bool) ret1, _ := ret[1].(error) return ret0, ret1 } -// RetrieveEntry indicates an expected call of RetrieveEntry -func (mr *MockStateInfoMockRecorder) RetrieveEntry(account, key interface{}) *gomock.Call { +// ProvidesStateHashes indicates an expected call of ProvidesStateHashes. +func (mr *MockStateInfoMockRecorder) ProvidesStateHashes() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RetrieveEntry", reflect.TypeOf((*MockStateInfo)(nil).RetrieveEntry), account, key) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProvidesStateHashes", reflect.TypeOf((*MockStateInfo)(nil).ProvidesStateHashes)) } -// RetrieveIntegerEntry mocks base method -func (m *MockStateInfo) RetrieveIntegerEntry(account proto.Recipient, key string) (*proto.IntegerDataEntry, error) { +// RetrieveBinaryEntry mocks base method. +func (m *MockStateInfo) RetrieveBinaryEntry(account proto.Recipient, key string) (*proto.BinaryDataEntry, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RetrieveIntegerEntry", account, key) - ret0, _ := ret[0].(*proto.IntegerDataEntry) + ret := m.ctrl.Call(m, "RetrieveBinaryEntry", account, key) + ret0, _ := ret[0].(*proto.BinaryDataEntry) ret1, _ := ret[1].(error) return ret0, ret1 } -// RetrieveIntegerEntry indicates an expected call of RetrieveIntegerEntry -func (mr *MockStateInfoMockRecorder) RetrieveIntegerEntry(account, key interface{}) *gomock.Call { +// RetrieveBinaryEntry indicates an expected call of RetrieveBinaryEntry. +func (mr *MockStateInfoMockRecorder) RetrieveBinaryEntry(account, key interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RetrieveIntegerEntry", reflect.TypeOf((*MockStateInfo)(nil).RetrieveIntegerEntry), account, key) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RetrieveBinaryEntry", reflect.TypeOf((*MockStateInfo)(nil).RetrieveBinaryEntry), account, key) } -// RetrieveBooleanEntry mocks base method +// RetrieveBooleanEntry mocks base method. func (m *MockStateInfo) RetrieveBooleanEntry(account proto.Recipient, key string) (*proto.BooleanDataEntry, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "RetrieveBooleanEntry", account, key) @@ -574,337 +637,290 @@ func (m *MockStateInfo) RetrieveBooleanEntry(account proto.Recipient, key string return ret0, ret1 } -// RetrieveBooleanEntry indicates an expected call of RetrieveBooleanEntry +// RetrieveBooleanEntry indicates an expected call of RetrieveBooleanEntry. func (mr *MockStateInfoMockRecorder) RetrieveBooleanEntry(account, key interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RetrieveBooleanEntry", reflect.TypeOf((*MockStateInfo)(nil).RetrieveBooleanEntry), account, key) } -// RetrieveStringEntry mocks base method -func (m *MockStateInfo) RetrieveStringEntry(account proto.Recipient, key string) (*proto.StringDataEntry, error) { +// RetrieveEntries mocks base method. +func (m *MockStateInfo) RetrieveEntries(account proto.Recipient) ([]proto.DataEntry, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RetrieveStringEntry", account, key) - ret0, _ := ret[0].(*proto.StringDataEntry) + ret := m.ctrl.Call(m, "RetrieveEntries", account) + ret0, _ := ret[0].([]proto.DataEntry) ret1, _ := ret[1].(error) return ret0, ret1 } -// RetrieveStringEntry indicates an expected call of RetrieveStringEntry -func (mr *MockStateInfoMockRecorder) RetrieveStringEntry(account, key interface{}) *gomock.Call { +// RetrieveEntries indicates an expected call of RetrieveEntries. +func (mr *MockStateInfoMockRecorder) RetrieveEntries(account interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RetrieveStringEntry", reflect.TypeOf((*MockStateInfo)(nil).RetrieveStringEntry), account, key) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RetrieveEntries", reflect.TypeOf((*MockStateInfo)(nil).RetrieveEntries), account) } -// RetrieveBinaryEntry mocks base method -func (m *MockStateInfo) RetrieveBinaryEntry(account proto.Recipient, key string) (*proto.BinaryDataEntry, error) { +// RetrieveEntry mocks base method. +func (m *MockStateInfo) RetrieveEntry(account proto.Recipient, key string) (proto.DataEntry, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RetrieveBinaryEntry", account, key) - ret0, _ := ret[0].(*proto.BinaryDataEntry) + ret := m.ctrl.Call(m, "RetrieveEntry", account, key) + ret0, _ := ret[0].(proto.DataEntry) ret1, _ := ret[1].(error) return ret0, ret1 } -// RetrieveBinaryEntry indicates an expected call of RetrieveBinaryEntry -func (mr *MockStateInfoMockRecorder) RetrieveBinaryEntry(account, key interface{}) *gomock.Call { +// RetrieveEntry indicates an expected call of RetrieveEntry. +func (mr *MockStateInfoMockRecorder) RetrieveEntry(account, key interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RetrieveBinaryEntry", reflect.TypeOf((*MockStateInfo)(nil).RetrieveBinaryEntry), account, key) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RetrieveEntry", reflect.TypeOf((*MockStateInfo)(nil).RetrieveEntry), account, key) } -// TransactionByID mocks base method -func (m *MockStateInfo) TransactionByID(id []byte) (proto.Transaction, error) { +// RetrieveIntegerEntry mocks base method. +func (m *MockStateInfo) RetrieveIntegerEntry(account proto.Recipient, key string) (*proto.IntegerDataEntry, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "TransactionByID", id) - ret0, _ := ret[0].(proto.Transaction) + ret := m.ctrl.Call(m, "RetrieveIntegerEntry", account, key) + ret0, _ := ret[0].(*proto.IntegerDataEntry) ret1, _ := ret[1].(error) return ret0, ret1 } -// TransactionByID indicates an expected call of TransactionByID -func (mr *MockStateInfoMockRecorder) TransactionByID(id interface{}) *gomock.Call { +// RetrieveIntegerEntry indicates an expected call of RetrieveIntegerEntry. +func (mr *MockStateInfoMockRecorder) RetrieveIntegerEntry(account, key interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TransactionByID", reflect.TypeOf((*MockStateInfo)(nil).TransactionByID), id) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RetrieveIntegerEntry", reflect.TypeOf((*MockStateInfo)(nil).RetrieveIntegerEntry), account, key) } -// TransactionByIDWithStatus mocks base method -func (m *MockStateInfo) TransactionByIDWithStatus(id []byte) (proto.Transaction, bool, error) { +// RetrieveStringEntry mocks base method. +func (m *MockStateInfo) RetrieveStringEntry(account proto.Recipient, key string) (*proto.StringDataEntry, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "TransactionByIDWithStatus", id) - ret0, _ := ret[0].(proto.Transaction) - ret1, _ := ret[1].(bool) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 + ret := m.ctrl.Call(m, "RetrieveStringEntry", account, key) + ret0, _ := ret[0].(*proto.StringDataEntry) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// TransactionByIDWithStatus indicates an expected call of TransactionByIDWithStatus -func (mr *MockStateInfoMockRecorder) TransactionByIDWithStatus(id interface{}) *gomock.Call { +// RetrieveStringEntry indicates an expected call of RetrieveStringEntry. +func (mr *MockStateInfoMockRecorder) RetrieveStringEntry(account, key interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TransactionByIDWithStatus", reflect.TypeOf((*MockStateInfo)(nil).TransactionByIDWithStatus), id) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RetrieveStringEntry", reflect.TypeOf((*MockStateInfo)(nil).RetrieveStringEntry), account, key) } -// TransactionHeightByID mocks base method -func (m *MockStateInfo) TransactionHeightByID(id []byte) (uint64, error) { +// ScoreAtHeight mocks base method. +func (m *MockStateInfo) ScoreAtHeight(height proto.Height) (*big.Int, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "TransactionHeightByID", id) - ret0, _ := ret[0].(uint64) + ret := m.ctrl.Call(m, "ScoreAtHeight", height) + ret0, _ := ret[0].(*big.Int) ret1, _ := ret[1].(error) return ret0, ret1 } -// TransactionHeightByID indicates an expected call of TransactionHeightByID -func (mr *MockStateInfoMockRecorder) TransactionHeightByID(id interface{}) *gomock.Call { +// ScoreAtHeight indicates an expected call of ScoreAtHeight. +func (mr *MockStateInfoMockRecorder) ScoreAtHeight(height interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TransactionHeightByID", reflect.TypeOf((*MockStateInfo)(nil).TransactionHeightByID), id) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ScoreAtHeight", reflect.TypeOf((*MockStateInfo)(nil).ScoreAtHeight), height) } -// NewAddrTransactionsIterator mocks base method -func (m *MockStateInfo) NewAddrTransactionsIterator(addr proto.Address) (state.TransactionIterator, error) { +// ScriptInfoByAccount mocks base method. +func (m *MockStateInfo) ScriptInfoByAccount(account proto.Recipient) (*proto.ScriptInfo, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewAddrTransactionsIterator", addr) - ret0, _ := ret[0].(state.TransactionIterator) + ret := m.ctrl.Call(m, "ScriptInfoByAccount", account) + ret0, _ := ret[0].(*proto.ScriptInfo) ret1, _ := ret[1].(error) return ret0, ret1 } -// NewAddrTransactionsIterator indicates an expected call of NewAddrTransactionsIterator -func (mr *MockStateInfoMockRecorder) NewAddrTransactionsIterator(addr interface{}) *gomock.Call { +// ScriptInfoByAccount indicates an expected call of ScriptInfoByAccount. +func (mr *MockStateInfoMockRecorder) ScriptInfoByAccount(account interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAddrTransactionsIterator", reflect.TypeOf((*MockStateInfo)(nil).NewAddrTransactionsIterator), addr) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ScriptInfoByAccount", reflect.TypeOf((*MockStateInfo)(nil).ScriptInfoByAccount), account) } -// AssetIsSponsored mocks base method -func (m *MockStateInfo) AssetIsSponsored(assetID crypto.Digest) (bool, error) { +// ScriptInfoByAsset mocks base method. +func (m *MockStateInfo) ScriptInfoByAsset(assetID crypto.Digest) (*proto.ScriptInfo, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AssetIsSponsored", assetID) - ret0, _ := ret[0].(bool) + ret := m.ctrl.Call(m, "ScriptInfoByAsset", assetID) + ret0, _ := ret[0].(*proto.ScriptInfo) ret1, _ := ret[1].(error) return ret0, ret1 } -// AssetIsSponsored indicates an expected call of AssetIsSponsored -func (mr *MockStateInfoMockRecorder) AssetIsSponsored(assetID interface{}) *gomock.Call { +// ScriptInfoByAsset indicates an expected call of ScriptInfoByAsset. +func (mr *MockStateInfoMockRecorder) ScriptInfoByAsset(assetID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AssetIsSponsored", reflect.TypeOf((*MockStateInfo)(nil).AssetIsSponsored), assetID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ScriptInfoByAsset", reflect.TypeOf((*MockStateInfo)(nil).ScriptInfoByAsset), assetID) } -// AssetInfo mocks base method -func (m *MockStateInfo) AssetInfo(assetID crypto.Digest) (*proto.AssetInfo, error) { +// ShouldPersistAddressTransactions mocks base method. +func (m *MockStateInfo) ShouldPersistAddressTransactions() (bool, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AssetInfo", assetID) - ret0, _ := ret[0].(*proto.AssetInfo) + ret := m.ctrl.Call(m, "ShouldPersistAddressTransactions") + ret0, _ := ret[0].(bool) ret1, _ := ret[1].(error) return ret0, ret1 } -// AssetInfo indicates an expected call of AssetInfo -func (mr *MockStateInfoMockRecorder) AssetInfo(assetID interface{}) *gomock.Call { +// ShouldPersistAddressTransactions indicates an expected call of ShouldPersistAddressTransactions. +func (mr *MockStateInfoMockRecorder) ShouldPersistAddressTransactions() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AssetInfo", reflect.TypeOf((*MockStateInfo)(nil).AssetInfo), assetID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ShouldPersistAddressTransactions", reflect.TypeOf((*MockStateInfo)(nil).ShouldPersistAddressTransactions)) } -// FullAssetInfo mocks base method -func (m *MockStateInfo) FullAssetInfo(assetID crypto.Digest) (*proto.FullAssetInfo, error) { +// SmartState mocks base method. +func (m *MockStateInfo) SmartState() types.SmartState { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FullAssetInfo", assetID) - ret0, _ := ret[0].(*proto.FullAssetInfo) - ret1, _ := ret[1].(error) - return ret0, ret1 + ret := m.ctrl.Call(m, "SmartState") + ret0, _ := ret[0].(types.SmartState) + return ret0 } -// FullAssetInfo indicates an expected call of FullAssetInfo -func (mr *MockStateInfoMockRecorder) FullAssetInfo(assetID interface{}) *gomock.Call { +// SmartState indicates an expected call of SmartState. +func (mr *MockStateInfoMockRecorder) SmartState() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FullAssetInfo", reflect.TypeOf((*MockStateInfo)(nil).FullAssetInfo), assetID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SmartState", reflect.TypeOf((*MockStateInfo)(nil).SmartState)) } -// NFTList mocks base method -func (m *MockStateInfo) NFTList(account proto.Recipient, limit uint64, afterAssetID []byte) ([]*proto.FullAssetInfo, error) { +// StateHashAtHeight mocks base method. +func (m *MockStateInfo) StateHashAtHeight(height uint64) (*proto.StateHash, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NFTList", account, limit, afterAssetID) - ret0, _ := ret[0].([]*proto.FullAssetInfo) + ret := m.ctrl.Call(m, "StateHashAtHeight", height) + ret0, _ := ret[0].(*proto.StateHash) ret1, _ := ret[1].(error) return ret0, ret1 } -// NFTList indicates an expected call of NFTList -func (mr *MockStateInfoMockRecorder) NFTList(account, limit, afterAssetID interface{}) *gomock.Call { +// StateHashAtHeight indicates an expected call of StateHashAtHeight. +func (mr *MockStateInfoMockRecorder) StateHashAtHeight(height interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NFTList", reflect.TypeOf((*MockStateInfo)(nil).NFTList), account, limit, afterAssetID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateHashAtHeight", reflect.TypeOf((*MockStateInfo)(nil).StateHashAtHeight), height) } -// ScriptInfoByAccount mocks base method -func (m *MockStateInfo) ScriptInfoByAccount(account proto.Recipient) (*proto.ScriptInfo, error) { +// TopBlock mocks base method. +func (m *MockStateInfo) TopBlock() *proto.Block { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ScriptInfoByAccount", account) - ret0, _ := ret[0].(*proto.ScriptInfo) - ret1, _ := ret[1].(error) - return ret0, ret1 + ret := m.ctrl.Call(m, "TopBlock") + ret0, _ := ret[0].(*proto.Block) + return ret0 } -// ScriptInfoByAccount indicates an expected call of ScriptInfoByAccount -func (mr *MockStateInfoMockRecorder) ScriptInfoByAccount(account interface{}) *gomock.Call { +// TopBlock indicates an expected call of TopBlock. +func (mr *MockStateInfoMockRecorder) TopBlock() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ScriptInfoByAccount", reflect.TypeOf((*MockStateInfo)(nil).ScriptInfoByAccount), account) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TopBlock", reflect.TypeOf((*MockStateInfo)(nil).TopBlock)) } -// ScriptInfoByAsset mocks base method -func (m *MockStateInfo) ScriptInfoByAsset(assetID crypto.Digest) (*proto.ScriptInfo, error) { +// TransactionByID mocks base method. +func (m *MockStateInfo) TransactionByID(id []byte) (proto.Transaction, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ScriptInfoByAsset", assetID) - ret0, _ := ret[0].(*proto.ScriptInfo) + ret := m.ctrl.Call(m, "TransactionByID", id) + ret0, _ := ret[0].(proto.Transaction) ret1, _ := ret[1].(error) return ret0, ret1 } -// ScriptInfoByAsset indicates an expected call of ScriptInfoByAsset -func (mr *MockStateInfoMockRecorder) ScriptInfoByAsset(assetID interface{}) *gomock.Call { +// TransactionByID indicates an expected call of TransactionByID. +func (mr *MockStateInfoMockRecorder) TransactionByID(id interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ScriptInfoByAsset", reflect.TypeOf((*MockStateInfo)(nil).ScriptInfoByAsset), assetID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TransactionByID", reflect.TypeOf((*MockStateInfo)(nil).TransactionByID), id) } -// IsActiveLeasing mocks base method -func (m *MockStateInfo) IsActiveLeasing(leaseID crypto.Digest) (bool, error) { +// TransactionByIDWithStatus mocks base method. +func (m *MockStateInfo) TransactionByIDWithStatus(id []byte) (proto.Transaction, bool, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IsActiveLeasing", leaseID) - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 + ret := m.ctrl.Call(m, "TransactionByIDWithStatus", id) + ret0, _ := ret[0].(proto.Transaction) + ret1, _ := ret[1].(bool) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 } -// IsActiveLeasing indicates an expected call of IsActiveLeasing -func (mr *MockStateInfoMockRecorder) IsActiveLeasing(leaseID interface{}) *gomock.Call { +// TransactionByIDWithStatus indicates an expected call of TransactionByIDWithStatus. +func (mr *MockStateInfoMockRecorder) TransactionByIDWithStatus(id interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsActiveLeasing", reflect.TypeOf((*MockStateInfo)(nil).IsActiveLeasing), leaseID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TransactionByIDWithStatus", reflect.TypeOf((*MockStateInfo)(nil).TransactionByIDWithStatus), id) } -// InvokeResultByID mocks base method -func (m *MockStateInfo) InvokeResultByID(invokeID crypto.Digest) (*proto.ScriptResult, error) { +// TransactionHeightByID mocks base method. +func (m *MockStateInfo) TransactionHeightByID(id []byte) (uint64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "InvokeResultByID", invokeID) - ret0, _ := ret[0].(*proto.ScriptResult) + ret := m.ctrl.Call(m, "TransactionHeightByID", id) + ret0, _ := ret[0].(uint64) ret1, _ := ret[1].(error) return ret0, ret1 } -// InvokeResultByID indicates an expected call of InvokeResultByID -func (mr *MockStateInfoMockRecorder) InvokeResultByID(invokeID interface{}) *gomock.Call { +// TransactionHeightByID indicates an expected call of TransactionHeightByID. +func (mr *MockStateInfoMockRecorder) TransactionHeightByID(id interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InvokeResultByID", reflect.TypeOf((*MockStateInfo)(nil).InvokeResultByID), invokeID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TransactionHeightByID", reflect.TypeOf((*MockStateInfo)(nil).TransactionHeightByID), id) } -// ProvidesExtendedApi mocks base method -func (m *MockStateInfo) ProvidesExtendedApi() (bool, error) { +// VotesNum mocks base method. +func (m *MockStateInfo) VotesNum(featureID int16) (uint64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ProvidesExtendedApi") - ret0, _ := ret[0].(bool) + ret := m.ctrl.Call(m, "VotesNum", featureID) + ret0, _ := ret[0].(uint64) ret1, _ := ret[1].(error) return ret0, ret1 } -// ProvidesExtendedApi indicates an expected call of ProvidesExtendedApi -func (mr *MockStateInfoMockRecorder) ProvidesExtendedApi() *gomock.Call { +// VotesNum indicates an expected call of VotesNum. +func (mr *MockStateInfoMockRecorder) VotesNum(featureID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProvidesExtendedApi", reflect.TypeOf((*MockStateInfo)(nil).ProvidesExtendedApi)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VotesNum", reflect.TypeOf((*MockStateInfo)(nil).VotesNum), featureID) } -// ProvidesStateHashes mocks base method -func (m *MockStateInfo) ProvidesStateHashes() (bool, error) { +// VotesNumAtHeight mocks base method. +func (m *MockStateInfo) VotesNumAtHeight(featureID int16, height proto.Height) (uint64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ProvidesStateHashes") - ret0, _ := ret[0].(bool) + ret := m.ctrl.Call(m, "VotesNumAtHeight", featureID, height) + ret0, _ := ret[0].(uint64) ret1, _ := ret[1].(error) return ret0, ret1 } -// ProvidesStateHashes indicates an expected call of ProvidesStateHashes -func (mr *MockStateInfoMockRecorder) ProvidesStateHashes() *gomock.Call { +// VotesNumAtHeight indicates an expected call of VotesNumAtHeight. +func (mr *MockStateInfoMockRecorder) VotesNumAtHeight(featureID, height interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProvidesStateHashes", reflect.TypeOf((*MockStateInfo)(nil).ProvidesStateHashes)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VotesNumAtHeight", reflect.TypeOf((*MockStateInfo)(nil).VotesNumAtHeight), featureID, height) } -// StateHashAtHeight mocks base method -func (m *MockStateInfo) StateHashAtHeight(height uint64) (*proto.StateHash, error) { +// WavesAddressesNumber mocks base method. +func (m *MockStateInfo) WavesAddressesNumber() (uint64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "StateHashAtHeight", height) - ret0, _ := ret[0].(*proto.StateHash) + ret := m.ctrl.Call(m, "WavesAddressesNumber") + ret0, _ := ret[0].(uint64) ret1, _ := ret[1].(error) return ret0, ret1 } -// StateHashAtHeight indicates an expected call of StateHashAtHeight -func (mr *MockStateInfoMockRecorder) StateHashAtHeight(height interface{}) *gomock.Call { +// WavesAddressesNumber indicates an expected call of WavesAddressesNumber. +func (mr *MockStateInfoMockRecorder) WavesAddressesNumber() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateHashAtHeight", reflect.TypeOf((*MockStateInfo)(nil).StateHashAtHeight), height) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WavesAddressesNumber", reflect.TypeOf((*MockStateInfo)(nil).WavesAddressesNumber)) } -// MapR mocks base method -func (m *MockStateInfo) MapR(arg0 func(state.StateInfo) (interface{}, error)) (interface{}, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "MapR", arg0) - ret0, _ := ret[0].(interface{}) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// MapR indicates an expected call of MapR -func (mr *MockStateInfoMockRecorder) MapR(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MapR", reflect.TypeOf((*MockStateInfo)(nil).MapR), arg0) -} - -// HitSourceAtHeight mocks base method -func (m *MockStateInfo) HitSourceAtHeight(height proto.Height) ([]byte, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "HitSourceAtHeight", height) - ret0, _ := ret[0].([]byte) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// HitSourceAtHeight indicates an expected call of HitSourceAtHeight -func (mr *MockStateInfoMockRecorder) HitSourceAtHeight(height interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HitSourceAtHeight", reflect.TypeOf((*MockStateInfo)(nil).HitSourceAtHeight), height) -} - -// ShouldPersistAddressTransactions mocks base method -func (m *MockStateInfo) ShouldPersistAddressTransactions() (bool, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ShouldPersistAddressTransactions") - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ShouldPersistAddressTransactions indicates an expected call of ShouldPersistAddressTransactions -func (mr *MockStateInfoMockRecorder) ShouldPersistAddressTransactions() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ShouldPersistAddressTransactions", reflect.TypeOf((*MockStateInfo)(nil).ShouldPersistAddressTransactions)) -} - -// MockStateModifier is a mock of StateModifier interface +// MockStateModifier is a mock of StateModifier interface. type MockStateModifier struct { ctrl *gomock.Controller recorder *MockStateModifierMockRecorder } -// MockStateModifierMockRecorder is the mock recorder for MockStateModifier +// MockStateModifierMockRecorder is the mock recorder for MockStateModifier. type MockStateModifierMockRecorder struct { mock *MockStateModifier } -// NewMockStateModifier creates a new mock instance +// NewMockStateModifier creates a new mock instance. func NewMockStateModifier(ctrl *gomock.Controller) *MockStateModifier { mock := &MockStateModifier{ctrl: ctrl} mock.recorder = &MockStateModifierMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockStateModifier) EXPECT() *MockStateModifierMockRecorder { return m.recorder } -// AddBlock mocks base method +// AddBlock mocks base method. func (m *MockStateModifier) AddBlock(block []byte) (*proto.Block, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AddBlock", block) @@ -913,13 +929,13 @@ func (m *MockStateModifier) AddBlock(block []byte) (*proto.Block, error) { return ret0, ret1 } -// AddBlock indicates an expected call of AddBlock +// AddBlock indicates an expected call of AddBlock. func (mr *MockStateModifierMockRecorder) AddBlock(block interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddBlock", reflect.TypeOf((*MockStateModifier)(nil).AddBlock), block) } -// AddDeserializedBlock mocks base method +// AddDeserializedBlock mocks base method. func (m *MockStateModifier) AddDeserializedBlock(block *proto.Block) (*proto.Block, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AddDeserializedBlock", block) @@ -928,13 +944,13 @@ func (m *MockStateModifier) AddDeserializedBlock(block *proto.Block) (*proto.Blo return ret0, ret1 } -// AddDeserializedBlock indicates an expected call of AddDeserializedBlock +// AddDeserializedBlock indicates an expected call of AddDeserializedBlock. func (mr *MockStateModifierMockRecorder) AddDeserializedBlock(block interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddDeserializedBlock", reflect.TypeOf((*MockStateModifier)(nil).AddDeserializedBlock), block) } -// AddNewBlocks mocks base method +// AddNewBlocks mocks base method. func (m *MockStateModifier) AddNewBlocks(blocks [][]byte) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AddNewBlocks", blocks) @@ -942,13 +958,13 @@ func (m *MockStateModifier) AddNewBlocks(blocks [][]byte) error { return ret0 } -// AddNewBlocks indicates an expected call of AddNewBlocks +// AddNewBlocks indicates an expected call of AddNewBlocks. func (mr *MockStateModifierMockRecorder) AddNewBlocks(blocks interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddNewBlocks", reflect.TypeOf((*MockStateModifier)(nil).AddNewBlocks), blocks) } -// AddNewDeserializedBlocks mocks base method +// AddNewDeserializedBlocks mocks base method. func (m *MockStateModifier) AddNewDeserializedBlocks(blocks []*proto.Block) (*proto.Block, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AddNewDeserializedBlocks", blocks) @@ -957,13 +973,13 @@ func (m *MockStateModifier) AddNewDeserializedBlocks(blocks []*proto.Block) (*pr return ret0, ret1 } -// AddNewDeserializedBlocks indicates an expected call of AddNewDeserializedBlocks +// AddNewDeserializedBlocks indicates an expected call of AddNewDeserializedBlocks. func (mr *MockStateModifierMockRecorder) AddNewDeserializedBlocks(blocks interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddNewDeserializedBlocks", reflect.TypeOf((*MockStateModifier)(nil).AddNewDeserializedBlocks), blocks) } -// AddOldBlocks mocks base method +// AddOldBlocks mocks base method. func (m *MockStateModifier) AddOldBlocks(blocks [][]byte) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AddOldBlocks", blocks) @@ -971,13 +987,13 @@ func (m *MockStateModifier) AddOldBlocks(blocks [][]byte) error { return ret0 } -// AddOldBlocks indicates an expected call of AddOldBlocks +// AddOldBlocks indicates an expected call of AddOldBlocks. func (mr *MockStateModifierMockRecorder) AddOldBlocks(blocks interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddOldBlocks", reflect.TypeOf((*MockStateModifier)(nil).AddOldBlocks), blocks) } -// AddOldDeserializedBlocks mocks base method +// AddOldDeserializedBlocks mocks base method. func (m *MockStateModifier) AddOldDeserializedBlocks(blocks []*proto.Block) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "AddOldDeserializedBlocks", blocks) @@ -985,95 +1001,95 @@ func (m *MockStateModifier) AddOldDeserializedBlocks(blocks []*proto.Block) erro return ret0 } -// AddOldDeserializedBlocks indicates an expected call of AddOldDeserializedBlocks +// AddOldDeserializedBlocks indicates an expected call of AddOldDeserializedBlocks. func (mr *MockStateModifierMockRecorder) AddOldDeserializedBlocks(blocks interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddOldDeserializedBlocks", reflect.TypeOf((*MockStateModifier)(nil).AddOldDeserializedBlocks), blocks) } -// RollbackToHeight mocks base method -func (m *MockStateModifier) RollbackToHeight(height proto.Height) error { +// Close mocks base method. +func (m *MockStateModifier) Close() error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RollbackToHeight", height) + ret := m.ctrl.Call(m, "Close") ret0, _ := ret[0].(error) return ret0 } -// RollbackToHeight indicates an expected call of RollbackToHeight -func (mr *MockStateModifierMockRecorder) RollbackToHeight(height interface{}) *gomock.Call { +// Close indicates an expected call of Close. +func (mr *MockStateModifierMockRecorder) Close() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RollbackToHeight", reflect.TypeOf((*MockStateModifier)(nil).RollbackToHeight), height) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockStateModifier)(nil).Close)) } -// RollbackTo mocks base method -func (m *MockStateModifier) RollbackTo(removalEdge proto.BlockID) error { +// Map mocks base method. +func (m *MockStateModifier) Map(arg0 func(state.NonThreadSafeState) error) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RollbackTo", removalEdge) + ret := m.ctrl.Call(m, "Map", arg0) ret0, _ := ret[0].(error) return ret0 } -// RollbackTo indicates an expected call of RollbackTo -func (mr *MockStateModifierMockRecorder) RollbackTo(removalEdge interface{}) *gomock.Call { +// Map indicates an expected call of Map. +func (mr *MockStateModifierMockRecorder) Map(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RollbackTo", reflect.TypeOf((*MockStateModifier)(nil).RollbackTo), removalEdge) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Map", reflect.TypeOf((*MockStateModifier)(nil).Map), arg0) } -// ValidateNextTx mocks base method -func (m *MockStateModifier) ValidateNextTx(tx proto.Transaction, currentTimestamp, parentTimestamp uint64, blockVersion proto.BlockVersion, acceptFailed bool) error { +// PersistAddressTransactions mocks base method. +func (m *MockStateModifier) PersistAddressTransactions() error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ValidateNextTx", tx, currentTimestamp, parentTimestamp, blockVersion, acceptFailed) + ret := m.ctrl.Call(m, "PersistAddressTransactions") ret0, _ := ret[0].(error) return ret0 } -// ValidateNextTx indicates an expected call of ValidateNextTx -func (mr *MockStateModifierMockRecorder) ValidateNextTx(tx, currentTimestamp, parentTimestamp, blockVersion, acceptFailed interface{}) *gomock.Call { +// PersistAddressTransactions indicates an expected call of PersistAddressTransactions. +func (mr *MockStateModifierMockRecorder) PersistAddressTransactions() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateNextTx", reflect.TypeOf((*MockStateModifier)(nil).ValidateNextTx), tx, currentTimestamp, parentTimestamp, blockVersion, acceptFailed) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PersistAddressTransactions", reflect.TypeOf((*MockStateModifier)(nil).PersistAddressTransactions)) } -// ResetValidationList mocks base method +// ResetValidationList mocks base method. func (m *MockStateModifier) ResetValidationList() { m.ctrl.T.Helper() m.ctrl.Call(m, "ResetValidationList") } -// ResetValidationList indicates an expected call of ResetValidationList +// ResetValidationList indicates an expected call of ResetValidationList. func (mr *MockStateModifierMockRecorder) ResetValidationList() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResetValidationList", reflect.TypeOf((*MockStateModifier)(nil).ResetValidationList)) } -// TxValidation mocks base method -func (m *MockStateModifier) TxValidation(arg0 func(state.TxValidation) error) error { +// RollbackTo mocks base method. +func (m *MockStateModifier) RollbackTo(removalEdge proto.BlockID) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "TxValidation", arg0) + ret := m.ctrl.Call(m, "RollbackTo", removalEdge) ret0, _ := ret[0].(error) return ret0 } -// TxValidation indicates an expected call of TxValidation -func (mr *MockStateModifierMockRecorder) TxValidation(arg0 interface{}) *gomock.Call { +// RollbackTo indicates an expected call of RollbackTo. +func (mr *MockStateModifierMockRecorder) RollbackTo(removalEdge interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TxValidation", reflect.TypeOf((*MockStateModifier)(nil).TxValidation), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RollbackTo", reflect.TypeOf((*MockStateModifier)(nil).RollbackTo), removalEdge) } -// Map mocks base method -func (m *MockStateModifier) Map(arg0 func(state.NonThreadSafeState) error) error { +// RollbackToHeight mocks base method. +func (m *MockStateModifier) RollbackToHeight(height proto.Height) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Map", arg0) + ret := m.ctrl.Call(m, "RollbackToHeight", height) ret0, _ := ret[0].(error) return ret0 } -// Map indicates an expected call of Map -func (mr *MockStateModifierMockRecorder) Map(arg0 interface{}) *gomock.Call { +// RollbackToHeight indicates an expected call of RollbackToHeight. +func (mr *MockStateModifierMockRecorder) RollbackToHeight(height interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Map", reflect.TypeOf((*MockStateModifier)(nil).Map), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RollbackToHeight", reflect.TypeOf((*MockStateModifier)(nil).RollbackToHeight), height) } -// SavePeers mocks base method +// SavePeers mocks base method. func (m *MockStateModifier) SavePeers(arg0 []proto.TCPAddr) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SavePeers", arg0) @@ -1081,13 +1097,13 @@ func (m *MockStateModifier) SavePeers(arg0 []proto.TCPAddr) error { return ret0 } -// SavePeers indicates an expected call of SavePeers +// SavePeers indicates an expected call of SavePeers. func (mr *MockStateModifierMockRecorder) SavePeers(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SavePeers", reflect.TypeOf((*MockStateModifier)(nil).SavePeers), arg0) } -// StartProvidingExtendedApi mocks base method +// StartProvidingExtendedApi mocks base method. func (m *MockStateModifier) StartProvidingExtendedApi() error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "StartProvidingExtendedApi") @@ -1095,64 +1111,64 @@ func (m *MockStateModifier) StartProvidingExtendedApi() error { return ret0 } -// StartProvidingExtendedApi indicates an expected call of StartProvidingExtendedApi +// StartProvidingExtendedApi indicates an expected call of StartProvidingExtendedApi. func (mr *MockStateModifierMockRecorder) StartProvidingExtendedApi() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartProvidingExtendedApi", reflect.TypeOf((*MockStateModifier)(nil).StartProvidingExtendedApi)) } -// PersistAddressTransactions mocks base method -func (m *MockStateModifier) PersistAddressTransactions() error { +// TxValidation mocks base method. +func (m *MockStateModifier) TxValidation(arg0 func(state.TxValidation) error) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PersistAddressTransactions") + ret := m.ctrl.Call(m, "TxValidation", arg0) ret0, _ := ret[0].(error) return ret0 } -// PersistAddressTransactions indicates an expected call of PersistAddressTransactions -func (mr *MockStateModifierMockRecorder) PersistAddressTransactions() *gomock.Call { +// TxValidation indicates an expected call of TxValidation. +func (mr *MockStateModifierMockRecorder) TxValidation(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PersistAddressTransactions", reflect.TypeOf((*MockStateModifier)(nil).PersistAddressTransactions)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TxValidation", reflect.TypeOf((*MockStateModifier)(nil).TxValidation), arg0) } -// Close mocks base method -func (m *MockStateModifier) Close() error { +// ValidateNextTx mocks base method. +func (m *MockStateModifier) ValidateNextTx(tx proto.Transaction, currentTimestamp, parentTimestamp uint64, blockVersion proto.BlockVersion, acceptFailed bool) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Close") + ret := m.ctrl.Call(m, "ValidateNextTx", tx, currentTimestamp, parentTimestamp, blockVersion, acceptFailed) ret0, _ := ret[0].(error) return ret0 } -// Close indicates an expected call of Close -func (mr *MockStateModifierMockRecorder) Close() *gomock.Call { +// ValidateNextTx indicates an expected call of ValidateNextTx. +func (mr *MockStateModifierMockRecorder) ValidateNextTx(tx, currentTimestamp, parentTimestamp, blockVersion, acceptFailed interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockStateModifier)(nil).Close)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateNextTx", reflect.TypeOf((*MockStateModifier)(nil).ValidateNextTx), tx, currentTimestamp, parentTimestamp, blockVersion, acceptFailed) } -// MockTxValidation is a mock of TxValidation interface +// MockTxValidation is a mock of TxValidation interface. type MockTxValidation struct { ctrl *gomock.Controller recorder *MockTxValidationMockRecorder } -// MockTxValidationMockRecorder is the mock recorder for MockTxValidation +// MockTxValidationMockRecorder is the mock recorder for MockTxValidation. type MockTxValidationMockRecorder struct { mock *MockTxValidation } -// NewMockTxValidation creates a new mock instance +// NewMockTxValidation creates a new mock instance. func NewMockTxValidation(ctrl *gomock.Controller) *MockTxValidation { mock := &MockTxValidation{ctrl: ctrl} mock.recorder = &MockTxValidationMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockTxValidation) EXPECT() *MockTxValidationMockRecorder { return m.recorder } -// ValidateNextTx mocks base method +// ValidateNextTx mocks base method. func (m *MockTxValidation) ValidateNextTx(tx proto.Transaction, currentTimestamp, parentTimestamp uint64, blockVersion proto.BlockVersion, acceptFailed bool) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ValidateNextTx", tx, currentTimestamp, parentTimestamp, blockVersion, acceptFailed) @@ -1160,576 +1176,586 @@ func (m *MockTxValidation) ValidateNextTx(tx proto.Transaction, currentTimestamp return ret0 } -// ValidateNextTx indicates an expected call of ValidateNextTx +// ValidateNextTx indicates an expected call of ValidateNextTx. func (mr *MockTxValidationMockRecorder) ValidateNextTx(tx, currentTimestamp, parentTimestamp, blockVersion, acceptFailed interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateNextTx", reflect.TypeOf((*MockTxValidation)(nil).ValidateNextTx), tx, currentTimestamp, parentTimestamp, blockVersion, acceptFailed) } -// MockState is a mock of State interface +// MockState is a mock of State interface. type MockState struct { ctrl *gomock.Controller recorder *MockStateMockRecorder } -// MockStateMockRecorder is the mock recorder for MockState +// MockStateMockRecorder is the mock recorder for MockState. type MockStateMockRecorder struct { mock *MockState } -// NewMockState creates a new mock instance +// NewMockState creates a new mock instance. func NewMockState(ctrl *gomock.Controller) *MockState { mock := &MockState{ctrl: ctrl} mock.recorder = &MockStateMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockState) EXPECT() *MockStateMockRecorder { return m.recorder } -// TopBlock mocks base method -func (m *MockState) TopBlock() *proto.Block { +// AccountBalance mocks base method. +func (m *MockState) AccountBalance(account proto.Recipient, asset []byte) (uint64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "TopBlock") - ret0, _ := ret[0].(*proto.Block) - return ret0 + ret := m.ctrl.Call(m, "AccountBalance", account, asset) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// TopBlock indicates an expected call of TopBlock -func (mr *MockStateMockRecorder) TopBlock() *gomock.Call { +// AccountBalance indicates an expected call of AccountBalance. +func (mr *MockStateMockRecorder) AccountBalance(account, asset interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TopBlock", reflect.TypeOf((*MockState)(nil).TopBlock)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AccountBalance", reflect.TypeOf((*MockState)(nil).AccountBalance), account, asset) } -// Block mocks base method -func (m *MockState) Block(blockID proto.BlockID) (*proto.Block, error) { +// ActivationHeight mocks base method. +func (m *MockState) ActivationHeight(featureID int16) (proto.Height, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Block", blockID) - ret0, _ := ret[0].(*proto.Block) + ret := m.ctrl.Call(m, "ActivationHeight", featureID) + ret0, _ := ret[0].(proto.Height) ret1, _ := ret[1].(error) return ret0, ret1 } -// Block indicates an expected call of Block -func (mr *MockStateMockRecorder) Block(blockID interface{}) *gomock.Call { +// ActivationHeight indicates an expected call of ActivationHeight. +func (mr *MockStateMockRecorder) ActivationHeight(featureID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Block", reflect.TypeOf((*MockState)(nil).Block), blockID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivationHeight", reflect.TypeOf((*MockState)(nil).ActivationHeight), featureID) } -// BlockByHeight mocks base method -func (m *MockState) BlockByHeight(height proto.Height) (*proto.Block, error) { +// AddBlock mocks base method. +func (m *MockState) AddBlock(block []byte) (*proto.Block, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "BlockByHeight", height) + ret := m.ctrl.Call(m, "AddBlock", block) ret0, _ := ret[0].(*proto.Block) ret1, _ := ret[1].(error) return ret0, ret1 } -// BlockByHeight indicates an expected call of BlockByHeight -func (mr *MockStateMockRecorder) BlockByHeight(height interface{}) *gomock.Call { +// AddBlock indicates an expected call of AddBlock. +func (mr *MockStateMockRecorder) AddBlock(block interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlockByHeight", reflect.TypeOf((*MockState)(nil).BlockByHeight), height) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddBlock", reflect.TypeOf((*MockState)(nil).AddBlock), block) } -// Header mocks base method -func (m *MockState) Header(blockID proto.BlockID) (*proto.BlockHeader, error) { +// AddDeserializedBlock mocks base method. +func (m *MockState) AddDeserializedBlock(block *proto.Block) (*proto.Block, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Header", blockID) - ret0, _ := ret[0].(*proto.BlockHeader) + ret := m.ctrl.Call(m, "AddDeserializedBlock", block) + ret0, _ := ret[0].(*proto.Block) ret1, _ := ret[1].(error) return ret0, ret1 } -// Header indicates an expected call of Header -func (mr *MockStateMockRecorder) Header(blockID interface{}) *gomock.Call { +// AddDeserializedBlock indicates an expected call of AddDeserializedBlock. +func (mr *MockStateMockRecorder) AddDeserializedBlock(block interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Header", reflect.TypeOf((*MockState)(nil).Header), blockID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddDeserializedBlock", reflect.TypeOf((*MockState)(nil).AddDeserializedBlock), block) } -// HeaderByHeight mocks base method -func (m *MockState) HeaderByHeight(height proto.Height) (*proto.BlockHeader, error) { +// AddNewBlocks mocks base method. +func (m *MockState) AddNewBlocks(blocks [][]byte) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "HeaderByHeight", height) - ret0, _ := ret[0].(*proto.BlockHeader) - ret1, _ := ret[1].(error) - return ret0, ret1 + ret := m.ctrl.Call(m, "AddNewBlocks", blocks) + ret0, _ := ret[0].(error) + return ret0 } -// HeaderByHeight indicates an expected call of HeaderByHeight -func (mr *MockStateMockRecorder) HeaderByHeight(height interface{}) *gomock.Call { +// AddNewBlocks indicates an expected call of AddNewBlocks. +func (mr *MockStateMockRecorder) AddNewBlocks(blocks interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HeaderByHeight", reflect.TypeOf((*MockState)(nil).HeaderByHeight), height) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddNewBlocks", reflect.TypeOf((*MockState)(nil).AddNewBlocks), blocks) } -// Height mocks base method -func (m *MockState) Height() (proto.Height, error) { +// AddNewDeserializedBlocks mocks base method. +func (m *MockState) AddNewDeserializedBlocks(blocks []*proto.Block) (*proto.Block, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Height") - ret0, _ := ret[0].(proto.Height) + ret := m.ctrl.Call(m, "AddNewDeserializedBlocks", blocks) + ret0, _ := ret[0].(*proto.Block) ret1, _ := ret[1].(error) return ret0, ret1 } -// Height indicates an expected call of Height -func (mr *MockStateMockRecorder) Height() *gomock.Call { +// AddNewDeserializedBlocks indicates an expected call of AddNewDeserializedBlocks. +func (mr *MockStateMockRecorder) AddNewDeserializedBlocks(blocks interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Height", reflect.TypeOf((*MockState)(nil).Height)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddNewDeserializedBlocks", reflect.TypeOf((*MockState)(nil).AddNewDeserializedBlocks), blocks) } -// BlockIDToHeight mocks base method -func (m *MockState) BlockIDToHeight(blockID proto.BlockID) (proto.Height, error) { +// AddOldBlocks mocks base method. +func (m *MockState) AddOldBlocks(blocks [][]byte) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "BlockIDToHeight", blockID) - ret0, _ := ret[0].(proto.Height) - ret1, _ := ret[1].(error) - return ret0, ret1 + ret := m.ctrl.Call(m, "AddOldBlocks", blocks) + ret0, _ := ret[0].(error) + return ret0 } -// BlockIDToHeight indicates an expected call of BlockIDToHeight -func (mr *MockStateMockRecorder) BlockIDToHeight(blockID interface{}) *gomock.Call { +// AddOldBlocks indicates an expected call of AddOldBlocks. +func (mr *MockStateMockRecorder) AddOldBlocks(blocks interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlockIDToHeight", reflect.TypeOf((*MockState)(nil).BlockIDToHeight), blockID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddOldBlocks", reflect.TypeOf((*MockState)(nil).AddOldBlocks), blocks) } -// HeightToBlockID mocks base method -func (m *MockState) HeightToBlockID(height proto.Height) (proto.BlockID, error) { +// AddOldDeserializedBlocks mocks base method. +func (m *MockState) AddOldDeserializedBlocks(blocks []*proto.Block) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "HeightToBlockID", height) - ret0, _ := ret[0].(proto.BlockID) - ret1, _ := ret[1].(error) - return ret0, ret1 + ret := m.ctrl.Call(m, "AddOldDeserializedBlocks", blocks) + ret0, _ := ret[0].(error) + return ret0 } -// HeightToBlockID indicates an expected call of HeightToBlockID -func (mr *MockStateMockRecorder) HeightToBlockID(height interface{}) *gomock.Call { +// AddOldDeserializedBlocks indicates an expected call of AddOldDeserializedBlocks. +func (mr *MockStateMockRecorder) AddOldDeserializedBlocks(blocks interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HeightToBlockID", reflect.TypeOf((*MockState)(nil).HeightToBlockID), height) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddOldDeserializedBlocks", reflect.TypeOf((*MockState)(nil).AddOldDeserializedBlocks), blocks) } -// FullWavesBalance mocks base method -func (m *MockState) FullWavesBalance(account proto.Recipient) (*proto.FullWavesBalance, error) { +// AddrByAlias mocks base method. +func (m *MockState) AddrByAlias(alias proto.Alias) (proto.Address, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FullWavesBalance", account) - ret0, _ := ret[0].(*proto.FullWavesBalance) + ret := m.ctrl.Call(m, "AddrByAlias", alias) + ret0, _ := ret[0].(proto.Address) ret1, _ := ret[1].(error) return ret0, ret1 } -// FullWavesBalance indicates an expected call of FullWavesBalance -func (mr *MockStateMockRecorder) FullWavesBalance(account interface{}) *gomock.Call { +// AddrByAlias indicates an expected call of AddrByAlias. +func (mr *MockStateMockRecorder) AddrByAlias(alias interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FullWavesBalance", reflect.TypeOf((*MockState)(nil).FullWavesBalance), account) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddrByAlias", reflect.TypeOf((*MockState)(nil).AddrByAlias), alias) } -// EffectiveBalance mocks base method -func (m *MockState) EffectiveBalance(account proto.Recipient, startHeight, endHeight proto.Height) (uint64, error) { +// AllFeatures mocks base method. +func (m *MockState) AllFeatures() ([]int16, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "EffectiveBalance", account, startHeight, endHeight) - ret0, _ := ret[0].(uint64) + ret := m.ctrl.Call(m, "AllFeatures") + ret0, _ := ret[0].([]int16) ret1, _ := ret[1].(error) return ret0, ret1 } -// EffectiveBalance indicates an expected call of EffectiveBalance -func (mr *MockStateMockRecorder) EffectiveBalance(account, startHeight, endHeight interface{}) *gomock.Call { +// AllFeatures indicates an expected call of AllFeatures. +func (mr *MockStateMockRecorder) AllFeatures() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EffectiveBalance", reflect.TypeOf((*MockState)(nil).EffectiveBalance), account, startHeight, endHeight) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AllFeatures", reflect.TypeOf((*MockState)(nil).AllFeatures)) } -// AccountBalance mocks base method -func (m *MockState) AccountBalance(account proto.Recipient, asset []byte) (uint64, error) { +// ApprovalHeight mocks base method. +func (m *MockState) ApprovalHeight(featureID int16) (proto.Height, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AccountBalance", account, asset) - ret0, _ := ret[0].(uint64) + ret := m.ctrl.Call(m, "ApprovalHeight", featureID) + ret0, _ := ret[0].(proto.Height) ret1, _ := ret[1].(error) return ret0, ret1 } -// AccountBalance indicates an expected call of AccountBalance -func (mr *MockStateMockRecorder) AccountBalance(account, asset interface{}) *gomock.Call { +// ApprovalHeight indicates an expected call of ApprovalHeight. +func (mr *MockStateMockRecorder) ApprovalHeight(featureID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AccountBalance", reflect.TypeOf((*MockState)(nil).AccountBalance), account, asset) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ApprovalHeight", reflect.TypeOf((*MockState)(nil).ApprovalHeight), featureID) } -// WavesAddressesNumber mocks base method -func (m *MockState) WavesAddressesNumber() (uint64, error) { +// AssetInfo mocks base method. +func (m *MockState) AssetInfo(assetID crypto.Digest) (*proto.AssetInfo, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "WavesAddressesNumber") - ret0, _ := ret[0].(uint64) + ret := m.ctrl.Call(m, "AssetInfo", assetID) + ret0, _ := ret[0].(*proto.AssetInfo) ret1, _ := ret[1].(error) return ret0, ret1 } -// WavesAddressesNumber indicates an expected call of WavesAddressesNumber -func (mr *MockStateMockRecorder) WavesAddressesNumber() *gomock.Call { +// AssetInfo indicates an expected call of AssetInfo. +func (mr *MockStateMockRecorder) AssetInfo(assetID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WavesAddressesNumber", reflect.TypeOf((*MockState)(nil).WavesAddressesNumber)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AssetInfo", reflect.TypeOf((*MockState)(nil).AssetInfo), assetID) } -// ScoreAtHeight mocks base method -func (m *MockState) ScoreAtHeight(height proto.Height) (*big.Int, error) { +// AssetIsSponsored mocks base method. +func (m *MockState) AssetIsSponsored(assetID crypto.Digest) (bool, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ScoreAtHeight", height) - ret0, _ := ret[0].(*big.Int) + ret := m.ctrl.Call(m, "AssetIsSponsored", assetID) + ret0, _ := ret[0].(bool) ret1, _ := ret[1].(error) return ret0, ret1 } -// ScoreAtHeight indicates an expected call of ScoreAtHeight -func (mr *MockStateMockRecorder) ScoreAtHeight(height interface{}) *gomock.Call { +// AssetIsSponsored indicates an expected call of AssetIsSponsored. +func (mr *MockStateMockRecorder) AssetIsSponsored(assetID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ScoreAtHeight", reflect.TypeOf((*MockState)(nil).ScoreAtHeight), height) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AssetIsSponsored", reflect.TypeOf((*MockState)(nil).AssetIsSponsored), assetID) } -// CurrentScore mocks base method -func (m *MockState) CurrentScore() (*big.Int, error) { +// Block mocks base method. +func (m *MockState) Block(blockID proto.BlockID) (*proto.Block, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CurrentScore") - ret0, _ := ret[0].(*big.Int) + ret := m.ctrl.Call(m, "Block", blockID) + ret0, _ := ret[0].(*proto.Block) ret1, _ := ret[1].(error) return ret0, ret1 } -// CurrentScore indicates an expected call of CurrentScore -func (mr *MockStateMockRecorder) CurrentScore() *gomock.Call { +// Block indicates an expected call of Block. +func (mr *MockStateMockRecorder) Block(blockID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CurrentScore", reflect.TypeOf((*MockState)(nil).CurrentScore)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Block", reflect.TypeOf((*MockState)(nil).Block), blockID) } -// BlockchainSettings mocks base method -func (m *MockState) BlockchainSettings() (*settings.BlockchainSettings, error) { +// BlockByHeight mocks base method. +func (m *MockState) BlockByHeight(height proto.Height) (*proto.Block, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "BlockchainSettings") - ret0, _ := ret[0].(*settings.BlockchainSettings) + ret := m.ctrl.Call(m, "BlockByHeight", height) + ret0, _ := ret[0].(*proto.Block) ret1, _ := ret[1].(error) return ret0, ret1 } -// BlockchainSettings indicates an expected call of BlockchainSettings -func (mr *MockStateMockRecorder) BlockchainSettings() *gomock.Call { +// BlockByHeight indicates an expected call of BlockByHeight. +func (mr *MockStateMockRecorder) BlockByHeight(height interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlockchainSettings", reflect.TypeOf((*MockState)(nil).BlockchainSettings)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlockByHeight", reflect.TypeOf((*MockState)(nil).BlockByHeight), height) } -// Peers mocks base method -func (m *MockState) Peers() ([]proto.TCPAddr, error) { +// BlockIDToHeight mocks base method. +func (m *MockState) BlockIDToHeight(blockID proto.BlockID) (proto.Height, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Peers") - ret0, _ := ret[0].([]proto.TCPAddr) + ret := m.ctrl.Call(m, "BlockIDToHeight", blockID) + ret0, _ := ret[0].(proto.Height) ret1, _ := ret[1].(error) return ret0, ret1 } -// Peers indicates an expected call of Peers -func (mr *MockStateMockRecorder) Peers() *gomock.Call { +// BlockIDToHeight indicates an expected call of BlockIDToHeight. +func (mr *MockStateMockRecorder) BlockIDToHeight(blockID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Peers", reflect.TypeOf((*MockState)(nil).Peers)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlockIDToHeight", reflect.TypeOf((*MockState)(nil).BlockIDToHeight), blockID) } -// VotesNum mocks base method -func (m *MockState) VotesNum(featureID int16) (uint64, error) { +// BlockchainSettings mocks base method. +func (m *MockState) BlockchainSettings() (*settings.BlockchainSettings, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "VotesNum", featureID) - ret0, _ := ret[0].(uint64) + ret := m.ctrl.Call(m, "BlockchainSettings") + ret0, _ := ret[0].(*settings.BlockchainSettings) ret1, _ := ret[1].(error) return ret0, ret1 } -// VotesNum indicates an expected call of VotesNum -func (mr *MockStateMockRecorder) VotesNum(featureID interface{}) *gomock.Call { +// BlockchainSettings indicates an expected call of BlockchainSettings. +func (mr *MockStateMockRecorder) BlockchainSettings() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VotesNum", reflect.TypeOf((*MockState)(nil).VotesNum), featureID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlockchainSettings", reflect.TypeOf((*MockState)(nil).BlockchainSettings)) } -// VotesNumAtHeight mocks base method -func (m *MockState) VotesNumAtHeight(featureID int16, height proto.Height) (uint64, error) { +// Close mocks base method. +func (m *MockState) Close() error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "VotesNumAtHeight", featureID, height) - ret0, _ := ret[0].(uint64) - ret1, _ := ret[1].(error) - return ret0, ret1 + ret := m.ctrl.Call(m, "Close") + ret0, _ := ret[0].(error) + return ret0 } -// VotesNumAtHeight indicates an expected call of VotesNumAtHeight -func (mr *MockStateMockRecorder) VotesNumAtHeight(featureID, height interface{}) *gomock.Call { +// Close indicates an expected call of Close. +func (mr *MockStateMockRecorder) Close() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VotesNumAtHeight", reflect.TypeOf((*MockState)(nil).VotesNumAtHeight), featureID, height) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockState)(nil).Close)) } -// IsActivated mocks base method -func (m *MockState) IsActivated(featureID int16) (bool, error) { +// CurrentScore mocks base method. +func (m *MockState) CurrentScore() (*big.Int, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IsActivated", featureID) - ret0, _ := ret[0].(bool) + ret := m.ctrl.Call(m, "CurrentScore") + ret0, _ := ret[0].(*big.Int) ret1, _ := ret[1].(error) return ret0, ret1 } -// IsActivated indicates an expected call of IsActivated -func (mr *MockStateMockRecorder) IsActivated(featureID interface{}) *gomock.Call { +// CurrentScore indicates an expected call of CurrentScore. +func (mr *MockStateMockRecorder) CurrentScore() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsActivated", reflect.TypeOf((*MockState)(nil).IsActivated), featureID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CurrentScore", reflect.TypeOf((*MockState)(nil).CurrentScore)) } -// IsActiveAtHeight mocks base method -func (m *MockState) IsActiveAtHeight(featureID int16, height proto.Height) (bool, error) { +// EffectiveBalance mocks base method. +func (m *MockState) EffectiveBalance(account proto.Recipient, startHeight, endHeight proto.Height) (uint64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IsActiveAtHeight", featureID, height) - ret0, _ := ret[0].(bool) + ret := m.ctrl.Call(m, "EffectiveBalance", account, startHeight, endHeight) + ret0, _ := ret[0].(uint64) ret1, _ := ret[1].(error) return ret0, ret1 } -// IsActiveAtHeight indicates an expected call of IsActiveAtHeight -func (mr *MockStateMockRecorder) IsActiveAtHeight(featureID, height interface{}) *gomock.Call { +// EffectiveBalance indicates an expected call of EffectiveBalance. +func (mr *MockStateMockRecorder) EffectiveBalance(account, startHeight, endHeight interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsActiveAtHeight", reflect.TypeOf((*MockState)(nil).IsActiveAtHeight), featureID, height) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EffectiveBalance", reflect.TypeOf((*MockState)(nil).EffectiveBalance), account, startHeight, endHeight) } -// ActivationHeight mocks base method -func (m *MockState) ActivationHeight(featureID int16) (proto.Height, error) { +// EstimatorVersion mocks base method. +func (m *MockState) EstimatorVersion() (int, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ActivationHeight", featureID) - ret0, _ := ret[0].(proto.Height) + ret := m.ctrl.Call(m, "EstimatorVersion") + ret0, _ := ret[0].(int) ret1, _ := ret[1].(error) return ret0, ret1 } -// ActivationHeight indicates an expected call of ActivationHeight -func (mr *MockStateMockRecorder) ActivationHeight(featureID interface{}) *gomock.Call { +// EstimatorVersion indicates an expected call of EstimatorVersion. +func (mr *MockStateMockRecorder) EstimatorVersion() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivationHeight", reflect.TypeOf((*MockState)(nil).ActivationHeight), featureID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EstimatorVersion", reflect.TypeOf((*MockState)(nil).EstimatorVersion)) } -// IsApproved mocks base method -func (m *MockState) IsApproved(featureID int16) (bool, error) { +// FullAssetInfo mocks base method. +func (m *MockState) FullAssetInfo(assetID crypto.Digest) (*proto.FullAssetInfo, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IsApproved", featureID) - ret0, _ := ret[0].(bool) + ret := m.ctrl.Call(m, "FullAssetInfo", assetID) + ret0, _ := ret[0].(*proto.FullAssetInfo) ret1, _ := ret[1].(error) return ret0, ret1 } -// IsApproved indicates an expected call of IsApproved -func (mr *MockStateMockRecorder) IsApproved(featureID interface{}) *gomock.Call { +// FullAssetInfo indicates an expected call of FullAssetInfo. +func (mr *MockStateMockRecorder) FullAssetInfo(assetID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsApproved", reflect.TypeOf((*MockState)(nil).IsApproved), featureID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FullAssetInfo", reflect.TypeOf((*MockState)(nil).FullAssetInfo), assetID) } -// IsApprovedAtHeight mocks base method -func (m *MockState) IsApprovedAtHeight(featureID int16, height proto.Height) (bool, error) { +// FullWavesBalance mocks base method. +func (m *MockState) FullWavesBalance(account proto.Recipient) (*proto.FullWavesBalance, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IsApprovedAtHeight", featureID, height) - ret0, _ := ret[0].(bool) + ret := m.ctrl.Call(m, "FullWavesBalance", account) + ret0, _ := ret[0].(*proto.FullWavesBalance) ret1, _ := ret[1].(error) return ret0, ret1 } -// IsApprovedAtHeight indicates an expected call of IsApprovedAtHeight -func (mr *MockStateMockRecorder) IsApprovedAtHeight(featureID, height interface{}) *gomock.Call { +// FullWavesBalance indicates an expected call of FullWavesBalance. +func (mr *MockStateMockRecorder) FullWavesBalance(account interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsApprovedAtHeight", reflect.TypeOf((*MockState)(nil).IsApprovedAtHeight), featureID, height) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FullWavesBalance", reflect.TypeOf((*MockState)(nil).FullWavesBalance), account) } -// ApprovalHeight mocks base method -func (m *MockState) ApprovalHeight(featureID int16) (proto.Height, error) { +// Header mocks base method. +func (m *MockState) Header(blockID proto.BlockID) (*proto.BlockHeader, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ApprovalHeight", featureID) - ret0, _ := ret[0].(proto.Height) + ret := m.ctrl.Call(m, "Header", blockID) + ret0, _ := ret[0].(*proto.BlockHeader) ret1, _ := ret[1].(error) return ret0, ret1 } -// ApprovalHeight indicates an expected call of ApprovalHeight -func (mr *MockStateMockRecorder) ApprovalHeight(featureID interface{}) *gomock.Call { +// Header indicates an expected call of Header. +func (mr *MockStateMockRecorder) Header(blockID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ApprovalHeight", reflect.TypeOf((*MockState)(nil).ApprovalHeight), featureID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Header", reflect.TypeOf((*MockState)(nil).Header), blockID) } -// AllFeatures mocks base method -func (m *MockState) AllFeatures() ([]int16, error) { +// HeaderByHeight mocks base method. +func (m *MockState) HeaderByHeight(height proto.Height) (*proto.BlockHeader, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AllFeatures") - ret0, _ := ret[0].([]int16) + ret := m.ctrl.Call(m, "HeaderByHeight", height) + ret0, _ := ret[0].(*proto.BlockHeader) ret1, _ := ret[1].(error) return ret0, ret1 } -// AllFeatures indicates an expected call of AllFeatures -func (mr *MockStateMockRecorder) AllFeatures() *gomock.Call { +// HeaderByHeight indicates an expected call of HeaderByHeight. +func (mr *MockStateMockRecorder) HeaderByHeight(height interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AllFeatures", reflect.TypeOf((*MockState)(nil).AllFeatures)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HeaderByHeight", reflect.TypeOf((*MockState)(nil).HeaderByHeight), height) } -// EstimatorVersion mocks base method -func (m *MockState) EstimatorVersion() (int, error) { +// Height mocks base method. +func (m *MockState) Height() (proto.Height, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "EstimatorVersion") - ret0, _ := ret[0].(int) + ret := m.ctrl.Call(m, "Height") + ret0, _ := ret[0].(proto.Height) ret1, _ := ret[1].(error) return ret0, ret1 } -// EstimatorVersion indicates an expected call of EstimatorVersion -func (mr *MockStateMockRecorder) EstimatorVersion() *gomock.Call { +// Height indicates an expected call of Height. +func (mr *MockStateMockRecorder) Height() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EstimatorVersion", reflect.TypeOf((*MockState)(nil).EstimatorVersion)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Height", reflect.TypeOf((*MockState)(nil).Height)) } -// AddrByAlias mocks base method -func (m *MockState) AddrByAlias(alias proto.Alias) (proto.Address, error) { +// HeightToBlockID mocks base method. +func (m *MockState) HeightToBlockID(height proto.Height) (proto.BlockID, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AddrByAlias", alias) - ret0, _ := ret[0].(proto.Address) + ret := m.ctrl.Call(m, "HeightToBlockID", height) + ret0, _ := ret[0].(proto.BlockID) ret1, _ := ret[1].(error) return ret0, ret1 } -// AddrByAlias indicates an expected call of AddrByAlias -func (mr *MockStateMockRecorder) AddrByAlias(alias interface{}) *gomock.Call { +// HeightToBlockID indicates an expected call of HeightToBlockID. +func (mr *MockStateMockRecorder) HeightToBlockID(height interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddrByAlias", reflect.TypeOf((*MockState)(nil).AddrByAlias), alias) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HeightToBlockID", reflect.TypeOf((*MockState)(nil).HeightToBlockID), height) } -// RetrieveEntries mocks base method -func (m *MockState) RetrieveEntries(account proto.Recipient) ([]proto.DataEntry, error) { +// HitSourceAtHeight mocks base method. +func (m *MockState) HitSourceAtHeight(height proto.Height) ([]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RetrieveEntries", account) - ret0, _ := ret[0].([]proto.DataEntry) + ret := m.ctrl.Call(m, "HitSourceAtHeight", height) + ret0, _ := ret[0].([]byte) ret1, _ := ret[1].(error) return ret0, ret1 } -// RetrieveEntries indicates an expected call of RetrieveEntries -func (mr *MockStateMockRecorder) RetrieveEntries(account interface{}) *gomock.Call { +// HitSourceAtHeight indicates an expected call of HitSourceAtHeight. +func (mr *MockStateMockRecorder) HitSourceAtHeight(height interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RetrieveEntries", reflect.TypeOf((*MockState)(nil).RetrieveEntries), account) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HitSourceAtHeight", reflect.TypeOf((*MockState)(nil).HitSourceAtHeight), height) } -// RetrieveEntry mocks base method -func (m *MockState) RetrieveEntry(account proto.Recipient, key string) (proto.DataEntry, error) { +// InvokeResultByID mocks base method. +func (m *MockState) InvokeResultByID(invokeID crypto.Digest) (*proto.ScriptResult, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RetrieveEntry", account, key) - ret0, _ := ret[0].(proto.DataEntry) + ret := m.ctrl.Call(m, "InvokeResultByID", invokeID) + ret0, _ := ret[0].(*proto.ScriptResult) ret1, _ := ret[1].(error) return ret0, ret1 } -// RetrieveEntry indicates an expected call of RetrieveEntry -func (mr *MockStateMockRecorder) RetrieveEntry(account, key interface{}) *gomock.Call { +// InvokeResultByID indicates an expected call of InvokeResultByID. +func (mr *MockStateMockRecorder) InvokeResultByID(invokeID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RetrieveEntry", reflect.TypeOf((*MockState)(nil).RetrieveEntry), account, key) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InvokeResultByID", reflect.TypeOf((*MockState)(nil).InvokeResultByID), invokeID) } -// RetrieveIntegerEntry mocks base method -func (m *MockState) RetrieveIntegerEntry(account proto.Recipient, key string) (*proto.IntegerDataEntry, error) { +// IsActivated mocks base method. +func (m *MockState) IsActivated(featureID int16) (bool, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RetrieveIntegerEntry", account, key) - ret0, _ := ret[0].(*proto.IntegerDataEntry) + ret := m.ctrl.Call(m, "IsActivated", featureID) + ret0, _ := ret[0].(bool) ret1, _ := ret[1].(error) return ret0, ret1 } -// RetrieveIntegerEntry indicates an expected call of RetrieveIntegerEntry -func (mr *MockStateMockRecorder) RetrieveIntegerEntry(account, key interface{}) *gomock.Call { +// IsActivated indicates an expected call of IsActivated. +func (mr *MockStateMockRecorder) IsActivated(featureID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RetrieveIntegerEntry", reflect.TypeOf((*MockState)(nil).RetrieveIntegerEntry), account, key) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsActivated", reflect.TypeOf((*MockState)(nil).IsActivated), featureID) } -// RetrieveBooleanEntry mocks base method -func (m *MockState) RetrieveBooleanEntry(account proto.Recipient, key string) (*proto.BooleanDataEntry, error) { +// IsActiveAtHeight mocks base method. +func (m *MockState) IsActiveAtHeight(featureID int16, height proto.Height) (bool, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RetrieveBooleanEntry", account, key) - ret0, _ := ret[0].(*proto.BooleanDataEntry) + ret := m.ctrl.Call(m, "IsActiveAtHeight", featureID, height) + ret0, _ := ret[0].(bool) ret1, _ := ret[1].(error) return ret0, ret1 } -// RetrieveBooleanEntry indicates an expected call of RetrieveBooleanEntry -func (mr *MockStateMockRecorder) RetrieveBooleanEntry(account, key interface{}) *gomock.Call { +// IsActiveAtHeight indicates an expected call of IsActiveAtHeight. +func (mr *MockStateMockRecorder) IsActiveAtHeight(featureID, height interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RetrieveBooleanEntry", reflect.TypeOf((*MockState)(nil).RetrieveBooleanEntry), account, key) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsActiveAtHeight", reflect.TypeOf((*MockState)(nil).IsActiveAtHeight), featureID, height) } -// RetrieveStringEntry mocks base method -func (m *MockState) RetrieveStringEntry(account proto.Recipient, key string) (*proto.StringDataEntry, error) { +// IsActiveLeasing mocks base method. +func (m *MockState) IsActiveLeasing(leaseID crypto.Digest) (bool, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RetrieveStringEntry", account, key) - ret0, _ := ret[0].(*proto.StringDataEntry) + ret := m.ctrl.Call(m, "IsActiveLeasing", leaseID) + ret0, _ := ret[0].(bool) ret1, _ := ret[1].(error) return ret0, ret1 } -// RetrieveStringEntry indicates an expected call of RetrieveStringEntry -func (mr *MockStateMockRecorder) RetrieveStringEntry(account, key interface{}) *gomock.Call { +// IsActiveLeasing indicates an expected call of IsActiveLeasing. +func (mr *MockStateMockRecorder) IsActiveLeasing(leaseID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RetrieveStringEntry", reflect.TypeOf((*MockState)(nil).RetrieveStringEntry), account, key) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsActiveLeasing", reflect.TypeOf((*MockState)(nil).IsActiveLeasing), leaseID) } -// RetrieveBinaryEntry mocks base method -func (m *MockState) RetrieveBinaryEntry(account proto.Recipient, key string) (*proto.BinaryDataEntry, error) { +// IsApproved mocks base method. +func (m *MockState) IsApproved(featureID int16) (bool, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RetrieveBinaryEntry", account, key) - ret0, _ := ret[0].(*proto.BinaryDataEntry) + ret := m.ctrl.Call(m, "IsApproved", featureID) + ret0, _ := ret[0].(bool) ret1, _ := ret[1].(error) return ret0, ret1 } -// RetrieveBinaryEntry indicates an expected call of RetrieveBinaryEntry -func (mr *MockStateMockRecorder) RetrieveBinaryEntry(account, key interface{}) *gomock.Call { +// IsApproved indicates an expected call of IsApproved. +func (mr *MockStateMockRecorder) IsApproved(featureID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RetrieveBinaryEntry", reflect.TypeOf((*MockState)(nil).RetrieveBinaryEntry), account, key) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsApproved", reflect.TypeOf((*MockState)(nil).IsApproved), featureID) } -// TransactionByID mocks base method -func (m *MockState) TransactionByID(id []byte) (proto.Transaction, error) { +// IsApprovedAtHeight mocks base method. +func (m *MockState) IsApprovedAtHeight(featureID int16, height proto.Height) (bool, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "TransactionByID", id) - ret0, _ := ret[0].(proto.Transaction) + ret := m.ctrl.Call(m, "IsApprovedAtHeight", featureID, height) + ret0, _ := ret[0].(bool) ret1, _ := ret[1].(error) return ret0, ret1 } -// TransactionByID indicates an expected call of TransactionByID -func (mr *MockStateMockRecorder) TransactionByID(id interface{}) *gomock.Call { +// IsApprovedAtHeight indicates an expected call of IsApprovedAtHeight. +func (mr *MockStateMockRecorder) IsApprovedAtHeight(featureID, height interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TransactionByID", reflect.TypeOf((*MockState)(nil).TransactionByID), id) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsApprovedAtHeight", reflect.TypeOf((*MockState)(nil).IsApprovedAtHeight), featureID, height) } -// TransactionByIDWithStatus mocks base method -func (m *MockState) TransactionByIDWithStatus(id []byte) (proto.Transaction, bool, error) { +// Map mocks base method. +func (m *MockState) Map(arg0 func(state.NonThreadSafeState) error) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "TransactionByIDWithStatus", id) - ret0, _ := ret[0].(proto.Transaction) - ret1, _ := ret[1].(bool) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 + ret := m.ctrl.Call(m, "Map", arg0) + ret0, _ := ret[0].(error) + return ret0 } -// TransactionByIDWithStatus indicates an expected call of TransactionByIDWithStatus -func (mr *MockStateMockRecorder) TransactionByIDWithStatus(id interface{}) *gomock.Call { +// Map indicates an expected call of Map. +func (mr *MockStateMockRecorder) Map(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TransactionByIDWithStatus", reflect.TypeOf((*MockState)(nil).TransactionByIDWithStatus), id) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Map", reflect.TypeOf((*MockState)(nil).Map), arg0) } -// TransactionHeightByID mocks base method -func (m *MockState) TransactionHeightByID(id []byte) (uint64, error) { +// MapR mocks base method. +func (m *MockState) MapR(arg0 func(state.StateInfo) (interface{}, error)) (interface{}, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "TransactionHeightByID", id) - ret0, _ := ret[0].(uint64) + ret := m.ctrl.Call(m, "MapR", arg0) + ret0, _ := ret[0].(interface{}) ret1, _ := ret[1].(error) return ret0, ret1 } -// TransactionHeightByID indicates an expected call of TransactionHeightByID -func (mr *MockStateMockRecorder) TransactionHeightByID(id interface{}) *gomock.Call { +// MapR indicates an expected call of MapR. +func (mr *MockStateMockRecorder) MapR(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TransactionHeightByID", reflect.TypeOf((*MockState)(nil).TransactionHeightByID), id) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MapR", reflect.TypeOf((*MockState)(nil).MapR), arg0) +} + +// NFTList mocks base method. +func (m *MockState) NFTList(account proto.Recipient, limit uint64, afterAssetID []byte) ([]*proto.FullAssetInfo, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NFTList", account, limit, afterAssetID) + ret0, _ := ret[0].([]*proto.FullAssetInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// NFTList indicates an expected call of NFTList. +func (mr *MockStateMockRecorder) NFTList(account, limit, afterAssetID interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NFTList", reflect.TypeOf((*MockState)(nil).NFTList), account, limit, afterAssetID) } -// NewAddrTransactionsIterator mocks base method +// NewAddrTransactionsIterator mocks base method. func (m *MockState) NewAddrTransactionsIterator(addr proto.Address) (state.TransactionIterator, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "NewAddrTransactionsIterator", addr) @@ -1738,443 +1764,447 @@ func (m *MockState) NewAddrTransactionsIterator(addr proto.Address) (state.Trans return ret0, ret1 } -// NewAddrTransactionsIterator indicates an expected call of NewAddrTransactionsIterator +// NewAddrTransactionsIterator indicates an expected call of NewAddrTransactionsIterator. func (mr *MockStateMockRecorder) NewAddrTransactionsIterator(addr interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewAddrTransactionsIterator", reflect.TypeOf((*MockState)(nil).NewAddrTransactionsIterator), addr) } -// AssetIsSponsored mocks base method -func (m *MockState) AssetIsSponsored(assetID crypto.Digest) (bool, error) { +// Peers mocks base method. +func (m *MockState) Peers() ([]proto.TCPAddr, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AssetIsSponsored", assetID) - ret0, _ := ret[0].(bool) + ret := m.ctrl.Call(m, "Peers") + ret0, _ := ret[0].([]proto.TCPAddr) ret1, _ := ret[1].(error) return ret0, ret1 } -// AssetIsSponsored indicates an expected call of AssetIsSponsored -func (mr *MockStateMockRecorder) AssetIsSponsored(assetID interface{}) *gomock.Call { +// Peers indicates an expected call of Peers. +func (mr *MockStateMockRecorder) Peers() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AssetIsSponsored", reflect.TypeOf((*MockState)(nil).AssetIsSponsored), assetID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Peers", reflect.TypeOf((*MockState)(nil).Peers)) } -// AssetInfo mocks base method -func (m *MockState) AssetInfo(assetID crypto.Digest) (*proto.AssetInfo, error) { +// PersistAddressTransactions mocks base method. +func (m *MockState) PersistAddressTransactions() error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AssetInfo", assetID) - ret0, _ := ret[0].(*proto.AssetInfo) - ret1, _ := ret[1].(error) - return ret0, ret1 + ret := m.ctrl.Call(m, "PersistAddressTransactions") + ret0, _ := ret[0].(error) + return ret0 } -// AssetInfo indicates an expected call of AssetInfo -func (mr *MockStateMockRecorder) AssetInfo(assetID interface{}) *gomock.Call { +// PersistAddressTransactions indicates an expected call of PersistAddressTransactions. +func (mr *MockStateMockRecorder) PersistAddressTransactions() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AssetInfo", reflect.TypeOf((*MockState)(nil).AssetInfo), assetID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PersistAddressTransactions", reflect.TypeOf((*MockState)(nil).PersistAddressTransactions)) } -// FullAssetInfo mocks base method -func (m *MockState) FullAssetInfo(assetID crypto.Digest) (*proto.FullAssetInfo, error) { +// ProvidesExtendedApi mocks base method. +func (m *MockState) ProvidesExtendedApi() (bool, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FullAssetInfo", assetID) - ret0, _ := ret[0].(*proto.FullAssetInfo) + ret := m.ctrl.Call(m, "ProvidesExtendedApi") + ret0, _ := ret[0].(bool) ret1, _ := ret[1].(error) return ret0, ret1 } -// FullAssetInfo indicates an expected call of FullAssetInfo -func (mr *MockStateMockRecorder) FullAssetInfo(assetID interface{}) *gomock.Call { +// ProvidesExtendedApi indicates an expected call of ProvidesExtendedApi. +func (mr *MockStateMockRecorder) ProvidesExtendedApi() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FullAssetInfo", reflect.TypeOf((*MockState)(nil).FullAssetInfo), assetID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProvidesExtendedApi", reflect.TypeOf((*MockState)(nil).ProvidesExtendedApi)) } -// NFTList mocks base method -func (m *MockState) NFTList(account proto.Recipient, limit uint64, afterAssetID []byte) ([]*proto.FullAssetInfo, error) { +// ProvidesStateHashes mocks base method. +func (m *MockState) ProvidesStateHashes() (bool, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NFTList", account, limit, afterAssetID) - ret0, _ := ret[0].([]*proto.FullAssetInfo) + ret := m.ctrl.Call(m, "ProvidesStateHashes") + ret0, _ := ret[0].(bool) ret1, _ := ret[1].(error) return ret0, ret1 } -// NFTList indicates an expected call of NFTList -func (mr *MockStateMockRecorder) NFTList(account, limit, afterAssetID interface{}) *gomock.Call { +// ProvidesStateHashes indicates an expected call of ProvidesStateHashes. +func (mr *MockStateMockRecorder) ProvidesStateHashes() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NFTList", reflect.TypeOf((*MockState)(nil).NFTList), account, limit, afterAssetID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProvidesStateHashes", reflect.TypeOf((*MockState)(nil).ProvidesStateHashes)) } -// ScriptInfoByAccount mocks base method -func (m *MockState) ScriptInfoByAccount(account proto.Recipient) (*proto.ScriptInfo, error) { +// ResetValidationList mocks base method. +func (m *MockState) ResetValidationList() { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ScriptInfoByAccount", account) - ret0, _ := ret[0].(*proto.ScriptInfo) - ret1, _ := ret[1].(error) - return ret0, ret1 + m.ctrl.Call(m, "ResetValidationList") } -// ScriptInfoByAccount indicates an expected call of ScriptInfoByAccount -func (mr *MockStateMockRecorder) ScriptInfoByAccount(account interface{}) *gomock.Call { +// ResetValidationList indicates an expected call of ResetValidationList. +func (mr *MockStateMockRecorder) ResetValidationList() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ScriptInfoByAccount", reflect.TypeOf((*MockState)(nil).ScriptInfoByAccount), account) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResetValidationList", reflect.TypeOf((*MockState)(nil).ResetValidationList)) } -// ScriptInfoByAsset mocks base method -func (m *MockState) ScriptInfoByAsset(assetID crypto.Digest) (*proto.ScriptInfo, error) { +// RetrieveBinaryEntry mocks base method. +func (m *MockState) RetrieveBinaryEntry(account proto.Recipient, key string) (*proto.BinaryDataEntry, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ScriptInfoByAsset", assetID) - ret0, _ := ret[0].(*proto.ScriptInfo) + ret := m.ctrl.Call(m, "RetrieveBinaryEntry", account, key) + ret0, _ := ret[0].(*proto.BinaryDataEntry) ret1, _ := ret[1].(error) return ret0, ret1 } -// ScriptInfoByAsset indicates an expected call of ScriptInfoByAsset -func (mr *MockStateMockRecorder) ScriptInfoByAsset(assetID interface{}) *gomock.Call { +// RetrieveBinaryEntry indicates an expected call of RetrieveBinaryEntry. +func (mr *MockStateMockRecorder) RetrieveBinaryEntry(account, key interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ScriptInfoByAsset", reflect.TypeOf((*MockState)(nil).ScriptInfoByAsset), assetID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RetrieveBinaryEntry", reflect.TypeOf((*MockState)(nil).RetrieveBinaryEntry), account, key) } -// IsActiveLeasing mocks base method -func (m *MockState) IsActiveLeasing(leaseID crypto.Digest) (bool, error) { +// RetrieveBooleanEntry mocks base method. +func (m *MockState) RetrieveBooleanEntry(account proto.Recipient, key string) (*proto.BooleanDataEntry, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IsActiveLeasing", leaseID) - ret0, _ := ret[0].(bool) + ret := m.ctrl.Call(m, "RetrieveBooleanEntry", account, key) + ret0, _ := ret[0].(*proto.BooleanDataEntry) ret1, _ := ret[1].(error) return ret0, ret1 } -// IsActiveLeasing indicates an expected call of IsActiveLeasing -func (mr *MockStateMockRecorder) IsActiveLeasing(leaseID interface{}) *gomock.Call { +// RetrieveBooleanEntry indicates an expected call of RetrieveBooleanEntry. +func (mr *MockStateMockRecorder) RetrieveBooleanEntry(account, key interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsActiveLeasing", reflect.TypeOf((*MockState)(nil).IsActiveLeasing), leaseID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RetrieveBooleanEntry", reflect.TypeOf((*MockState)(nil).RetrieveBooleanEntry), account, key) } -// InvokeResultByID mocks base method -func (m *MockState) InvokeResultByID(invokeID crypto.Digest) (*proto.ScriptResult, error) { +// RetrieveEntries mocks base method. +func (m *MockState) RetrieveEntries(account proto.Recipient) ([]proto.DataEntry, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "InvokeResultByID", invokeID) - ret0, _ := ret[0].(*proto.ScriptResult) + ret := m.ctrl.Call(m, "RetrieveEntries", account) + ret0, _ := ret[0].([]proto.DataEntry) ret1, _ := ret[1].(error) return ret0, ret1 } -// InvokeResultByID indicates an expected call of InvokeResultByID -func (mr *MockStateMockRecorder) InvokeResultByID(invokeID interface{}) *gomock.Call { +// RetrieveEntries indicates an expected call of RetrieveEntries. +func (mr *MockStateMockRecorder) RetrieveEntries(account interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InvokeResultByID", reflect.TypeOf((*MockState)(nil).InvokeResultByID), invokeID) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RetrieveEntries", reflect.TypeOf((*MockState)(nil).RetrieveEntries), account) } -// ProvidesExtendedApi mocks base method -func (m *MockState) ProvidesExtendedApi() (bool, error) { +// RetrieveEntry mocks base method. +func (m *MockState) RetrieveEntry(account proto.Recipient, key string) (proto.DataEntry, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ProvidesExtendedApi") - ret0, _ := ret[0].(bool) + ret := m.ctrl.Call(m, "RetrieveEntry", account, key) + ret0, _ := ret[0].(proto.DataEntry) ret1, _ := ret[1].(error) return ret0, ret1 } -// ProvidesExtendedApi indicates an expected call of ProvidesExtendedApi -func (mr *MockStateMockRecorder) ProvidesExtendedApi() *gomock.Call { +// RetrieveEntry indicates an expected call of RetrieveEntry. +func (mr *MockStateMockRecorder) RetrieveEntry(account, key interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProvidesExtendedApi", reflect.TypeOf((*MockState)(nil).ProvidesExtendedApi)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RetrieveEntry", reflect.TypeOf((*MockState)(nil).RetrieveEntry), account, key) } -// ProvidesStateHashes mocks base method -func (m *MockState) ProvidesStateHashes() (bool, error) { +// RetrieveIntegerEntry mocks base method. +func (m *MockState) RetrieveIntegerEntry(account proto.Recipient, key string) (*proto.IntegerDataEntry, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ProvidesStateHashes") - ret0, _ := ret[0].(bool) + ret := m.ctrl.Call(m, "RetrieveIntegerEntry", account, key) + ret0, _ := ret[0].(*proto.IntegerDataEntry) ret1, _ := ret[1].(error) return ret0, ret1 } -// ProvidesStateHashes indicates an expected call of ProvidesStateHashes -func (mr *MockStateMockRecorder) ProvidesStateHashes() *gomock.Call { +// RetrieveIntegerEntry indicates an expected call of RetrieveIntegerEntry. +func (mr *MockStateMockRecorder) RetrieveIntegerEntry(account, key interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ProvidesStateHashes", reflect.TypeOf((*MockState)(nil).ProvidesStateHashes)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RetrieveIntegerEntry", reflect.TypeOf((*MockState)(nil).RetrieveIntegerEntry), account, key) } -// StateHashAtHeight mocks base method -func (m *MockState) StateHashAtHeight(height uint64) (*proto.StateHash, error) { +// RetrieveStringEntry mocks base method. +func (m *MockState) RetrieveStringEntry(account proto.Recipient, key string) (*proto.StringDataEntry, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "StateHashAtHeight", height) - ret0, _ := ret[0].(*proto.StateHash) + ret := m.ctrl.Call(m, "RetrieveStringEntry", account, key) + ret0, _ := ret[0].(*proto.StringDataEntry) ret1, _ := ret[1].(error) return ret0, ret1 } -// StateHashAtHeight indicates an expected call of StateHashAtHeight -func (mr *MockStateMockRecorder) StateHashAtHeight(height interface{}) *gomock.Call { +// RetrieveStringEntry indicates an expected call of RetrieveStringEntry. +func (mr *MockStateMockRecorder) RetrieveStringEntry(account, key interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateHashAtHeight", reflect.TypeOf((*MockState)(nil).StateHashAtHeight), height) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RetrieveStringEntry", reflect.TypeOf((*MockState)(nil).RetrieveStringEntry), account, key) } -// MapR mocks base method -func (m *MockState) MapR(arg0 func(state.StateInfo) (interface{}, error)) (interface{}, error) { +// RollbackTo mocks base method. +func (m *MockState) RollbackTo(removalEdge proto.BlockID) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "MapR", arg0) - ret0, _ := ret[0].(interface{}) - ret1, _ := ret[1].(error) - return ret0, ret1 + ret := m.ctrl.Call(m, "RollbackTo", removalEdge) + ret0, _ := ret[0].(error) + return ret0 } -// MapR indicates an expected call of MapR -func (mr *MockStateMockRecorder) MapR(arg0 interface{}) *gomock.Call { +// RollbackTo indicates an expected call of RollbackTo. +func (mr *MockStateMockRecorder) RollbackTo(removalEdge interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MapR", reflect.TypeOf((*MockState)(nil).MapR), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RollbackTo", reflect.TypeOf((*MockState)(nil).RollbackTo), removalEdge) } -// HitSourceAtHeight mocks base method -func (m *MockState) HitSourceAtHeight(height proto.Height) ([]byte, error) { +// RollbackToHeight mocks base method. +func (m *MockState) RollbackToHeight(height proto.Height) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "HitSourceAtHeight", height) - ret0, _ := ret[0].([]byte) - ret1, _ := ret[1].(error) - return ret0, ret1 + ret := m.ctrl.Call(m, "RollbackToHeight", height) + ret0, _ := ret[0].(error) + return ret0 } -// HitSourceAtHeight indicates an expected call of HitSourceAtHeight -func (mr *MockStateMockRecorder) HitSourceAtHeight(height interface{}) *gomock.Call { +// RollbackToHeight indicates an expected call of RollbackToHeight. +func (mr *MockStateMockRecorder) RollbackToHeight(height interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HitSourceAtHeight", reflect.TypeOf((*MockState)(nil).HitSourceAtHeight), height) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RollbackToHeight", reflect.TypeOf((*MockState)(nil).RollbackToHeight), height) } -// ShouldPersistAddressTransactions mocks base method -func (m *MockState) ShouldPersistAddressTransactions() (bool, error) { +// SavePeers mocks base method. +func (m *MockState) SavePeers(arg0 []proto.TCPAddr) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ShouldPersistAddressTransactions") - ret0, _ := ret[0].(bool) - ret1, _ := ret[1].(error) - return ret0, ret1 + ret := m.ctrl.Call(m, "SavePeers", arg0) + ret0, _ := ret[0].(error) + return ret0 } -// ShouldPersistAddressTransactions indicates an expected call of ShouldPersistAddressTransactions -func (mr *MockStateMockRecorder) ShouldPersistAddressTransactions() *gomock.Call { +// SavePeers indicates an expected call of SavePeers. +func (mr *MockStateMockRecorder) SavePeers(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ShouldPersistAddressTransactions", reflect.TypeOf((*MockState)(nil).ShouldPersistAddressTransactions)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SavePeers", reflect.TypeOf((*MockState)(nil).SavePeers), arg0) } -// AddBlock mocks base method -func (m *MockState) AddBlock(block []byte) (*proto.Block, error) { +// ScoreAtHeight mocks base method. +func (m *MockState) ScoreAtHeight(height proto.Height) (*big.Int, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AddBlock", block) - ret0, _ := ret[0].(*proto.Block) + ret := m.ctrl.Call(m, "ScoreAtHeight", height) + ret0, _ := ret[0].(*big.Int) ret1, _ := ret[1].(error) return ret0, ret1 } -// AddBlock indicates an expected call of AddBlock -func (mr *MockStateMockRecorder) AddBlock(block interface{}) *gomock.Call { +// ScoreAtHeight indicates an expected call of ScoreAtHeight. +func (mr *MockStateMockRecorder) ScoreAtHeight(height interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddBlock", reflect.TypeOf((*MockState)(nil).AddBlock), block) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ScoreAtHeight", reflect.TypeOf((*MockState)(nil).ScoreAtHeight), height) } -// AddDeserializedBlock mocks base method -func (m *MockState) AddDeserializedBlock(block *proto.Block) (*proto.Block, error) { +// ScriptInfoByAccount mocks base method. +func (m *MockState) ScriptInfoByAccount(account proto.Recipient) (*proto.ScriptInfo, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AddDeserializedBlock", block) - ret0, _ := ret[0].(*proto.Block) + ret := m.ctrl.Call(m, "ScriptInfoByAccount", account) + ret0, _ := ret[0].(*proto.ScriptInfo) ret1, _ := ret[1].(error) return ret0, ret1 } -// AddDeserializedBlock indicates an expected call of AddDeserializedBlock -func (mr *MockStateMockRecorder) AddDeserializedBlock(block interface{}) *gomock.Call { +// ScriptInfoByAccount indicates an expected call of ScriptInfoByAccount. +func (mr *MockStateMockRecorder) ScriptInfoByAccount(account interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddDeserializedBlock", reflect.TypeOf((*MockState)(nil).AddDeserializedBlock), block) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ScriptInfoByAccount", reflect.TypeOf((*MockState)(nil).ScriptInfoByAccount), account) } -// AddNewBlocks mocks base method -func (m *MockState) AddNewBlocks(blocks [][]byte) error { +// ScriptInfoByAsset mocks base method. +func (m *MockState) ScriptInfoByAsset(assetID crypto.Digest) (*proto.ScriptInfo, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AddNewBlocks", blocks) - ret0, _ := ret[0].(error) - return ret0 + ret := m.ctrl.Call(m, "ScriptInfoByAsset", assetID) + ret0, _ := ret[0].(*proto.ScriptInfo) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// AddNewBlocks indicates an expected call of AddNewBlocks -func (mr *MockStateMockRecorder) AddNewBlocks(blocks interface{}) *gomock.Call { +// ScriptInfoByAsset indicates an expected call of ScriptInfoByAsset. +func (mr *MockStateMockRecorder) ScriptInfoByAsset(assetID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddNewBlocks", reflect.TypeOf((*MockState)(nil).AddNewBlocks), blocks) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ScriptInfoByAsset", reflect.TypeOf((*MockState)(nil).ScriptInfoByAsset), assetID) } -// AddNewDeserializedBlocks mocks base method -func (m *MockState) AddNewDeserializedBlocks(blocks []*proto.Block) (*proto.Block, error) { +// ShouldPersistAddressTransactions mocks base method. +func (m *MockState) ShouldPersistAddressTransactions() (bool, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AddNewDeserializedBlocks", blocks) - ret0, _ := ret[0].(*proto.Block) + ret := m.ctrl.Call(m, "ShouldPersistAddressTransactions") + ret0, _ := ret[0].(bool) ret1, _ := ret[1].(error) return ret0, ret1 } -// AddNewDeserializedBlocks indicates an expected call of AddNewDeserializedBlocks -func (mr *MockStateMockRecorder) AddNewDeserializedBlocks(blocks interface{}) *gomock.Call { +// ShouldPersistAddressTransactions indicates an expected call of ShouldPersistAddressTransactions. +func (mr *MockStateMockRecorder) ShouldPersistAddressTransactions() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddNewDeserializedBlocks", reflect.TypeOf((*MockState)(nil).AddNewDeserializedBlocks), blocks) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ShouldPersistAddressTransactions", reflect.TypeOf((*MockState)(nil).ShouldPersistAddressTransactions)) } -// AddOldBlocks mocks base method -func (m *MockState) AddOldBlocks(blocks [][]byte) error { +// SmartState mocks base method. +func (m *MockState) SmartState() types.SmartState { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AddOldBlocks", blocks) - ret0, _ := ret[0].(error) + ret := m.ctrl.Call(m, "SmartState") + ret0, _ := ret[0].(types.SmartState) return ret0 } -// AddOldBlocks indicates an expected call of AddOldBlocks -func (mr *MockStateMockRecorder) AddOldBlocks(blocks interface{}) *gomock.Call { +// SmartState indicates an expected call of SmartState. +func (mr *MockStateMockRecorder) SmartState() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddOldBlocks", reflect.TypeOf((*MockState)(nil).AddOldBlocks), blocks) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SmartState", reflect.TypeOf((*MockState)(nil).SmartState)) } -// AddOldDeserializedBlocks mocks base method -func (m *MockState) AddOldDeserializedBlocks(blocks []*proto.Block) error { +// StartProvidingExtendedApi mocks base method. +func (m *MockState) StartProvidingExtendedApi() error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AddOldDeserializedBlocks", blocks) + ret := m.ctrl.Call(m, "StartProvidingExtendedApi") ret0, _ := ret[0].(error) return ret0 } -// AddOldDeserializedBlocks indicates an expected call of AddOldDeserializedBlocks -func (mr *MockStateMockRecorder) AddOldDeserializedBlocks(blocks interface{}) *gomock.Call { +// StartProvidingExtendedApi indicates an expected call of StartProvidingExtendedApi. +func (mr *MockStateMockRecorder) StartProvidingExtendedApi() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddOldDeserializedBlocks", reflect.TypeOf((*MockState)(nil).AddOldDeserializedBlocks), blocks) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartProvidingExtendedApi", reflect.TypeOf((*MockState)(nil).StartProvidingExtendedApi)) } -// RollbackToHeight mocks base method -func (m *MockState) RollbackToHeight(height proto.Height) error { +// StateHashAtHeight mocks base method. +func (m *MockState) StateHashAtHeight(height uint64) (*proto.StateHash, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RollbackToHeight", height) - ret0, _ := ret[0].(error) - return ret0 + ret := m.ctrl.Call(m, "StateHashAtHeight", height) + ret0, _ := ret[0].(*proto.StateHash) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// RollbackToHeight indicates an expected call of RollbackToHeight -func (mr *MockStateMockRecorder) RollbackToHeight(height interface{}) *gomock.Call { +// StateHashAtHeight indicates an expected call of StateHashAtHeight. +func (mr *MockStateMockRecorder) StateHashAtHeight(height interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RollbackToHeight", reflect.TypeOf((*MockState)(nil).RollbackToHeight), height) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateHashAtHeight", reflect.TypeOf((*MockState)(nil).StateHashAtHeight), height) } -// RollbackTo mocks base method -func (m *MockState) RollbackTo(removalEdge proto.BlockID) error { +// TopBlock mocks base method. +func (m *MockState) TopBlock() *proto.Block { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RollbackTo", removalEdge) - ret0, _ := ret[0].(error) + ret := m.ctrl.Call(m, "TopBlock") + ret0, _ := ret[0].(*proto.Block) return ret0 } -// RollbackTo indicates an expected call of RollbackTo -func (mr *MockStateMockRecorder) RollbackTo(removalEdge interface{}) *gomock.Call { +// TopBlock indicates an expected call of TopBlock. +func (mr *MockStateMockRecorder) TopBlock() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RollbackTo", reflect.TypeOf((*MockState)(nil).RollbackTo), removalEdge) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TopBlock", reflect.TypeOf((*MockState)(nil).TopBlock)) } -// ValidateNextTx mocks base method -func (m *MockState) ValidateNextTx(tx proto.Transaction, currentTimestamp, parentTimestamp uint64, blockVersion proto.BlockVersion, acceptFailed bool) error { +// TransactionByID mocks base method. +func (m *MockState) TransactionByID(id []byte) (proto.Transaction, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ValidateNextTx", tx, currentTimestamp, parentTimestamp, blockVersion, acceptFailed) - ret0, _ := ret[0].(error) - return ret0 + ret := m.ctrl.Call(m, "TransactionByID", id) + ret0, _ := ret[0].(proto.Transaction) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// ValidateNextTx indicates an expected call of ValidateNextTx -func (mr *MockStateMockRecorder) ValidateNextTx(tx, currentTimestamp, parentTimestamp, blockVersion, acceptFailed interface{}) *gomock.Call { +// TransactionByID indicates an expected call of TransactionByID. +func (mr *MockStateMockRecorder) TransactionByID(id interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateNextTx", reflect.TypeOf((*MockState)(nil).ValidateNextTx), tx, currentTimestamp, parentTimestamp, blockVersion, acceptFailed) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TransactionByID", reflect.TypeOf((*MockState)(nil).TransactionByID), id) } -// ResetValidationList mocks base method -func (m *MockState) ResetValidationList() { +// TransactionByIDWithStatus mocks base method. +func (m *MockState) TransactionByIDWithStatus(id []byte) (proto.Transaction, bool, error) { m.ctrl.T.Helper() - m.ctrl.Call(m, "ResetValidationList") + ret := m.ctrl.Call(m, "TransactionByIDWithStatus", id) + ret0, _ := ret[0].(proto.Transaction) + ret1, _ := ret[1].(bool) + ret2, _ := ret[2].(error) + return ret0, ret1, ret2 } -// ResetValidationList indicates an expected call of ResetValidationList -func (mr *MockStateMockRecorder) ResetValidationList() *gomock.Call { +// TransactionByIDWithStatus indicates an expected call of TransactionByIDWithStatus. +func (mr *MockStateMockRecorder) TransactionByIDWithStatus(id interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ResetValidationList", reflect.TypeOf((*MockState)(nil).ResetValidationList)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TransactionByIDWithStatus", reflect.TypeOf((*MockState)(nil).TransactionByIDWithStatus), id) } -// TxValidation mocks base method -func (m *MockState) TxValidation(arg0 func(state.TxValidation) error) error { +// TransactionHeightByID mocks base method. +func (m *MockState) TransactionHeightByID(id []byte) (uint64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "TxValidation", arg0) - ret0, _ := ret[0].(error) - return ret0 + ret := m.ctrl.Call(m, "TransactionHeightByID", id) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// TxValidation indicates an expected call of TxValidation -func (mr *MockStateMockRecorder) TxValidation(arg0 interface{}) *gomock.Call { +// TransactionHeightByID indicates an expected call of TransactionHeightByID. +func (mr *MockStateMockRecorder) TransactionHeightByID(id interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TxValidation", reflect.TypeOf((*MockState)(nil).TxValidation), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TransactionHeightByID", reflect.TypeOf((*MockState)(nil).TransactionHeightByID), id) } -// Map mocks base method -func (m *MockState) Map(arg0 func(state.NonThreadSafeState) error) error { +// TxValidation mocks base method. +func (m *MockState) TxValidation(arg0 func(state.TxValidation) error) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Map", arg0) + ret := m.ctrl.Call(m, "TxValidation", arg0) ret0, _ := ret[0].(error) return ret0 } -// Map indicates an expected call of Map -func (mr *MockStateMockRecorder) Map(arg0 interface{}) *gomock.Call { +// TxValidation indicates an expected call of TxValidation. +func (mr *MockStateMockRecorder) TxValidation(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Map", reflect.TypeOf((*MockState)(nil).Map), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TxValidation", reflect.TypeOf((*MockState)(nil).TxValidation), arg0) } -// SavePeers mocks base method -func (m *MockState) SavePeers(arg0 []proto.TCPAddr) error { +// ValidateNextTx mocks base method. +func (m *MockState) ValidateNextTx(tx proto.Transaction, currentTimestamp, parentTimestamp uint64, blockVersion proto.BlockVersion, acceptFailed bool) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "SavePeers", arg0) + ret := m.ctrl.Call(m, "ValidateNextTx", tx, currentTimestamp, parentTimestamp, blockVersion, acceptFailed) ret0, _ := ret[0].(error) return ret0 } -// SavePeers indicates an expected call of SavePeers -func (mr *MockStateMockRecorder) SavePeers(arg0 interface{}) *gomock.Call { +// ValidateNextTx indicates an expected call of ValidateNextTx. +func (mr *MockStateMockRecorder) ValidateNextTx(tx, currentTimestamp, parentTimestamp, blockVersion, acceptFailed interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SavePeers", reflect.TypeOf((*MockState)(nil).SavePeers), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateNextTx", reflect.TypeOf((*MockState)(nil).ValidateNextTx), tx, currentTimestamp, parentTimestamp, blockVersion, acceptFailed) } -// StartProvidingExtendedApi mocks base method -func (m *MockState) StartProvidingExtendedApi() error { +// VotesNum mocks base method. +func (m *MockState) VotesNum(featureID int16) (uint64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "StartProvidingExtendedApi") - ret0, _ := ret[0].(error) - return ret0 + ret := m.ctrl.Call(m, "VotesNum", featureID) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// StartProvidingExtendedApi indicates an expected call of StartProvidingExtendedApi -func (mr *MockStateMockRecorder) StartProvidingExtendedApi() *gomock.Call { +// VotesNum indicates an expected call of VotesNum. +func (mr *MockStateMockRecorder) VotesNum(featureID interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartProvidingExtendedApi", reflect.TypeOf((*MockState)(nil).StartProvidingExtendedApi)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VotesNum", reflect.TypeOf((*MockState)(nil).VotesNum), featureID) } -// PersistAddressTransactions mocks base method -func (m *MockState) PersistAddressTransactions() error { +// VotesNumAtHeight mocks base method. +func (m *MockState) VotesNumAtHeight(featureID int16, height proto.Height) (uint64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PersistAddressTransactions") - ret0, _ := ret[0].(error) - return ret0 + ret := m.ctrl.Call(m, "VotesNumAtHeight", featureID, height) + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// PersistAddressTransactions indicates an expected call of PersistAddressTransactions -func (mr *MockStateMockRecorder) PersistAddressTransactions() *gomock.Call { +// VotesNumAtHeight indicates an expected call of VotesNumAtHeight. +func (mr *MockStateMockRecorder) VotesNumAtHeight(featureID, height interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PersistAddressTransactions", reflect.TypeOf((*MockState)(nil).PersistAddressTransactions)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VotesNumAtHeight", reflect.TypeOf((*MockState)(nil).VotesNumAtHeight), featureID, height) } -// Close mocks base method -func (m *MockState) Close() error { +// WavesAddressesNumber mocks base method. +func (m *MockState) WavesAddressesNumber() (uint64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Close") - ret0, _ := ret[0].(error) - return ret0 + ret := m.ctrl.Call(m, "WavesAddressesNumber") + ret0, _ := ret[0].(uint64) + ret1, _ := ret[1].(error) + return ret0, ret1 } -// Close indicates an expected call of Close -func (mr *MockStateMockRecorder) Close() *gomock.Call { +// WavesAddressesNumber indicates an expected call of WavesAddressesNumber. +func (mr *MockStateMockRecorder) WavesAddressesNumber() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockState)(nil).Close)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WavesAddressesNumber", reflect.TypeOf((*MockState)(nil).WavesAddressesNumber)) } diff --git a/pkg/node/state_fsm/default_mock.go b/pkg/node/state_fsm/default_mock.go index b7db63e51..fc5cfb53f 100644 --- a/pkg/node/state_fsm/default_mock.go +++ b/pkg/node/state_fsm/default_mock.go @@ -5,78 +5,79 @@ package state_fsm import ( + reflect "reflect" + gomock "github.com/golang/mock/gomock" . "github.com/wavesplatform/gowaves/pkg/p2p/peer" - reflect "reflect" ) -// MockDefault is a mock of Default interface +// MockDefault is a mock of Default interface. type MockDefault struct { ctrl *gomock.Controller recorder *MockDefaultMockRecorder } -// MockDefaultMockRecorder is the mock recorder for MockDefault +// MockDefaultMockRecorder is the mock recorder for MockDefault. type MockDefaultMockRecorder struct { mock *MockDefault } -// NewMockDefault creates a new mock instance +// NewMockDefault creates a new mock instance. func NewMockDefault(ctrl *gomock.Controller) *MockDefault { mock := &MockDefault{ctrl: ctrl} mock.recorder = &MockDefaultMockRecorder{mock} return mock } -// EXPECT returns an object that allows the caller to indicate expected use +// EXPECT returns an object that allows the caller to indicate expected use. func (m *MockDefault) EXPECT() *MockDefaultMockRecorder { return m.recorder } -// Noop mocks base method -func (m *MockDefault) Noop(arg0 FSM) (FSM, Async, error) { +// NewPeer mocks base method. +func (m *MockDefault) NewPeer(fsm FSM, p Peer, info BaseInfo) (FSM, Async, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Noop", arg0) + ret := m.ctrl.Call(m, "NewPeer", fsm, p, info) ret0, _ := ret[0].(FSM) ret1, _ := ret[1].(Async) ret2, _ := ret[2].(error) return ret0, ret1, ret2 } -// Noop indicates an expected call of Noop -func (mr *MockDefaultMockRecorder) Noop(arg0 interface{}) *gomock.Call { +// NewPeer indicates an expected call of NewPeer. +func (mr *MockDefaultMockRecorder) NewPeer(fsm, p, info interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Noop", reflect.TypeOf((*MockDefault)(nil).Noop), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewPeer", reflect.TypeOf((*MockDefault)(nil).NewPeer), fsm, p, info) } -// PeerError mocks base method -func (m *MockDefault) PeerError(fsm FSM, p Peer, baseInfo BaseInfo, arg3 error) (FSM, Async, error) { +// Noop mocks base method. +func (m *MockDefault) Noop(arg0 FSM) (FSM, Async, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "PeerError", fsm, p, baseInfo, arg3) + ret := m.ctrl.Call(m, "Noop", arg0) ret0, _ := ret[0].(FSM) ret1, _ := ret[1].(Async) ret2, _ := ret[2].(error) return ret0, ret1, ret2 } -// PeerError indicates an expected call of PeerError -func (mr *MockDefaultMockRecorder) PeerError(fsm, p, baseInfo, arg3 interface{}) *gomock.Call { +// Noop indicates an expected call of Noop. +func (mr *MockDefaultMockRecorder) Noop(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PeerError", reflect.TypeOf((*MockDefault)(nil).PeerError), fsm, p, baseInfo, arg3) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Noop", reflect.TypeOf((*MockDefault)(nil).Noop), arg0) } -// NewPeer mocks base method -func (m *MockDefault) NewPeer(fsm FSM, p Peer, info BaseInfo) (FSM, Async, error) { +// PeerError mocks base method. +func (m *MockDefault) PeerError(fsm FSM, p Peer, baseInfo BaseInfo, arg3 error) (FSM, Async, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NewPeer", fsm, p, info) + ret := m.ctrl.Call(m, "PeerError", fsm, p, baseInfo, arg3) ret0, _ := ret[0].(FSM) ret1, _ := ret[1].(Async) ret2, _ := ret[2].(error) return ret0, ret1, ret2 } -// NewPeer indicates an expected call of NewPeer -func (mr *MockDefaultMockRecorder) NewPeer(fsm, p, info interface{}) *gomock.Call { +// PeerError indicates an expected call of PeerError. +func (mr *MockDefaultMockRecorder) PeerError(fsm, p, baseInfo, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewPeer", reflect.TypeOf((*MockDefault)(nil).NewPeer), fsm, p, info) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PeerError", reflect.TypeOf((*MockDefault)(nil).PeerError), fsm, p, baseInfo, arg3) } diff --git a/pkg/proto/proto_test.go b/pkg/proto/proto_test.go index c84d2f9f1..ad34c064d 100644 --- a/pkg/proto/proto_test.go +++ b/pkg/proto/proto_test.go @@ -558,6 +558,7 @@ func TestGetBlockMessage_MarshalBinary(t *testing.T) { } rs, err := b.MarshalBinary() + t.Log(rs) require.NoError(t, err) b2 := GetBlockMessage{} @@ -616,3 +617,13 @@ func TestTCPAddr_ToUint64(t *testing.T) { require.True(t, a.Equal(b)) } + +func TestGetPeersMessage_MarshalBinary(t *testing.T) { + m := GetPeersMessage{} + bts, err := m.MarshalBinary() + require.NoError(t, err) + t.Log(bts) + + err = m.UnmarshalBinary(bts) + require.NoError(t, err) +} diff --git a/pkg/proto/scripting.go b/pkg/proto/scripting.go index fd744a59d..7e4ba7e3a 100644 --- a/pkg/proto/scripting.go +++ b/pkg/proto/scripting.go @@ -1,6 +1,7 @@ package proto import ( + "bytes" "encoding/binary" "unicode/utf16" @@ -10,9 +11,25 @@ import ( g "github.com/wavesplatform/gowaves/pkg/grpc/generated/waves" ) +type ScriptActions []ScriptAction + +func (a ScriptActions) Eq(b ScriptActions) bool { + if len(a) != len(b) { + return false + } + + for i := range a { + if !a[i].Eq(b[i]) { + return false + } + } + return true +} + // ScriptAction common interface of script invocation actions. type ScriptAction interface { scriptAction() + Eq(ScriptAction) bool } // DataEntryScriptAction is an action to manipulate account data state. @@ -22,6 +39,14 @@ type DataEntryScriptAction struct { func (a DataEntryScriptAction) scriptAction() {} +func (a DataEntryScriptAction) Eq(another ScriptAction) bool { + b, ok := another.(*DataEntryScriptAction) + if !ok { + return false + } + return a.Entry.Eq(b.Entry) +} + func (a *DataEntryScriptAction) ToProtobuf() *g.DataTransactionData_DataEntry { return a.Entry.ToProtobuf() } @@ -35,6 +60,14 @@ type TransferScriptAction struct { func (a TransferScriptAction) scriptAction() {} +func (a TransferScriptAction) Eq(other ScriptAction) bool { + b, ok := other.(*TransferScriptAction) + if !ok { + return false + } + return a.Amount == b.Amount && a.Asset == b.Asset && a.Recipient.Eq(b.Recipient) +} + func (a *TransferScriptAction) ToProtobuf() (*g.InvokeScriptResult_Payment, error) { amount := &g.Amount{ AssetId: a.Asset.ToID(), @@ -61,6 +94,21 @@ type IssueScriptAction struct { func (a IssueScriptAction) scriptAction() {} +func (a IssueScriptAction) Eq(other ScriptAction) bool { + b, ok := other.(*IssueScriptAction) + if !ok { + return false + } + return a.ID == b.ID && + a.Name == b.Name && + a.Description == b.Description && + a.Quantity == b.Quantity && + a.Decimals == b.Decimals && + a.Reissuable == b.Reissuable && + bytes.Equal(a.Script, b.Script) && + a.Nonce == b.Nonce +} + func (a *IssueScriptAction) ToProtobuf() *g.InvokeScriptResult_Issue { return &g.InvokeScriptResult_Issue{ AssetId: a.ID.Bytes(), @@ -109,6 +157,14 @@ type ReissueScriptAction struct { func (a ReissueScriptAction) scriptAction() {} +func (a ReissueScriptAction) Eq(other ScriptAction) bool { + b, ok := other.(*ReissueScriptAction) + if !ok { + return false + } + return a.Reissuable == b.Reissuable && a.AssetID == b.AssetID && a.Quantity == b.Quantity +} + func (a *ReissueScriptAction) ToProtobuf() *g.InvokeScriptResult_Reissue { return &g.InvokeScriptResult_Reissue{ AssetId: a.AssetID.Bytes(), @@ -125,6 +181,14 @@ type BurnScriptAction struct { func (a BurnScriptAction) scriptAction() {} +func (a BurnScriptAction) Eq(other ScriptAction) bool { + b, ok := other.(*BurnScriptAction) + if !ok { + return false + } + return a.AssetID == b.AssetID && a.Quantity == b.Quantity +} + func (a *BurnScriptAction) ToProtobuf() *g.InvokeScriptResult_Burn { return &g.InvokeScriptResult_Burn{ AssetId: a.AssetID.Bytes(), @@ -140,6 +204,14 @@ type SponsorshipScriptAction struct { func (a SponsorshipScriptAction) scriptAction() {} +func (a SponsorshipScriptAction) Eq(other ScriptAction) bool { + b, ok := other.(*SponsorshipScriptAction) + if !ok { + return false + } + return a.AssetID == b.AssetID && a.MinFee == b.MinFee +} + func (a *SponsorshipScriptAction) ToProtobuf() *g.InvokeScriptResult_SponsorFee { return &g.InvokeScriptResult_SponsorFee{ MinFee: &g.Amount{ diff --git a/pkg/proto/types.go b/pkg/proto/types.go index f2be41ad6..f672983ca 100644 --- a/pkg/proto/types.go +++ b/pkg/proto/types.go @@ -1731,6 +1731,8 @@ type DataEntry interface { BinarySize() int ToProtobuf() *g.DataTransactionData_DataEntry + + Eq(DataEntry) bool } var bytesToDataEntry = map[DataValueType]reflect.Type{ @@ -1786,6 +1788,13 @@ type IntegerDataEntry struct { Value int64 } +func (e IntegerDataEntry) Eq(other DataEntry) bool { + if b, ok := other.(*IntegerDataEntry); ok { + return e.Key == b.Key && e.Value == b.Value + } + return false +} + func (e IntegerDataEntry) ToProtobuf() *g.DataTransactionData_DataEntry { return &g.DataTransactionData_DataEntry{ Key: e.Key, @@ -1914,6 +1923,13 @@ type BooleanDataEntry struct { Value bool } +func (e BooleanDataEntry) Eq(other DataEntry) bool { + if b, ok := other.(*BooleanDataEntry); ok { + return e.Key == b.Key && e.Value == b.Value + } + return false +} + func (e BooleanDataEntry) ToProtobuf() *g.DataTransactionData_DataEntry { return &g.DataTransactionData_DataEntry{ Key: e.Key, @@ -2046,6 +2062,13 @@ type BinaryDataEntry struct { Value []byte } +func (e BinaryDataEntry) Eq(other DataEntry) bool { + if b, ok := other.(*BinaryDataEntry); ok { + return e.Key == b.Key && bytes.Equal(e.Value, b.Value) + } + return false +} + func (e BinaryDataEntry) ToProtobuf() *g.DataTransactionData_DataEntry { return &g.DataTransactionData_DataEntry{ Key: e.Key, @@ -2181,6 +2204,13 @@ type StringDataEntry struct { Value string } +func (e StringDataEntry) Eq(other DataEntry) bool { + if b, ok := other.(*StringDataEntry); ok { + return e.Key == b.Key && e.Value == b.Value + } + return false +} + func (e StringDataEntry) ToProtobuf() *g.DataTransactionData_DataEntry { return &g.DataTransactionData_DataEntry{ Key: e.Key, @@ -2315,6 +2345,13 @@ type DeleteDataEntry struct { Key string } +func (e DeleteDataEntry) Eq(other DataEntry) bool { + if b, ok := other.(*DeleteDataEntry); ok { + return e.Key == b.Key + } + return false +} + func (e DeleteDataEntry) ToProtobuf() *g.DataTransactionData_DataEntry { return &g.DataTransactionData_DataEntry{ Key: e.Key, diff --git a/pkg/ride/code_samples.go b/pkg/ride/code_samples.go new file mode 100644 index 000000000..e49a59229 --- /dev/null +++ b/pkg/ride/code_samples.go @@ -0,0 +1,35 @@ +package ride + +const fcall1 = ` +func getInt(key: String) = { + match getInteger(this, key) { + case x : Int => x + case _ => 0 + } +} + +let a = getInt("5") +let b = getInt("6") +a == b +` + +const finf = ` +func abc() = { + func in() = { + true + } + in() +} +abc() +` + +const intersectNames = ` +{-# STDLIB_VERSION 3 #-} +{-# SCRIPT_TYPE ACCOUNT #-} +{-# CONTENT_TYPE EXPRESSION #-} +func inc(v: Int) = v + 1 +func call(inc: Int) = { + inc(inc) +} +call(2) == 3 +` diff --git a/pkg/ride/compiler.go b/pkg/ride/compiler.go index 7500f168d..97daf4b71 100644 --- a/pkg/ride/compiler.go +++ b/pkg/ride/compiler.go @@ -1,720 +1,155 @@ package ride -//go:generate go run ./generate - import ( - "bytes" - "encoding/binary" "math" "github.com/pkg/errors" + "go.uber.org/zap" ) -func Compile(tree *Tree) (RideScript, error) { - fCheck, err := selectFunctionChecker(tree.LibVersion) - if err != nil { - return nil, errors.Wrap(err, "compile") - } - cCheck, err := selectConstantsChecker(tree.LibVersion) - if err != nil { - return nil, errors.Wrap(err, "compile") - } - c := &compiler{ - constants: newRideConstants(), - checkFunction: fCheck, - checkConstant: cCheck, - values: make([]rideValue, 0), - functions: make([]*localFunction, 0), - declarations: make([]rideDeclaration, 0), - patcher: newPatcher(), - } - if tree.IsDApp() { - return c.compileDAppScript(tree) - } - return c.compileSimpleScript(tree) -} - -type compiler struct { - constants *rideConstants - checkFunction func(string) (uint16, bool) - checkConstant func(string) (uint16, bool) - values []rideValue - functions []*localFunction - declarations []rideDeclaration - patcher *patcher - callable *rideCallable -} +import ( + "encoding/binary" +) -func (c *compiler) compileSimpleScript(tree *Tree) (*SimpleScript, error) { - bb := new(bytes.Buffer) - err := c.compile(bb, tree.Verifier) - if err != nil { - return nil, err - } - bb.WriteByte(OpHalt) - for _, d := range c.declarations { - pos := bb.Len() - c.patcher.setOrigin(d.buffer(), pos) - bb.Write(patchedCode(d.buffer(), pos)) - bb.WriteByte(OpReturn) - for _, ref := range d.references() { - c.patcher.setPosition(ref, uint16(pos)) - } - } - code := bb.Bytes() - patches, err := c.patcher.get() - if err != nil { - return nil, err - } - for pos, addr := range patches { - binary.BigEndian.PutUint16(code[pos:], addr) - } - return &SimpleScript{ - LibVersion: tree.LibVersion, - EntryPoint: 0, - Code: bb.Bytes(), - Constants: c.constants.items, - }, nil +func encode(v uint16) []byte { + b := make([]byte, 2) + binary.BigEndian.PutUint16(b, v) + return b } -func (c *compiler) compileDAppScript(tree *Tree) (*DAppScript, error) { - // Compile global declarations. - // Each declaration goes to the declaration stack with code compiled in its own buffer. - functions := make(map[string]callable) - bb := new(bytes.Buffer) - for _, node := range tree.Declarations { - err := c.compile(bb, node) - if err != nil { - return nil, err - } - } - for _, n := range tree.Functions { - fn, ok := n.(*FunctionDeclarationNode) - if !ok { - return nil, errors.Errorf("invalid node type %T", n) - } - c.callable = &rideCallable{ - name: fn.Name, - parameter: fn.invocationParameter, - } - err := c.compile(bb, fn) - if err != nil { - return nil, err - } - } - if tree.HasVerifier() { - v, ok := tree.Verifier.(*FunctionDeclarationNode) - if !ok { - return nil, errors.Errorf("invalid node type for DApp's verifier '%T'", tree.Verifier) - } - c.callable = &rideCallable{ - name: "", // Verifier has empty name - parameter: v.invocationParameter, - } - err := c.compile(bb, v) +func compile(f State, node Node) (State, error) { + switch n := node.(type) { + case *AssignmentNode: + state, err := compile(f.Assigment(n.Name), n.Expression) if err != nil { - return nil, err + return state, err } - functions[""] = callable{ - entryPoint: 0, - parameterName: v.invocationParameter, - } - } - // All declarations goes here after verifier and public functions - for _, d := range c.declarations { - pos := bb.Len() - c.patcher.setOrigin(d.buffer(), pos) - bb.Write(patchedCode(d.buffer(), pos)) - if c := d.callable(); c != nil { - bb.WriteByte(OpHalt) - // Add reference to entry point - functions[c.name] = callable{ - entryPoint: pos, - parameterName: c.parameter, + return compile(state.Return(), n.Block) + case *LongNode: + return f.Long(n.Value), nil + case *FunctionCallNode: + var err error + f = f.Call(n.Name, uint16(len(n.Arguments))) + for i := range n.Arguments { + f, err = compile(f, n.Arguments[i]) + if err != nil { + return f, err } - } else { - bb.WriteByte(OpReturn) } - for _, ref := range d.references() { - c.patcher.setPosition(ref, uint16(pos)) - } - } - code := bb.Bytes() - patches, err := c.patcher.get() - if err != nil { - return nil, err - } - for pos, addr := range patches { - binary.BigEndian.PutUint16(code[pos:], addr) - } - return &DAppScript{ - LibVersion: tree.LibVersion, - Code: bb.Bytes(), - Constants: c.constants.items, - EntryPoints: functions, - }, nil -} - -func (c *compiler) compile(bb *bytes.Buffer, node Node) error { - switch n := node.(type) { - case *LongNode: - return c.longNode(bb, n) - case *BytesNode: - return c.bytesNode(bb, n) - case *StringNode: - return c.stringNode(bb, n) + return f.Return(), nil + case *ReferenceNode: + return f.Reference(n.Name), nil case *BooleanNode: - return c.booleanNode(bb, n) + return f.Boolean(n.Value), nil + case *StringNode: + return f.String(n.Value), nil + case *BytesNode: + return f.Bytes(n.Value), nil case *ConditionalNode: - return c.conditionalNode(bb, n) - case *AssignmentNode: - return c.assignmentNode(bb, n) - case *ReferenceNode: - return c.referenceNode(bb, n) - case *FunctionDeclarationNode: - return c.functionDeclarationNode(bb, n) - case *FunctionCallNode: - return c.callNode(bb, n) - case *PropertyNode: - return c.propertyNode(bb, n) - default: - return errors.Errorf("unexpected node type '%T'", node) - } -} - -func (c *compiler) longNode(bb *bytes.Buffer, node *LongNode) error { - cid, err := c.constants.put(rideInt(node.Value)) - if err != nil { - return err - } - bb.WriteByte(OpPush) - bb.Write(encode(cid)) - return nil -} - -func (c *compiler) bytesNode(bb *bytes.Buffer, node *BytesNode) error { - cid, err := c.constants.put(rideBytes(node.Value)) - if err != nil { - return err - } - bb.WriteByte(OpPush) - bb.Write(encode(cid)) - return nil -} - -func (c *compiler) stringNode(bb *bytes.Buffer, node *StringNode) error { - cid, err := c.constants.put(rideString(node.Value)) - if err != nil { - return err - } - bb.WriteByte(OpPush) - bb.Write(encode(cid)) - return nil -} - -func (c *compiler) booleanNode(bb *bytes.Buffer, node *BooleanNode) error { - if node.Value { - bb.WriteByte(OpTrue) - } else { - bb.WriteByte(OpFalse) - } - return nil -} - -func (c *compiler) conditionalNode(bb *bytes.Buffer, node *ConditionalNode) error { - err := c.compile(bb, node.Condition) - if err != nil { - return err - } - bb.WriteByte(OpJumpIfFalse) - otherwise := bb.Len() - bb.Write([]byte{0xff, 0xff}) - - // Truthy branch - bb.WriteByte(OpPop) // Remove condition result from stack - - err = c.compile(bb, node.TrueExpression) - if err != nil { - return err - } - - bb.WriteByte(OpJump) - end := bb.Len() - bb.Write([]byte{0xff, 0xff}) - - // Patch jump to alternative branch - code := bb.Bytes() - binary.BigEndian.PutUint16(code[otherwise:], uint16(bb.Len())) - - // Alternative branch - bb.WriteByte(OpPop) // Remove condition result from stack - err = c.compile(bb, node.FalseExpression) - if err != nil { - return err - } - - // Patch jump to the end of alternative branch - code = bb.Bytes() - binary.BigEndian.PutUint16(code[end:], uint16(bb.Len())) - - return nil -} - -func (c *compiler) assignmentNode(bb *bytes.Buffer, node *AssignmentNode) error { - err := c.pushGlobalValue(node.Name, node.Expression, c.callable) - if err != nil { - return err - } - if node.Block != nil { - err = c.compile(bb, node.Block) - if err != nil { - return err - } - err = c.popValue() + f, err := compile(f.Condition(), n.Condition) if err != nil { - return err + return f, err } - } else { - err = c.peekValue() + f, err = compile(f.TrueBranch(), n.TrueExpression) if err != nil { - return err + return f, err } - } - return nil -} - -func (c *compiler) referenceNode(bb *bytes.Buffer, node *ReferenceNode) error { - if id, ok := c.checkConstant(node.Name); ok { - //Globally declared constant - bb.WriteByte(OpGlobal) - bb.Write(encode(id)) - return nil - } else { - v, err := c.lookupValue(node.Name) + f, err = compile(f.FalseBranch(), n.FalseExpression) if err != nil { - return err - } - switch value := v.(type) { - case *localValue: - bb.WriteByte(OpLoadLocal) - bb.Write(encode(value.position)) - return nil - case *globalValue: - bb.WriteByte(OpLoad) - value.refer(c.patcher.add(bb)) - bb.Write([]byte{0xff, 0xff}) - return nil - default: - return errors.Errorf("unexpected value type '%T'", value) + return f, err } - } -} - -func (c *compiler) functionDeclarationNode(bb *bytes.Buffer, node *FunctionDeclarationNode) error { - var args []string - if c.callable != nil { // DApp callable function - args = make([]string, len(node.Arguments)+1) - args[0] = c.callable.parameter - copy(args[1:], node.Arguments) - } else { - args = node.Arguments - } - err := c.pushFunction(node.Name, args, node.Body, c.callable) - if err != nil { - return err - } - if node.Block != nil { - err = c.compile(bb, node.Block) - if err != nil { - return err - } - err = c.popFunction() - if err != nil { - return err - } - } else { - err = c.peekFunction() - if err != nil { - return err - } - } - return nil -} - -func (c *compiler) callNode(bb *bytes.Buffer, node *FunctionCallNode) error { - for _, arg := range node.Arguments { - err := c.compile(bb, arg) + return f.Return(), nil + case *FunctionDeclarationNode: + state, err := compile(f.Func(n.Name, n.Arguments, n.invocationParameter), n.Body) if err != nil { - return err + return state, err } - } - cnt := encode(uint16(len(node.Arguments))) - - if id, ok := c.checkFunction(node.Name); ok { - //External function - bb.WriteByte(OpExternalCall) - bb.Write(encode(id)) - bb.Write(cnt) - } else { - //Internal function - decl, err := c.lookupFunction(node.Name) + return compile(state.Return(), n.Block) + case *PropertyNode: + f, err := compile(f.Property(n.Name), n.Object) if err != nil { - return err + return f, err } - bb.WriteByte(OpCall) - decl.call(c.patcher.add(bb)) - bb.Write([]byte{0xff, 0xff}) - bb.Write(cnt) - } - return nil -} - -func (c *compiler) propertyNode(bb *bytes.Buffer, node *PropertyNode) error { - err := c.compile(bb, node.Object) - if err != nil { - return err - } - id, err := c.constants.put(rideString(node.Name)) - if err != nil { - return err - } - bb.WriteByte(OpProperty) - bb.Write(encode(id)) - return nil -} - -func (c *compiler) pushGlobalValue(name string, node Node, annex *rideCallable) error { - d := newGlobalValue(name, annex) - c.callable = nil - c.values = append(c.values, d) - err := c.compile(d.bb, node) - if err != nil { - return err - } - return nil -} - -func (c *compiler) popValue() error { - l := len(c.values) - if l == 0 { - return errors.New("failed to pop value from empty stack") - } - var v rideValue - v, c.values = c.values[l-1], c.values[:l-1] - if d, ok := v.(rideDeclaration); ok { - c.declarations = append(c.declarations, d) - } - return nil -} - -func (c *compiler) peekValue() error { - l := len(c.values) - if l == 0 { - return errors.New("failed to peek value from empty stack") - } - v := c.values[l-1] - if d, ok := v.(rideDeclaration); ok { - c.declarations = append(c.declarations, d) + return f.Return(), nil + case nil: + // it should be dapp + return f, nil + default: + return f, errors.Errorf("unknown type %T", node) } - return nil } -func (c *compiler) lookupValue(name string) (rideValue, error) { - for i := len(c.values) - 1; i >= 0; i-- { - if c.values[i].id() == name { - return c.values[i], nil +func CompileVerifier(txID string, tree *Tree) (*Executable, error) { + if tree.IsDApp() { + if tree.HasVerifier() { + _, ok := tree.Verifier.(*FunctionDeclarationNode) + if !ok { + return nil, errors.New("invalid verifier declaration") + } + return compileFunction(txID, tree.LibVersion, append(tree.Declarations, tree.Verifier), tree.IsDApp(), tree.HasVerifier()) } + return nil, errors.New("no verifier declaration") } - return nil, errors.Errorf("value '%s' is not declared", name) + return compileFunction(txID, tree.LibVersion, []Node{tree.Verifier}, tree.IsDApp(), tree.HasVerifier()) } -func (c *compiler) pushFunction(name string, args []string, node Node, annex *rideCallable) error { - d := newLocalFunction(name, args, annex) - c.functions = append(c.functions, d) - for i, a := range args { - c.values = append(c.values, newLocalValue(a, i)) - } - c.callable = nil - err := c.compile(d.bb, node) - if err != nil { - return err - } - for range args { - err := c.popValue() - if err != nil { - return err +func CompileDapp(txID string, tree *Tree) (out *Executable, err error) { + defer func() { + if r := recover(); r != nil { + zap.S().Error(DecompileTree(tree), " ", r) + err = errors.New("failed to compile") } + }() + if !tree.IsDApp() { + return nil, errors.Errorf("unable to compile dappp") } - return nil -} - -func (c *compiler) popFunction() error { - l := len(c.functions) - if l == 0 { - return errors.New("failed to pop function from empty stack") + fns := tree.Functions + if tree.HasVerifier() { + fns = append(fns, tree.Verifier) } - var f *localFunction - f, c.functions = c.functions[l-1], c.functions[:l-1] - c.declarations = append(c.declarations, f) - return nil + return compileFunction(txID, tree.LibVersion, append(tree.Declarations, fns...), true, tree.HasVerifier()) } -func (c *compiler) peekFunction() error { - l := len(c.functions) - if l == 0 { - return errors.New("failed to peek function from empty stack") +func compileFunction(txID string, libVersion int, nodes []Node, isDapp bool, hasVerifier bool) (*Executable, error) { + fCheck, err := selectFunctionChecker(libVersion) + if err != nil { + return nil, err } - f := c.functions[l-1] - c.declarations = append(c.declarations, f) - return nil -} + u := &uniqid{} + b := newBuilder() + r := newReferences(nil) + c := newCell() + b.writeByte(OpReturn) -func (c *compiler) lookupFunction(name string) (*localFunction, error) { - for i := len(c.functions) - 1; i >= 0; i-- { - if c.functions[i].name == name { - return c.functions[i], nil - } + params := params{ + b: b, + r: r, + f: fCheck, + u: u, + c: c, + txID: txID, } - return nil, errors.Errorf("function '%s' is not declared", name) -} - -type rideCallable struct { - name string - parameter string -} - -type rideConstants struct { - items []rideType - strings map[string]uint16 -} - -func newRideConstants() *rideConstants { - return &rideConstants{ - items: make([]rideType, 0, 4), - strings: make(map[string]uint16, 4), + for k, v := range predefinedFunctions { + params.addPredefined(v.name, uint16(math.MaxUint16-k), uint16(math.MaxUint16-k)) } -} -func (c *rideConstants) put(value rideType) (uint16, error) { - switch v := value.(type) { - case rideString: - s := string(v) - if pos, ok := c.strings[s]; ok { - return pos, nil - } - pos, err := c.append(value) - if err != nil { - return 0, err - } - c.strings[s] = pos - return pos, nil - default: - pos, err := c.append(value) + f := NewMain(params) + for _, node := range nodes { + f, err = compile(f, node) if err != nil { - return 0, err - } - return pos, nil - } -} - -func (c *rideConstants) append(value rideType) (uint16, error) { - if len(c.items) >= math.MaxUint16 { - return 0, errors.New("max number of constants reached") - } - c.items = append(c.items, value) - return uint16(len(c.items) - 1), nil -} - -type rideDeclaration interface { - buffer() *bytes.Buffer - references() []int - callable() *rideCallable -} - -type rideValue interface { - id() string -} - -type localValue struct { - name string - position uint16 -} - -func newLocalValue(name string, pos int) *localValue { - return &localValue{ - name: name, - position: uint16(pos), - } -} - -func (v *localValue) id() string { - return v.name -} - -type globalValue struct { - name string - annex *rideCallable - bb *bytes.Buffer - usages []int - using []*globalValue -} - -func newGlobalValue(name string, annex *rideCallable) *globalValue { - return &globalValue{ - name: name, - annex: annex, - bb: new(bytes.Buffer), - usages: make([]int, 0), - using: make([]*globalValue, 0), - } -} - -func (v *globalValue) buffer() *bytes.Buffer { - return v.bb -} - -func (v *globalValue) references() []int { - return v.usages -} - -func (v *globalValue) id() string { - return v.name -} - -func (v *globalValue) refer(patch int) { - v.usages = append(v.usages, patch) -} - -func (v *globalValue) callable() *rideCallable { - return v.annex -} - -type localFunction struct { - name string - annex *rideCallable - bb *bytes.Buffer - calls []int - args []string -} - -func newLocalFunction(name string, args []string, annex *rideCallable) *localFunction { - return &localFunction{ - name: name, - annex: annex, - bb: new(bytes.Buffer), - calls: make([]int, 0), - args: args, - } -} - -func (f *localFunction) buffer() *bytes.Buffer { - return f.bb -} - -func (f *localFunction) references() []int { - return f.calls -} - -func (f *localFunction) call(pos int) { - f.calls = append(f.calls, pos) -} - -func (f *localFunction) callable() *rideCallable { - return f.annex -} - -type patch struct { - id int - origin int - pos int - addr uint16 -} - -type patcher struct { - count int - buffers map[*bytes.Buffer][]patch -} - -func newPatcher() *patcher { - return &patcher{ - count: 0, - buffers: make(map[*bytes.Buffer][]patch), - } -} - -func (p *patcher) add(bb *bytes.Buffer) int { - pt := patch{ - id: p.count, - pos: bb.Len(), - } - if bps, ok := p.buffers[bb]; ok { - p.buffers[bb] = append(bps, pt) - } else { - p.buffers[bb] = []patch{pt} - } - p.count++ - return pt.id -} - -func (p *patcher) setOrigin(bb *bytes.Buffer, origin int) { - if ps, ok := p.buffers[bb]; ok { - for i := range ps { - ps[i].origin = origin - } - } -} - -func (p *patcher) setPosition(id int, addr uint16) { - for _, v := range p.buffers { - for i := range v { - if v[i].id == id { - v[i].addr = addr - } + return nil, err } } -} + // Just to write `OpReturn` to bytecode. + f = f.Return() -func (p *patcher) get() (map[int]uint16, error) { - r := make(map[int]uint16) - for _, v := range p.buffers { - for i := range v { - abs := v[i].origin + v[i].pos - if _, ok := r[abs]; ok { - return nil, errors.Errorf("duplicate patch at position %d", abs) - } - r[abs] = v[i].addr - } - } - return r, nil + return f.(BuildExecutable).BuildExecutable(libVersion, isDapp, hasVerifier), nil } -func encode(v uint16) []byte { - b := make([]byte, 2) - binary.BigEndian.PutUint16(b, v) - return b -} - -func patchedCode(bb *bytes.Buffer, origin int) []byte { - bts := bb.Bytes() - i := 0 - for i < bb.Len() { - switch bts[i] { - case OpJumpIfFalse, OpJump: - addr := bts[i+1 : i+3] - update(addr, origin) - i += 3 - case OpPush, OpProperty, OpLoad, OpLoadLocal, OpGlobal: - i += 3 - case OpCall, OpExternalCall: - i += 5 - default: - i++ - } +func CompileTree(tx string, tree *Tree) (*Executable, error) { + tree = MustExpand(tree) + if tree.IsDApp() { + return CompileDapp(tx, tree) } - return bts -} - -func update(b []byte, n int) { - v := binary.BigEndian.Uint16(b) - binary.BigEndian.PutUint16(b, uint16(int(v)+n)) + return CompileVerifier(tx, tree) } diff --git a/pkg/ride/compiler_assigment.go b/pkg/ride/compiler_assigment.go new file mode 100644 index 000000000..132e6da60 --- /dev/null +++ b/pkg/ride/compiler_assigment.go @@ -0,0 +1,115 @@ +package ride + +import "fmt" + +// Assigment: let x = 5 +type AssigmentState struct { + params + bodyParams params + prev State + name string + n uniqueid + body Deferred + d Deferreds +} + +func (a AssigmentState) backward(state State) State { + a.body = state.(Deferred) + return a +} + +func (a AssigmentState) Property(name string) State { + return propertyTransition(a, a.bodyParams, name, a.d) +} + +func (a AssigmentState) Func(name string, args []string, invoke string) State { + return funcTransition(a, a.bodyParams, name, args, invoke) +} + +func (a AssigmentState) Bytes(b []byte) State { + a.body = a.constant(rideBytes(b)) + return a +} + +func (a AssigmentState) Condition() State { + return conditionalTransition(a, a.bodyParams, a.d) +} + +func (a AssigmentState) TrueBranch() State { + panic("Illegal call `TrueBranch` on AssigmentState") +} + +func (a AssigmentState) FalseBranch() State { + panic("Illegal call `FalseBranch` on AssigmentState") +} + +func (a AssigmentState) String(s string) State { + a.body = a.constant(rideString(s)) + return a +} + +func (a AssigmentState) Boolean(v bool) State { + a.body = a.constant(rideBoolean(v)) + return a +} + +func assigmentTransition(prev State, params params, name string, n uniqueid, d Deferreds) State { + return newAssigment(prev, params, name, n, d) +} + +func extendParams(p params) params { + p.r = newReferences(p.r) + return p +} + +func newAssigment(prev State, p params, name string, n uniqueid, d Deferreds) State { + return AssigmentState{ + prev: prev, + params: p, + bodyParams: extendParams(p), + name: name, + n: n, + d: d, + } +} + +// Create new scope, so assigment in assigment can't affect global state. +func (a AssigmentState) Assigment(name string) State { + n := a.params.u.next() + return assigmentTransition(a, a.bodyParams, name, n, a.d) +} + +func (a AssigmentState) Return() State { + a.r.setAssigment(a.name, a.n) + a.d.Add(a, a.n, fmt.Sprintf("ref %s", a.name)) + return a.prev +} + +func (a AssigmentState) Long(value int64) State { + a.body = a.constant(rideInt(value)) + return a +} + +func (a AssigmentState) Call(name string, argc uint16) State { + return callTransition(a, a.bodyParams, name, argc, a.d) +} + +func (a AssigmentState) Reference(name string) State { + a.body = reference(a, a.bodyParams, name) + return a +} + +func (a AssigmentState) Write(_ params, _ []byte) { + if a.body == nil { + panic("no body for assigment") + } + a.body.Write(a.params, nil) + a.b.writeByte(OpCache) + a.b.write(encode(a.n)) + a.b.ret() +} + +func (a AssigmentState) Clean() { + a.b.writeByte(OpClearCache) + a.b.write(encode(a.n)) +} diff --git a/pkg/ride/compiler_call_system.go b/pkg/ride/compiler_call_system.go new file mode 100644 index 000000000..1b66691c8 --- /dev/null +++ b/pkg/ride/compiler_call_system.go @@ -0,0 +1,141 @@ +package ride + +import "fmt" + +// Function call +type CallSystemState struct { + prev State + params + name string + argc uint16 + deferred []Deferred + deferreds Deferreds + // Sequential function arguments. + ns []uniqueid +} + +func (a CallSystemState) backward(state State) State { + a.deferred = append(a.deferred, state.(Deferred)) + return a +} + +func (a CallSystemState) Property(name string) State { + return propertyTransition(a, a.params, name, a.deferreds) +} + +func (a CallSystemState) Func(name string, args []string, invoke string) State { + return funcTransition(a, a.params, name, args, invoke) +} + +func (a CallSystemState) Bytes(value []byte) State { + a.deferred = append(a.deferred, a.constant(rideBytes(value))) + return a +} + +func (a CallSystemState) Condition() State { + return conditionalTransition(a, a.params, a.deferreds) +} + +func (a CallSystemState) TrueBranch() State { + panic("Illegal call `TrueBranch` on CallSystemState") +} + +func (a CallSystemState) FalseBranch() State { + panic("Illegal call `FalseBranch` on CallSystemState") +} + +func (a CallSystemState) String(value string) State { + a.deferred = append(a.deferred, a.constant(rideString(value))) + return a +} + +func (a CallSystemState) Boolean(value bool) State { + a.deferred = append(a.deferred, a.constant(rideBoolean(value))) + return a +} + +func callTransition(prev State, params params, name string, argc uint16, d Deferreds) State { + if _, ok := params.r.getFunc(name); ok { + return newCallUserState(prev, params, name, argc, d) + } + return newCallSystemState(prev, params, name, argc, d) +} + +func newCallSystemState(prev State, params params, name string, argc uint16, d Deferreds) State { + var ns []uniqueid + for i := uint16(0); i < argc; i++ { + ns = append(ns, params.u.next()) + } + + return &CallSystemState{ + prev: prev, + params: params, + name: name, + argc: argc, + deferreds: d, + ns: ns, + } +} + +func (a CallSystemState) Assigment(name string) State { + n := a.params.u.next() + return assigmentTransition(a, a.params, name, n, a.deferreds) +} + +func (a CallSystemState) Long(value int64) State { + a.deferred = append(a.deferred, a.constant(rideInt(value))) + return a +} + +func (a CallSystemState) Return() State { + + if len(a.ns) != len(a.deferred) { + panic(fmt.Sprintf("ns %d != a.deferred %d", a.argc, len(a.deferred))) + } + + for i, b := range a.deferred { + if _, ok := isConstant(b); ok { + // skip right now + } else { + a.deferreds.Add(b, a.ns[i], fmt.Sprintf("sys %s param #%d", a.name, i)) + } + } + + return a.prev.backward(a) +} + +func (a CallSystemState) Call(name string, argc uint16) State { + return callTransition(a, a.params, name, argc, a.deferreds) +} + +func (a CallSystemState) Reference(name string) State { + a.deferred = append(a.deferred, reference(a, a.params, name)) + return a +} + +func (a CallSystemState) Clean() { + +} + +func (a CallSystemState) Write(_ params, _ []byte) { + if int(a.argc) != len(a.deferred) { + panic(fmt.Sprintf("argc %d != a.deferred %d", a.argc, len(a.deferred))) + } + + for i := range a.ns { + if n, ok := isConstant(a.deferred[i]); ok { + a.b.writeByte(OpRef) + a.b.write(encode(n)) + } else { + n := a.ns[i] + a.b.writeByte(OpRef) + a.b.write(encode(n)) + } + } + + n, ok := a.f(a.name) + if !ok { + panic(fmt.Sprintf("%s system function named `%s` not found", a.params.txID, a.name)) + } + a.b.externalCall(n, a.argc) +} diff --git a/pkg/ride/compiler_call_user.go b/pkg/ride/compiler_call_user.go new file mode 100644 index 000000000..a95647c11 --- /dev/null +++ b/pkg/ride/compiler_call_user.go @@ -0,0 +1,115 @@ +package ride + +import "fmt" + +// Function call +type CallUserState struct { + prev State + params + name string + argc uint16 + deferreds Deferreds + ns []uniqueid +} + +func (a CallUserState) backward(state State) State { + num := len(a.ns) + n := a.params.u.next() + a.ns = append(a.ns, n) + a.deferreds.Add(state.(Deferred), n, fmt.Sprintf("call user %s backward #%d", a.name, num)) + return a +} + +func newCallUserState(prev State, params params, name string, argc uint16, d Deferreds) State { + return &CallUserState{ + prev: prev, + params: params, + name: name, + argc: argc, + deferreds: d, + } +} + +func (a CallUserState) Property(name string) State { + return propertyTransition(a, a.params, name, a.deferreds) +} + +func (a CallUserState) Func(name string, args []string, invoke string) State { + return funcTransition(a, a.params, name, args, invoke) +} + +func (a CallUserState) Bytes(b []byte) State { + cons := a.constant(rideBytes(b)) + a.ns = append(a.ns, cons.n) + return a +} + +func (a CallUserState) Condition() State { + return conditionalTransition(a, a.params, a.deferreds) +} + +func (a CallUserState) TrueBranch() State { + panic("Illegal call `TrueBranch` on CallUserState") +} + +func (a CallUserState) FalseBranch() State { + panic("Illegal call `FalseBranch` on CallUserState") +} + +func (a CallUserState) String(s string) State { + cons := a.constant(rideString(s)) + a.ns = append(a.ns, cons.n) + return a +} + +func (a CallUserState) Boolean(v bool) State { + cons := a.constant(rideBoolean(v)) + a.ns = append(a.ns, cons.n) + return a +} + +func (a CallUserState) Assigment(string) State { + panic("CallUserState Assigment") +} + +func (a CallUserState) Long(value int64) State { + cons := a.constant(rideInt(value)) + a.ns = append(a.ns, cons.n) + return a +} + +func (a CallUserState) Return() State { + return a.prev.backward(a) +} + +func (a CallUserState) Call(name string, argc uint16) State { + return callTransition(a, a.params, name, argc, a.deferreds) +} + +func (a CallUserState) Reference(name string) State { + cons := reference(a, a.params, name) + a.ns = append(a.ns, cons.n) + return a +} + +func (a CallUserState) Clean() { + +} + +func (a CallUserState) Write(_ params, b []byte) { + // check user functions + fn, ok := a.r.getFunc(a.name) + if !ok { + panic(fmt.Sprintf("user function `%s` not found", a.name)) + } + if int(a.argc) != len(a.ns) { + panic(fmt.Sprintf("argc %d != a.ns %d", a.argc, len(a.ns))) + } + for _, n := range a.ns { + a.b.writeByte(OpRef) + a.b.write(encode(n)) + } + a.b.writeByte(OpRef) + a.b.write(encode(fn)) + a.b.write(b) +} diff --git a/pkg/ride/compiler_conditional.go b/pkg/ride/compiler_conditional.go new file mode 100644 index 000000000..7d44d02b1 --- /dev/null +++ b/pkg/ride/compiler_conditional.go @@ -0,0 +1,144 @@ +package ride + +import "fmt" + +// If-else statement. +type ConditionalState struct { + /* + Be aware that `x` and `y` should not be executed. + + if (true) then { + let x = throw() + 5 + } else { + let y = throw() + 6 + } + */ + + originalParams params + params + prev State + + rets []uint16 + + // Clean assigments after exit. + deferred []Deferred + deferreds Deferreds + + condN uniqueid +} + +func (a ConditionalState) backward(as State) State { + // Func in func. + if f, ok := as.(FuncState); ok { + a.deferreds.Add(as.(Deferred), f.n, fmt.Sprintf("func `%s`in conditional", f.name)) + } else { + a.deferred = append(a.deferred, as.(Deferred)) + } + return a +} + +func (a ConditionalState) Property(name string) State { + return propertyTransition(a, a.params, name, a.deferreds) +} + +func (a ConditionalState) Func(name string, args []string, invoke string) State { + return funcTransition(a, a.params, name, args, invoke) +} + +func (a ConditionalState) Bytes(value []byte) State { + a.deferred = append(a.deferred, a.constant(rideBytes(value))) + return a +} + +func conditionalTransition(prev State, params params, deferreds Deferreds) State { + return ConditionalState{ + prev: prev, + params: extendParams(params), + deferreds: deferreds, + originalParams: params, + } +} + +func (a ConditionalState) Condition() State { + a.rets = append(a.rets, a.params.b.len()) + return conditionalTransition(a, a.params, a.deferreds) +} + +func (a ConditionalState) TrueBranch() State { + a.params = extendParams(a.originalParams) + return a +} + +func (a ConditionalState) FalseBranch() State { + a.params = extendParams(a.originalParams) + return a +} + +func (a ConditionalState) Assigment(name string) State { + n := a.params.u.next() + return assigmentTransition(a, a.params, name, n, a.deferreds) +} + +func (a ConditionalState) Long(value int64) State { + a.deferred = append(a.deferred, a.constant(rideInt(value))) + return a +} + +func (a ConditionalState) Call(name string, argc uint16) State { + return callTransition(a, a.params, name, argc, a.deferreds) +} + +func (a ConditionalState) Reference(name string) State { + a.deferred = append(a.deferred, reference(a, a.params, name)) + return a +} + +func (a ConditionalState) Boolean(value bool) State { + a.deferred = append(a.deferred, a.constant(rideBoolean(value))) + return a +} + +func (a ConditionalState) String(value string) State { + a.deferred = append(a.deferred, a.constant(rideString(value))) + return a +} + +func (a ConditionalState) Return() State { + if len(a.deferred) < 3 { + panic("len(a.deferred) < 3") + } + a.condN = a.u.next() + a.deferreds.Add(a.deferred[0], a.condN, "condition cond") + return a.prev.backward(a) +} + +func (a ConditionalState) Write(_ params, _ []byte) { + if len(a.deferred) != 3 { + panic("len(a.deferred) != 3") + } + + trueB := a.deferred[1] + falsB := a.deferred[2] + + a.b.writeByte(OpRef) + a.b.write(encode(a.condN)) + + a.b.jpmIfFalse() + patchTruePosition := a.b.writeStub(2) + patchFalsePosition := a.b.writeStub(2) + patchNextPosition := a.b.writeStub(2) + + a.b.patch(patchTruePosition, encode(a.b.len())) + trueB.Write(a.params, nil) + a.b.ret() + + a.b.patch(patchFalsePosition, encode(a.b.len())) + falsB.Write(a.params, nil) + a.b.ret() + + a.b.patch(patchNextPosition, encode(a.b.len())) +} +func (a ConditionalState) Clean() { +} diff --git a/pkg/ride/compiler_func.go b/pkg/ride/compiler_func.go new file mode 100644 index 000000000..7c7814cea --- /dev/null +++ b/pkg/ride/compiler_func.go @@ -0,0 +1,186 @@ +package ride + +import "fmt" + +type arguments []string + +type Deferreds interface { + Add(Deferred, uniqueid, string) +} + +type dd struct { + deferred Deferred + uniq uniqueid + debug string +} + +type deferreds struct { + name string + d []dd +} + +func (a *deferreds) Add(deferred2 Deferred, n uniqueid, debug string) { + a.d = append(a.d, dd{ + deferred: deferred2, + uniq: n, + debug: debug, + }) +} + +func (a *deferreds) Get() []dd { + return a.d +} + +type FuncState struct { + params + prev State + name string + args arguments + n uniqueid + invokeParam string + paramIds []uniqueid + + // References that defined inside function. + deferred []Deferred + defers *deferreds + argn int +} + +func (a FuncState) backward(as State) State { + // Func in func. + if f, ok := as.(FuncState); ok { + a.defers.Add(as.(Deferred), f.n, fmt.Sprintf("func `%s`in func %s", f.name, a.name)) + } else { + a.deferred = append(a.deferred, as.(Deferred)) + } + return a +} + +func (a FuncState) Property(name string) State { + return propertyTransition(a, a.params, name, a.defers) +} + +func funcTransition(prev State, params params, name string, args []string, invokeParam string) State { + argn := len(args) + n := params.u.next() + params.r.setFunc(name, n) + // All variable we add only visible to current scope, + // avoid corrupting global scope. + params.r = newReferences(params.r) + + // Function call: verifier or not. + if invokeParam != "" { + args = append([]string{invokeParam}, args...) + } + paramIds := make([]uniqueid, 0, len(args)) + for i := range args { + e := params.u.next() + paramIds = append(paramIds, e) + params.r.setAssigment(args[i], e) + } + + return &FuncState{ + prev: prev, + name: name, + args: args, + params: params, + n: n, + invokeParam: invokeParam, + defers: &deferreds{ + name: "func " + name, + }, + paramIds: paramIds, + argn: argn, + } +} + +func (a FuncState) Assigment(name string) State { + n := a.params.u.next() + return assigmentTransition(a, a.params, name, n, a.defers) +} + +func (a FuncState) ParamIds() []uniqueid { + return a.paramIds +} + +func (a FuncState) Return() State { + return a.prev.backward(a) +} + +func (a FuncState) Long(value int64) State { + a.deferred = append(a.deferred, a.constant(rideInt(value))) + return a +} + +func (a FuncState) Call(name string, argc uint16) State { + return callTransition(a, a.params, name, argc, a.defers) +} + +func (a FuncState) Reference(name string) State { + a.deferred = append(a.deferred, reference(a, a.params, name)) + return a +} + +func (a FuncState) Boolean(value bool) State { + a.deferred = append(a.deferred, a.constant(rideBoolean(value))) + return a +} + +func (a FuncState) String(value string) State { + a.deferred = append(a.deferred, a.constant(rideString(value))) + return a +} + +func (a FuncState) Condition() State { + return conditionalTransition(a, a.params, a.defers) +} + +func (a FuncState) TrueBranch() State { + panic("Illegal call `TrueBranch` on `FuncState`") +} + +func (a FuncState) FalseBranch() State { + panic("Illegal call `FalseBranch` on `FuncState`") +} + +func (a FuncState) Bytes(value []byte) State { + a.deferred = append(a.deferred, a.constant(rideBytes(value))) + return a +} + +func (a FuncState) Func(name string, args []string, invoke string) State { + return funcTransition(a, a.params, name, args, invoke) +} + +func (a FuncState) Clean() { + +} + +func (a FuncState) Write(_ params, _ []byte) { + pos := a.b.len() + a.params.c.set(a.n, nil, 0, pos, false, fmt.Sprintf("function %s", a.name)) + if len(a.deferred) != 1 { + panic("len(a.deferred) != 1") + } + // Assign function arguments from stack. + for i := len(a.paramIds) - 1; i >= 0; i-- { + a.b.writeByte(OpCache) + a.b.write(encode(a.paramIds[i])) + a.b.writeByte(OpPop) + } + a.deferred[0].Write(a.params, nil) + + // End of function body. Clear and write assigments. + for _, v := range a.defers.Get() { + v.deferred.Clean() + } + a.b.ret() + + for _, v := range a.defers.Get() { + pos := a.b.len() + a.c.set(v.uniq, nil, 0, pos, false, v.debug) + v.deferred.Write(a.params, nil) + a.b.ret() + } + +} diff --git a/pkg/ride/compiler_helpers.go b/pkg/ride/compiler_helpers.go new file mode 100644 index 000000000..3c2820612 --- /dev/null +++ b/pkg/ride/compiler_helpers.go @@ -0,0 +1,306 @@ +package ride + +import "bytes" + +type constid = uint16 + +type Refs map[uint16]point + +type Entrypoint struct { + name string + at uint16 + argn uint16 +} + +func (a Entrypoint) Serialize(s Serializer) error { + err := s.String(a.name) + if err != nil { + return err + } + s.Uint16(a.at) + s.Uint16(a.argn) + return nil +} + +func deserializeEntrypoint(d *Deserializer) (Entrypoint, error) { + var err error + a := Entrypoint{} + a.name, err = d.String() + if err != nil { + return a, err + } + a.at, err = d.Uint16() + if err != nil { + return a, err + } + a.argn, err = d.Uint16() + if err != nil { + return a, err + } + return a, nil +} + +type builder struct { + w *bytes.Buffer + entrypoints map[string]Entrypoint +} + +func newBuilder() *builder { + return &builder{ + w: new(bytes.Buffer), + entrypoints: make(map[string]Entrypoint), + } +} + +func (b *builder) writeStub(len int) (position uint16) { + position = uint16(b.w.Len()) + for i := 0; i < len; i++ { + b.w.WriteByte(0) + } + return position +} + +func (b *builder) setStart(name string, argn int) { + b.entrypoints[name] = Entrypoint{ + name: name, + at: b.len(), + argn: uint16(argn), + } +} + +func (b *builder) bool(v bool) { + if v { + b.w.WriteByte(OpTrue) + } else { + b.w.WriteByte(OpFalse) + } +} + +func (b *builder) bytes() []byte { + return b.w.Bytes() +} + +func (b *builder) ret() { + b.w.WriteByte(OpReturn) +} + +func (b *builder) patch(at uint16, val []byte) { + bts := b.w.Bytes()[at:] + copy(bts, val) +} + +func (b *builder) len() uint16 { + return uint16(b.w.Len()) +} + +func (b *builder) externalCall(id uint16, argc uint16) { + b.w.WriteByte(OpExternalCall) + b.w.Write(encode(id)) + b.w.Write(encode(argc)) +} + +func (b *builder) build() (map[string]Entrypoint, []byte) { + return b.entrypoints, b.w.Bytes() +} + +func (b *builder) jpmIfFalse() { + b.w.WriteByte(OpJumpIfFalse) +} + +func (b *builder) writeByte(p byte) { + b.w.WriteByte(p) +} + +func (b *builder) write(i []byte) { + b.w.Write(i) +} + +type point struct { + position uint16 + value rideType + fn uint16 + debugInfo string +} + +func (a point) Serialize(s Serializer) error { + s.Uint16(a.position) + if a.value != nil { + err := a.value.Serialize(s) + if err != nil { + return err + } + } else { + err := s.RideNoValue() + if err != nil { + return err + } + } + + s.Uint16(a.fn) + _ = s.String(a.debugInfo) + return nil +} + +func (a point) constant() bool { + return a.position == 0 && a.fn == 0 +} + +func deserializePoint(d *Deserializer) (point, error) { + var a point + var err error + a.position, err = d.Uint16() + if err != nil { + return a, err + } + a.value, err = d.RideValue() + if err != nil { + return a, err + } + a.fn, err = d.Uint16() + if err != nil { + return a, err + } + a.debugInfo, err = d.String() + if err != nil { + return a, err + } + return a, nil +} + +type cell struct { + values map[uniqueid]point +} + +func newCell() *cell { + return &cell{ + values: make(map[uniqueid]point), + } +} + +func (a *cell) set(u uniqueid, result rideType, fn uint16, position uint16, constant bool, debug string) { + a.values[u] = point{ + position: position, + value: result, + fn: fn, + debugInfo: debug, + } +} + +type uniqueid = uint16 + +type refKind struct { + assigment bool + n uniqueid +} + +type references struct { + prev *references + refs map[string][]refKind +} + +func newReferences(prev *references) *references { + return &references{ + prev: prev, + refs: make(map[string][]refKind), + } +} + +func (a *references) setAssigment(name string, uniq uniqueid) { + a.refs[name] = append([]refKind{refKind{assigment: true, n: uniq}}, a.refs[name]...) +} + +func (a *references) setFunc(name string, uniq uniqueid) { + a.refs[name] = append([]refKind{refKind{assigment: false, n: uniq}}, a.refs[name]...) +} + +func (a *references) getFunc(name string) (uniqueid, bool) { + return a.get(name, false) +} + +func (a *references) getAssigment(name string) (uniqueid, bool) { + return a.get(name, true) +} + +func (a *references) get(name string, assigment bool) (uniqueid, bool) { + if a == nil { + return 0, false + } + if offset, ok := a.refs[name]; ok { + for _, v := range offset { + if v.assigment == assigment { + return v.n, true + } + } + return a.prev.get(name, assigment) + } + return a.prev.get(name, assigment) +} + +type predefFunc struct { + name string + f rideFunction +} + +type pfunc struct { + name string + f rideFunction + id uint16 +} + +type predef struct { + prev *predef + m map[string]pfunc +} + +func newPredef(prev *predef) *predef { + return &predef{ + prev: prev, + m: make(map[string]pfunc), + } +} + +func (a *predef) set(name string, id uint16, f rideFunction) { + a.m[name] = pfunc{ + name: name, + id: id, + f: f, + } +} + +func (a *predef) getn(id int) rideFunction { + if a == nil { + return nil + } + for _, v := range a.m { + if v.id == uint16(id) { + return v.f + } + } + return a.prev.getn(id) +} + +type Deferred interface { + Write + Clean +} + +type constantDeferred struct { + n uniqueid +} + +func (a constantDeferred) Write(p params, _ []byte) { + p.b.writeByte(OpRef) + p.b.write(encode(a.n)) +} + +func (a constantDeferred) Clean() { +} + +func NewConstantDeferred(n uniqueid) constantDeferred { + return constantDeferred{n: n} +} + +func isConstant(deferred Deferred) (uniqueid, bool) { + v, ok := deferred.(constantDeferred) + return v.n, ok +} diff --git a/pkg/ride/compiler_helpers_test.go b/pkg/ride/compiler_helpers_test.go new file mode 100644 index 000000000..d71f3756b --- /dev/null +++ b/pkg/ride/compiler_helpers_test.go @@ -0,0 +1,21 @@ +package ride + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +// Check that patches correctly. +func TestBuilderPatch(t *testing.T) { + b := newBuilder() + + b.bool(true) + patchStart := b.writeStub(2) + b.bool(true) + + b.patch(patchStart, []byte{0xff, 0xff}) + + require.Equal(t, b.bytes(), []byte{OpTrue, 0xff, 0xff, OpTrue}) + +} diff --git a/pkg/ride/compiler_main.go b/pkg/ride/compiler_main.go new file mode 100644 index 000000000..cd93d4dee --- /dev/null +++ b/pkg/ride/compiler_main.go @@ -0,0 +1,135 @@ +package ride + +// Initial state, contains only assigments and last expression. +type MainState struct { + params + + body []Deferred + deferreds *deferreds +} + +func (a MainState) backward(state State) State { + a.body = append(a.body, state.(Deferred)) + return a +} + +func (a MainState) Property(name string) State { + return propertyTransition(a, a.params, name, a.deferreds) +} + +func (a MainState) Func(name string, args []string, invoke string) State { + return funcTransition(a, a.params, name, args, invoke) +} + +func (a MainState) Bytes([]byte) State { + panic("Illegal call `Bytes` on `MainState`") +} + +func (a MainState) Condition() State { + return conditionalTransition(a, a.params, a.deferreds) +} + +func (a MainState) TrueBranch() State { + panic("Illegal call `TrueBranch` on MainState") +} + +func (a MainState) FalseBranch() State { + panic("Illegal call `FalseBranch` on MainState") +} + +func (a MainState) String(string) State { + panic("Illegal call `String` on MainState") +} + +type BuildExecutable interface { + BuildExecutable(version int, isDapp bool, hasVerifier bool) *Executable +} + +func NewMain(params params) State { + return &MainState{ + params: params, + deferreds: &deferreds{ + name: "main", + }, + } +} + +func (a MainState) Assigment(name string) State { + n := a.params.u.next() + return assigmentTransition(a, a.params, name, n, a.deferreds) +} + +func (a MainState) Return() State { + for _, v := range a.deferreds.Get() { + v.deferred.Clean() + } + a.b.ret() + + body := a.body + // empty script, example https://testnet.wavesexplorer.com/tx/DprupHKCwJwRhyhbHyqJqp35CvhiJdpkhjf53z1vmwHr + if len(body) == 0 { + return a + } + for { + if f, ok := body[0].(FuncState); ok && f.invokeParam != "" { + a.b.setStart(f.name, f.argn) + a.b.setStart("", 0) + } else { + a.b.setStart("", 0) + } + + body[0].Write(a.params, nil) + a.b.ret() + body = body[1:] + if len(body) == 0 { + break + } + } + a.b.ret() + + for _, v := range a.deferreds.Get() { + pos := a.b.len() + a.c.set(v.uniq, nil, 0, pos, false, v.debug) + v.deferred.Write(a.params, nil) + a.b.ret() + } + return a +} + +func (a MainState) Long(int64) State { + panic("Illegal call Long on MainState") +} + +func (a MainState) Call(name string, argc uint16) State { + return callTransition(a, a.params, name, argc, a.deferreds) +} + +func (a MainState) Reference(name string) State { + a.body = append(a.body, reference(a, a.params, name)) + return a +} + +func (a MainState) Boolean(v bool) State { + a.body = append(a.body, a.constant(rideBoolean(v))) + return a +} + +func (a MainState) BuildExecutable(version int, isDapp bool, hasVerifier bool) *Executable { + entrypoints, code := a.b.build() + return &Executable{ + LibVersion: version, + ByteCode: code, + References: a.c.values, + EntryPoints: entrypoints, + IsDapp: isDapp, + hasVerifier: hasVerifier, + } +} + +func (a MainState) Write(_ params, _ []byte) { + +} + +func (a MainState) Clean() { + +} diff --git a/pkg/ride/compiler_property.go b/pkg/ride/compiler_property.go new file mode 100644 index 000000000..1a0e4fc9c --- /dev/null +++ b/pkg/ride/compiler_property.go @@ -0,0 +1,105 @@ +package ride + +import "fmt" + +type PropertyState struct { + prev State + name string + params + body Deferred + deferreds Deferreds + n uniqueid +} + +func (a PropertyState) backward(as State) State { + a.body = as + return a +} + +func propertyTransition(prev State, params params, name string, d Deferreds) State { + return &PropertyState{ + params: params, + prev: prev, + name: name, + deferreds: d, + } +} + +func (a PropertyState) Assigment(string) State { + panic("Illegal call `Assigment` on PropertyState") +} + +func (a PropertyState) Return() State { + // 2 possible variations: + // 1) tx.id => body is reference + // 2) tx.sellOrder.assetPair => body is another property + a.n = a.params.u.next() + if n, ok := isConstant(a.body); ok { // body is reference + a.n = n + } else { // body is another property + a.n = a.u.next() + a.deferreds.Add(a.body, a.n, fmt.Sprintf("property== `%s`", a.name)) + } + return a.prev.backward(a) +} + +func (a PropertyState) Long(int64) State { + panic("Illegal call `Long` on PropertyState") +} + +func (a PropertyState) Call(name string, argc uint16) State { + return callTransition(a, a.params, name, argc, a.deferreds) +} + +func (a PropertyState) Reference(name string) State { + a.body = reference(a, a.params, name) + return a +} + +func (a PropertyState) Boolean(bool) State { + panic("Illegal call `Boolean` on PropertyState") +} + +func (a PropertyState) String(string) State { + panic("Illegal call `String` on PropertyState") +} + +func (a PropertyState) Condition() State { + panic("Illegal call `Condition` on PropertyState") +} + +func (a PropertyState) TrueBranch() State { + panic("Illegal call `TrueBranch` on PropertyState") +} + +func (a PropertyState) FalseBranch() State { + panic("Illegal call `FalseBranch` on PropertyState") +} + +func (a PropertyState) Bytes(b []byte) State { + panic("PropertyState Bytes") +} + +func (a PropertyState) Func(_ string, _ []string, _ string) State { + panic("Illegal call `Func` on PropertyState") +} + +func (a PropertyState) Property(name string) State { + return propertyTransition(a, a.params, name, a.deferreds) +} + +func (a PropertyState) Clean() { + +} + +func (a PropertyState) Write(_ params, b []byte) { + a.b.writeByte(OpRef) + a.b.write(encode(a.n)) + next := a.u.next() + a.c.set(next, rideString(a.name), 0, 0, true, fmt.Sprintf("property?? %s", a.name)) + a.b.writeByte(OpRef) + a.b.write(encode(next)) + a.b.writeByte(OpProperty) + a.b.write(b) + a.b.ret() +} diff --git a/pkg/ride/compiler_state.go b/pkg/ride/compiler_state.go new file mode 100644 index 000000000..0f601db02 --- /dev/null +++ b/pkg/ride/compiler_state.go @@ -0,0 +1,89 @@ +package ride + +import "fmt" + +type State interface { + Assigment(name string) State + Return() State + Long(value int64) State + Call(name string, argc uint16) State + Reference(name string) State + Boolean(v bool) State + String(s string) State + Condition() State + TrueBranch() State + FalseBranch() State + Bytes(b []byte) State + Func(name string, args []string, invokeParam string) State + Property(name string) State + backward(state State) State + Deferred +} + +type Write interface { + Write(params, []byte) +} + +type Clean interface { + Clean() +} + +type uniqid struct { + id uint16 +} + +func (a *uniqid) next() uint16 { + if a.id < 200 { + a.id = 200 + } + a.id++ + return a.id +} + +type FunctionChecker func(string) (uint16, bool) + +type params struct { + // Wrapper on bytes.Buffer with handy methods. + b *builder + // Relation of variables and it's offset. + r *references + // Way to get function id. + f FunctionChecker + // Unique id for func params. + u *uniqid + // Predefined variables. + c *cell + // Transaction ID, for debug purpose. + txID string +} + +func (a *params) addPredefined(name string, id uniqueid, fn uint16) { + a.r.setAssigment(name, id) + a.c.set(id, nil, fn, 0, false, name) +} + +func (a *params) constant(value rideType) constantDeferred { + switch v := value.(type) { + case rideInt: + if v >= 0 && v <= 100 { + return NewConstantDeferred(uniqueid(v)) + } + case rideBoolean: + if v { + return NewConstantDeferred(101) + } else { + return NewConstantDeferred(102) + } + } + n := a.u.next() + a.c.set(n, value, 0, 0, true, fmt.Sprintf("constant %q", value)) + return NewConstantDeferred(n) +} + +func reference(_ State, params params, name string) constantDeferred { + pos, ok := params.r.getAssigment(name) + if !ok { + panic(fmt.Sprintf("reference `%s` not found, tx %s", name, params.txID)) + } + return NewConstantDeferred(pos) +} diff --git a/pkg/ride/compiler_test.go b/pkg/ride/compiler_test.go index 5bba40549..738df55ac 100644 --- a/pkg/ride/compiler_test.go +++ b/pkg/ride/compiler_test.go @@ -2,80 +2,106 @@ package ride import ( "encoding/base64" - "encoding/hex" + "errors" + "strconv" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/wavesplatform/gowaves/pkg/proto" + "github.com/wavesplatform/gowaves/pkg/types" + "github.com/wavesplatform/gowaves/pkg/util/byte_helpers" ) -func c(values ...rideType) []rideType { - return values +var defaultState = &MockSmartState{ + NewestTransactionByIDFunc: func(_ []byte) (proto.Transaction, error) { + return byte_helpers.TransferWithProofs.Transaction, nil + }, + RetrieveNewestBinaryEntryFunc: func(account proto.Recipient, key string) (*proto.BinaryDataEntry, error) { + return nil, errors.New("not found") + }, + RetrieveNewestIntegerEntryFunc: func(account proto.Recipient, key string) (*proto.IntegerDataEntry, error) { + v, err := strconv.ParseInt(key, 10, 64) + if err != nil { + return nil, err + } + return &proto.IntegerDataEntry{ + Value: v, + }, nil + }, +} +var defaultEnv = &MockRideEnvironment{ + transactionFunc: testTransferObject, + stateFunc: func() types.SmartState { + return defaultState + }, + schemeFunc: func() byte { + return 'T' + }, + thisFunc: func() rideType { + return rideAddress{} + }, + invocationFunc: func() rideObject { + return rideObject{} + }, + heightFunc: func() rideInt { + return rideInt(100500) + }, } -func TestSimpleScriptsCompilation(t *testing.T) { +func TestCompiler(t *testing.T) { + env := defaultEnv for _, test := range []struct { - comment string - source string - code string - constants []rideType + comment string + source string + env RideEnvironment + res bool }{ - {`V1: true`, "AQa3b8tH", "0400", nil}, - {`V3: let x = 1; true`, "AwQAAAABeAAAAAAAAAAAAQbtAkXn", "040002000001", c(rideInt(1))}, - {`V3: let x = "abc"; true`, "AwQAAAABeAIAAAADYWJjBrpUkE4=", "040002000001", c(rideString("abc"))}, - {`V3: func A() = 1; func B() = 2; true`, "AwoBAAAAAUEAAAAAAAAAAAAAAAABCgEAAAABQgAAAAAAAAAAAAAAAAIG+N0aQQ==", - "04000200010102000001", c(rideInt(1), rideInt(2))}, - {`V3: func A() = 1; func B() = 2; A() != B()`, "AwoBAAAAAUEAAAAAAAAAAAAAAAABCgEAAAABQgAAAAAAAAAAAAAAAAIJAQAAAAIhPQAAAAIJAQAAAAFBAAAAAAkBAAAAAUIAAAAAv/Pmkg==", - "0a001400000a001000000900010002000200010102000001", c(rideInt(1), rideInt(2))}, - {`V1: let i = 1; let s = "string"; toString(i) == s`, "AQQAAAABaQAAAAAAAAAAAQQAAAABcwIAAAAGc3RyaW5nCQAAAAAAAAIJAAGkAAAAAQUAAAABaQUAAAABcwIsH74=", - "0c001509002700010c00110900030002000200010102000001", c(rideInt(1), rideString("string"))}, - {`V3: if true then if true then true else false else false`, "AwMGAwYGBwdYjCji", - "04070013030407000e03040600100305060015030500", nil}, - {`V3: if (true) then {let r = true; r} else {let r = false; r}`, "AwMGBAAAAAFyBgUAAAABcgQAAAABcgcFAAAAAXJ/ok0E", - "0407000b030c001006000f030c00120004010501", nil}, - {`V3: if (let a = 1; a == 0) then {let a = 2; a == 0} else {let a = 0; a == 0}`, "AwMEAAAAAWEAAAAAAAAAAAEJAAAAAAAAAgUAAAABYQAAAAAAAAAAAAQAAAABYQAAAAAAAAAAAgkAAAAAAAACBQAAAAFhAAAAAAAAAAAABAAAAAFhAAAAAAAAAAAACQAAAAAAAAIFAAAAAWEAAAAAAAAAAAB3u9Yb", - "0c002a020001090003000207001d030c002e0200030900030002060029030c0032020005090003000200020000010200020102000401", c(rideInt(1), rideInt(0), rideInt(2), rideInt(0), rideInt(0), rideInt(0))}, - {`let a = 1; let b = a; let c = b; a == c`, - "AwQAAAABYQAAAAAAAAAAAQQAAAABYgUAAAABYQQAAAABYwUAAAABYgkAAAAAAAACBQAAAAFhBQAAAAFjUFI1Og==", - "0c00140c000c0900030002000c0010010c00140102000001", c(rideInt(1))}, - {`let x = addressFromString("3PJaDyprvekvPXPuAtxrapacuDJopgJRaU3"); let a = x; let b = a; let c = b; let d = c; let e = d; let f = e; f == e`, - "AQQAAAABeAkBAAAAEWFkZHJlc3NGcm9tU3RyaW5nAAAAAQIAAAAjM1BKYUR5cHJ2ZWt2UFhQdUF0eHJhcGFjdURKb3BnSlJhVTMEAAAAAWEFAAAAAXgEAAAAAWIFAAAAAWEEAAAAAWMFAAAAAWIEAAAAAWQFAAAAAWMEAAAAAWUFAAAAAWQEAAAAAWYFAAAAAWUJAAAAAAAAAgUAAAABZgUAAAABZS5FHzs=", - "0c000c0c00100900030002000c0010010c0014010c0018010c001c010c0020010c002401020000090037000101", c(rideString("3PJaDyprvekvPXPuAtxrapacuDJopgJRaU3"))}, - {`V3: let x = { let y = 1; y == 0 }; let y = { let z = 2; z == 0 } x == y`, - "AwQAAAABeAQAAAABeQAAAAAAAAAAAQkAAAAAAAACBQAAAAF5AAAAAAAAAAAABAAAAAF5BAAAAAF6AAAAAAAAAAACCQAAAAAAAAIFAAAAAXoAAAAAAAAAAAAJAAAAAAAAAgUAAAABeAUAAAABedn8HVg=", - "0c00200c001409000300020002000001020002010c00100200030900030002010c000c020001090003000201", c(rideInt(1), rideInt(0), rideInt(2), rideInt(0))}, - {`V3: let z = 0; let a = {let b = 1; b == z}; let b = {let c = 2; c == z}; a == b`, - "AwQAAAABegAAAAAAAAAAAAQAAAABYQQAAAABYgAAAAAAAAAAAQkAAAAAAAACBQAAAAFiBQAAAAF6BAAAAAFiBAAAAAFjAAAAAAAAAAACCQAAAAAAAAIFAAAAAWMFAAAAAXoJAAAAAAAAAgUAAAABYQUAAAABYnau3I8=", - "0c00200c001409000300020002000101020002010c00100c002c0900030002010c000c0c002c09000300020102000001", c(rideInt(0), rideInt(1), rideInt(2))}, - {`V3: func abs(i:Int) = if (i >= 0) then i else -i; abs(-10) == 10`, "AwoBAAAAA2FicwAAAAEAAAABaQMJAABnAAAAAgUAAAABaQAAAAAAAAAAAAUAAAABaQkBAAAAAS0AAAABBQAAAAFpCQAAAAAAAAIJAQAAAANhYnMAAAABAP/////////2AAAAAAAAAAAKmp8BWw==", - "0200010a001100010200020900030002000d000002000009000d0002070026030d000006002f030d0000090002000101", c(rideInt(0), rideInt(-10), rideInt(10))}, - {`V3: if (true) then {if (false) then {func XX() = true; XX()} else {func XX() = false; XX()}} else {if (true) then {let x = false; x} else {let x = true; x}}`, - "AwMGAwcKAQAAAAJYWAAAAAAGCQEAAAACWFgAAAAACgEAAAACWFgAAAAABwkBAAAAAlhYAAAAAAMGBAAAAAF4BwUAAAABeAQAAAABeAYFAAAAAXgYYeMi", - "0407001b0305070012030a002c0000060018030a002e000006002b0304070027030c003006002b030c0032000401050105010401", nil}, - {`tx.sender == Address(base58'11111111111111111')`, "AwkAAAAAAAACCAUAAAACdHgAAAAGc2VuZGVyCQEAAAAHQWRkcmVzcwAAAAEBAAAAEQAAAAAAAAAAAAAAAAAAAAAAWc7d/w==", - "0b00180800000200010900510001090003000200", c(rideString("sender"), rideBytes{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})}, - {`func b(x: Int) = {func a(y: Int) = x + y; a(1) + a(2)}; b(2) + b(3) == 0`, "AwoBAAAAAWIAAAABAAAAAXgKAQAAAAFhAAAAAQAAAAF5CQAAZAAAAAIFAAAAAXgFAAAAAXkJAABkAAAAAgkBAAAAAWEAAAABAAAAAAAAAAABCQEAAAABYQAAAAEAAAAAAAAAAAIJAAAAAAAAAgkAAGQAAAACCQEAAAABYgAAAAEAAAAAAAAAAAIJAQAAAAFiAAAAAQAAAAAAAAAAAwAAAAAAAAAAAPsZlhQ=", - "0200020a002a00010200030a002a000109000500020200040900030002000d00000d00000900050002010200000a001e00010200010a001e0001090005000201", c(rideInt(1), rideInt(2), rideInt(2), rideInt(3), rideInt(0))}, - {`func first(a: Int, b: Int) = {let x = a + b; x}; first(1, 2) == 0`, "AwoBAAAABWZpcnN0AAAAAgAAAAFhAAAAAWIEAAAAAXgJAABkAAAAAgUAAAABYQUAAAABYgUAAAABeAkAAAAAAAACCQEAAAAFZmlyc3QAAAACAAAAAAAAAAABAAAAAAAAAAACAAAAAAAAAAAAm+QHtw==", - "0200000200010a002000020200020900030002000d00000d00010900050002010c001401", c(rideInt(1), rideInt(2), rideInt(0))}, - {`func A(x: Int, y: Int) = {let r = x + y; r}; func B(x: Int, y: Int) = {let r = A(x, y); r}; B(1, 2) == 3`, "AwoBAAAAAUEAAAACAAAAAXgAAAABeQQAAAABcgkAAGQAAAACBQAAAAF4BQAAAAF5BQAAAAFyCgEAAAABQgAAAAIAAAABeAAAAAF5BAAAAAFyCQEAAAABQQAAAAIFAAAAAXgFAAAAAXkFAAAAAXIJAAAAAAAAAgkBAAAAAUIAAAACAAAAAAAAAAABAAAAAAAAAAACAAAAAAAAAAADSAdb8g==", - "0200000200010a002c00020200020900030002000d00000d00010900050002010d00000d00010a00300002010c0020010c001401", c(rideInt(1), rideInt(2), rideInt(3))}, - {`func f1(a: Int, b: Int) = a + b; func f2(a: Int, b: Int) = a - b; f2(f1(1, 2), 3) == 0`, "AwoBAAAAAmYxAAAAAgAAAAFhAAAAAWIJAABkAAAAAgUAAAABYQUAAAABYgoBAAAAAmYyAAAAAgAAAAFhAAAAAWIJAABlAAAAAgUAAAABYQUAAAABYgkAAAAAAAACCQEAAAACZjIAAAACCQEAAAACZjEAAAACAAAAAAAAAAABAAAAAAAAAAACAAAAAAAAAAADAAAAAAAAAAAALZ/RdA==", - "0200000200010a002800020200020a001c00020200030900030002000d00000d000109000b0002010d00000d0001090005000201", c(rideInt(1), rideInt(2), rideInt(3), rideInt(0))}, - {`func f1(a: Int, b: Int) = a + b; func f2(a: Int, b: Int) = a - b; let x = f1(1, 2); f2(x, 3) == 0`, "AwoBAAAAAmYxAAAAAgAAAAFhAAAAAWIJAABkAAAAAgUAAAABYQUAAAABYgoBAAAAAmYyAAAAAgAAAAFhAAAAAWIJAABlAAAAAgUAAAABYQUAAAABYgQAAAABeAkBAAAAAmYxAAAAAgAAAAAAAAAAAQAAAAAAAAAAAgkAAAAAAAACCQEAAAACZjIAAAACBQAAAAF4AAAAAAAAAAADAAAAAAAAAAAAr1ooAg==", - "0c00140200020a002000020200030900030002000200000200010a002c0002010d00000d000109000b0002010d00000d0001090005000201", c(rideInt(1), rideInt(2), rideInt(3), rideInt(0))}, - {`func f1(a: Int, b: Int) = a + b; func f2(a: Int, b: Int) = b; f2(f1(1, 2), 3) == 3`, "AwoBAAAAAmYxAAAAAgAAAAFhAAAAAWIJAABkAAAAAgUAAAABYQUAAAABYgoBAAAAAmYyAAAAAgAAAAFhAAAAAWIFAAAAAWIJAAAAAAAAAgkBAAAAAmYyAAAAAgkBAAAAAmYxAAAAAgAAAAAAAAAAAQAAAAAAAAAAAgAAAAAAAAAAAwAAAAAAAAAAA1cKYN4=", - "0200000200010a002000020200020a001c00020200030900030002000d0001010d00000d0001090005000201", c(rideInt(1), rideInt(2), rideInt(3), rideInt(3))}, - {`func f1(a: Int, b: Int) = a + b; func f2(a: Int, b: Int) = b; let x = f1(1, 2); f2(x, 3) == 3`, "AwoBAAAAAmYxAAAAAgAAAAFhAAAAAWIJAABkAAAAAgUAAAABYQUAAAABYgoBAAAAAmYyAAAAAgAAAAFhAAAAAWIFAAAAAWIEAAAAAXgJAQAAAAJmMQAAAAIAAAAAAAAAAAEAAAAAAAAAAAIJAAAAAAAAAgkBAAAAAmYyAAAAAgUAAAABeAAAAAAAAAAAAwAAAAAAAAAAA6avbPE=", - "0c00140200020a002000020200030900030002000200000200010a00240002010d0001010d00000d0001090005000201", c(rideInt(1), rideInt(2), rideInt(3), rideInt(3))}, - {`let x = 1; func add(i: Int) = i + 1; add(x) == 2`, "AwQAAAABeAAAAAAAAAAAAQoBAAAAA2FkZAAAAAEAAAABaQkAAGQAAAACBQAAAAFpAAAAAAAAAAABCQAAAAAAAAIJAQAAAANhZGQAAAABBQAAAAF4AAAAAAAAAAACfr6U6w==", - "0c001d0a001100010200020900030002000d000002000109000500020102000001", c(rideInt(1), rideInt(1), rideInt(2))}, - {`let b = base16'0000000000000001'; func add(b: ByteVector) = toInt(b) + 1; add(b) == 2`, "AwQAAAABYgEAAAAIAAAAAAAAAAEKAQAAAANhZGQAAAABAAAAAWIJAABkAAAAAgkABLEAAAABBQAAAAFiAAAAAAAAAAABCQAAAAAAAAIJAQAAAANhZGQAAAABBQAAAAFiAAAAAAAAAAACX00biA==", - "0c00220a001100010200020900030002000d0000090020000102000109000500020102000001", c(rideBytes{0, 0, 0, 0, 0, 0, 0, 1}, rideInt(1), rideInt(2))}, - {`let b = base16'0000000000000001'; func add(v: ByteVector) = toInt(v) + 1; add(b) == 2`, "AwQAAAABYgEAAAAIAAAAAAAAAAEKAQAAAANhZGQAAAABAAAAAXYJAABkAAAAAgkABLEAAAABBQAAAAF2AAAAAAAAAAABCQAAAAAAAAIJAQAAAANhZGQAAAABBQAAAAFiAAAAAAAAAAACI7gYxg==", - "0c00220a001100010200020900030002000d0000090020000102000109000500020102000001", c(rideBytes{0, 0, 0, 0, 0, 0, 0, 1}, rideInt(1), rideInt(2))}, - {`let b = base16'0000000000000001'; func add(v: ByteVector) = toInt(b) + 1; add(b) == 2`, "AwQAAAABYgEAAAAIAAAAAAAAAAEKAQAAAANhZGQAAAABAAAAAXYJAABkAAAAAgkABLEAAAABBQAAAAFiAAAAAAAAAAABCQAAAAAAAAIJAQAAAANhZGQAAAABBQAAAAFiAAAAAAAAAAAChRvwnQ==", - "0c00220a001100010200020900030002000c0022090020000102000109000500020102000001", c(rideBytes{0, 0, 0, 0, 0, 0, 0, 1}, rideInt(1), rideInt(2))}, + {`V1: true`, "AQa3b8tH", env, true}, + {`V1: false`, `AQfeYll6`, nil, false}, + {`V3: let x = 1; true`, "AwQAAAABeAAAAAAAAAAAAQbtAkXn", env, true}, + {`V3: let x = true; x`, "BAQAAAABeAYFAAAAAXhUb/5M", env, true}, + {`V3: let x = "abc"; true`, "AwQAAAABeAIAAAADYWJjBrpUkE4=", nil, true}, + {`V1: let i = 1; let s = "string"; toString(i) == s`, "BAQAAAABaQAAAAAAAAAAAQQAAAABcwIAAAAGc3RyaW5nCQAAAAAAAAIJAAGkAAAAAQUAAAABaQUAAAABc6Y8UOc=", env, false}, + {`V3: let i = 12345; let s = "12345"; toString(i) == s`, "AwQAAAABaQAAAAAAAAAwOQQAAAABcwIAAAAFMTIzNDUJAAAAAAAAAgkAAaQAAAABBQAAAAFpBQAAAAFz1B1iCw==", nil, true}, + {`V3: if (true) then {let r = true; r} else {let r = false; r}`, "AwMGBAAAAAFyBgUAAAABcgQAAAABcgcFAAAAAXJ/ok0E", env, true}, + {`V3: if (false) then {let r = true; r} else {let r = false; r}`, "AwMHBAAAAAFyBgUAAAABcgQAAAABcgcFAAAAAXI+tfo1", env, false}, + {`V3: func abs(i:Int) = if (i >= 0) then i else -i; abs(-10) == 10`, "AwoBAAAAA2FicwAAAAEAAAABaQMJAABnAAAAAgUAAAABaQAAAAAAAAAAAAUAAAABaQkBAAAAAS0AAAABBQAAAAFpCQAAAAAAAAIJAQAAAANhYnMAAAABAP/////////2AAAAAAAAAAAKmp8BWw==", env, true}, + {`V3: func a() = 1; a() == 2`, "BAoBAAAAAWEAAAAAAAAAAAAAAAABCQAAAAAAAAIJAQAAAAFhAAAAAAAAAAAAAAAAAsVdmuc=", env, false}, + {`V3: func abc() = true; abc()`, "BAoBAAAAA2FiYwAAAAAGCQEAAAADYWJjAAAAANHu1ew=", env, true}, + {`V3: func id(v: Boolean) = v; id(true)`, "BAoBAAAAAmlkAAAAAQAAAAF2BQAAAAF2CQEAAAACaWQAAAABBglAaUs=", env, true}, + {`V3: 1 == 1`, "BAkAAAAAAAACAAAAAAAAAAABAAAAAAAAAAABq0EiMw==", env, true}, + {`V3: (1 == 1) == (1 == 1)`, "BAkAAAAAAAACCQAAAAAAAAIAAAAAAAAAAAEAAAAAAAAAAAEJAAAAAAAAAgAAAAAAAAAAAQAAAAAAAAAAAWXKjzM=", env, true}, + {`V3: let x = 1; func add(i: Int) = i + 1; add(x) == 2`, "AwQAAAABeAAAAAAAAAAAAQoBAAAAA2FkZAAAAAEAAAABaQkAAGQAAAACBQAAAAFpAAAAAAAAAAABCQAAAAAAAAIJAQAAAANhZGQAAAABBQAAAAF4AAAAAAAAAAACfr6U6w==", env, true}, + {`V3: let x = if (true) then true else false; x`, "BAQAAAABeAMGBgcFAAAAAXgCINPC", env, true}, + {`V3: let b = base16'0000000000000001'; func add(b: ByteVector) = toInt(b) + 1; add(b) == 2`, "AwQAAAABYgEAAAAIAAAAAAAAAAEKAQAAAANhZGQAAAABAAAAAWIJAABkAAAAAgkABLEAAAABBQAAAAFiAAAAAAAAAAABCQAAAAAAAAIJAQAAAANhZGQAAAABBQAAAAFiAAAAAAAAAAACX00biA==", nil, true}, + {`V3: let b = base16'0000000000000001'; func add(v: ByteVector) = toInt(v) + 1; add(b) == 2`, "AwQAAAABYgEAAAAIAAAAAAAAAAEKAQAAAANhZGQAAAABAAAAAXYJAABkAAAAAgkABLEAAAABBQAAAAF2AAAAAAAAAAABCQAAAAAAAAIJAQAAAANhZGQAAAABBQAAAAFiAAAAAAAAAAACI7gYxg==", nil, true}, + {`V3: let b = base16'0000000000000001'; func add(v: ByteVector) = toInt(b) + 1; add(b) == 2`, "AwQAAAABYgEAAAAIAAAAAAAAAAEKAQAAAANhZGQAAAABAAAAAXYJAABkAAAAAgkABLEAAAABBQAAAAFiAAAAAAAAAAABCQAAAAAAAAIJAQAAAANhZGQAAAABBQAAAAFiAAAAAAAAAAAChRvwnQ==", nil, true}, + {`V3: let data = base64'AAAAAAABhqAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWyt9GyysOW84u/u5V5Ah/SzLfef4c28UqXxowxFZS4SLiC6+XBh8D7aJDXyTTjpkPPED06ZPOzUE23V6VYCsLw=='; func getStock(data:ByteVector) = toInt(take(drop(data, 8), 8)); getStock(data) == 1`, `AwQAAAAEZGF0YQEAAABwAAAAAAABhqAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWyt9GyysOW84u/u5V5Ah/SzLfef4c28UqXxowxFZS4SLiC6+XBh8D7aJDXyTTjpkPPED06ZPOzUE23V6VYCsLwoBAAAACGdldFN0b2NrAAAAAQAAAARkYXRhCQAEsQAAAAEJAADJAAAAAgkAAMoAAAACBQAAAARkYXRhAAAAAAAAAAAIAAAAAAAAAAAICQAAAAAAAAIJAQAAAAhnZXRTdG9jawAAAAEFAAAABGRhdGEAAAAAAAAAAAFCtabi`, env, true}, + {`V3: let ref = 999; func g(a: Int) = ref; func f(ref: Int) = g(ref); f(1) == 999`, "AwQAAAADcmVmAAAAAAAAAAPnCgEAAAABZwAAAAEAAAABYQUAAAADcmVmCgEAAAABZgAAAAEAAAADcmVmCQEAAAABZwAAAAEFAAAAA3JlZgkAAAAAAAACCQEAAAABZgAAAAEAAAAAAAAAAAEAAAAAAAAAA+fjknmW", env, true}, + {`let x = 5; 6 > 4`, `AQQAAAABeAAAAAAAAAAABQkAAGYAAAACAAAAAAAAAAAGAAAAAAAAAAAEYSW6XA==`, nil, true}, + {`let x = 5; 6 > x`, `AQQAAAABeAAAAAAAAAAABQkAAGYAAAACAAAAAAAAAAAGBQAAAAF4Gh24hw==`, nil, true}, + {`let x = 5; 6 >= x`, `AQQAAAABeAAAAAAAAAAABQkAAGcAAAACAAAAAAAAAAAGBQAAAAF4jlxXHA==`, nil, true}, + {`let x = {let y = true;y}x`, `BAQAAAABeAQAAAABeQYFAAAAAXkFAAAAAXhCPj2C`, nil, true}, + {`let x = throw(); true`, `AQQAAAABeAkBAAAABXRocm93AAAAAAa7bgf4`, nil, true}, + {`let x = throw(); true || x`, `AQQAAAABeAkBAAAABXRocm93AAAAAAMGBgUAAAABeKRnLds=`, env, true}, + {`tx == tx`, "BAkAAAAAAAACBQAAAAJ0eAUAAAACdHhnqgP4", env, true}, + {fcall1, "BAoBAAAABmdldEludAAAAAEAAAADa2V5BAAAAAckbWF0Y2gwCQAEGgAAAAIFAAAABHRoaXMFAAAAA2tleQMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAADSW50BAAAAAF4BQAAAAckbWF0Y2gwBQAAAAF4AAAAAAAAAAAABAAAAAFhCQEAAAAGZ2V0SW50AAAAAQIAAAABNQQAAAABYgkBAAAABmdldEludAAAAAECAAAAATYJAAAAAAAAAgUAAAABYQUAAAABYkOIJQA=", env, false}, + {finf, "BAoBAAAAA2FiYwAAAAAKAQAAAAJpbgAAAAAGCQEAAAACaW4AAAAACQEAAAADYWJjAAAAADpBKyM=", env, true}, + {intersectNames, "AwoBAAAAA2luYwAAAAEAAAABdgkAAGQAAAACBQAAAAF2AAAAAAAAAAABCgEAAAAEY2FsbAAAAAEAAAADaW5jCQEAAAADaW5jAAAAAQUAAAADaW5jCQAAAAAAAAIJAQAAAARjYWxsAAAAAQAAAAAAAAAAAgAAAAAAAAAAAxgTXMY=", env, true}, + {`func abc(addr: Address) = addr == tx.sender;abc(tx.sender)`, "BAoBAAAAA2FiYwAAAAEAAAAEYWRkcgkAAAAAAAACBQAAAARhZGRyCAUAAAACdHgAAAAGc2VuZGVyCQEAAAADYWJjAAAAAQgFAAAAAnR4AAAABnNlbmRlckJrXFI=", env, true}, + {`let y = [{let x = 1;x}];true`, "BAQAAAABeQkABEwAAAACBAAAAAF4AAAAAAAAAAABBQAAAAF4BQAAAANuaWwGua/TXw==", env, true}, + {`tx.id == base58''`, `AQkAAAAAAAACCAUAAAACdHgAAAACaWQBAAAAAJBtD70=`, env, false}, + {`tx.id == base58'H5C8bRzbUTMePSDVVxjiNKDUwk6CKzfZGTP2Rs7aCjsV'`, `BAkAAAAAAAACCAUAAAACdHgAAAACaWQBAAAAIO7N5luRDUgN1SJ4kFmy/Ni8U2H6k7bpszok5tlLlRVgHwSHyg==`, env, false}, + {`tx.id == tx.id`, `BAkAAAAAAAACCAUAAAACdHgAAAACaWQIBQAAAAJ0eAAAAAJpZHErpOM=`, env, true}, + {`let x = tx.id == base58'a';true`, `AQQAAAABeAkAAAAAAAACCAUAAAACdHgAAAACaWQBAAAAASEGjR0kcA==`, env, true}, + {`tx.proofs[0] != base58'' && tx.proofs[1] == base58''`, `BAMJAQAAAAIhPQAAAAIJAAGRAAAAAggFAAAAAnR4AAAABnByb29mcwAAAAAAAAAAAAEAAAAACQAAAAAAAAIJAAGRAAAAAggFAAAAAnR4AAAABnByb29mcwAAAAAAAAAAAQEAAAAAB106gzM=`, env, true}, + {`match tx {case t : TransferTransaction | MassTransferTransaction | ExchangeTransaction => true; case _ => false}`, `AQQAAAAHJG1hdGNoMAUAAAACdHgDAwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAABNFeGNoYW5nZVRyYW5zYWN0aW9uBgMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAXTWFzc1RyYW5zZmVyVHJhbnNhY3Rpb24GCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAE1RyYW5zZmVyVHJhbnNhY3Rpb24EAAAAAXQFAAAAByRtYXRjaDAGB6Ilvok=`, env, true}, + {`V2: match transactionById(tx.id) {case t: Unit => false case _ => true}`, `AgQAAAAHJG1hdGNoMAkAA+gAAAABCAUAAAACdHgAAAACaWQDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAABFVuaXQEAAAAAXQFAAAAByRtYXRjaDAHBp9TFcQ=`, env, true}, + {`Up() == UP`, `AwkAAAAAAAACCQEAAAACVXAAAAAABQAAAAJVUPGUxeg=`, env, true}, + {`HalfUp() == HALFUP`, `AwkAAAAAAAACCQEAAAAGSGFsZlVwAAAAAAUAAAAGSEFMRlVQbUfpTQ==`, nil, true}, + {`let a0 = NoAlg() == NOALG; let a1 = Md5() == MD5; let a2 = Sha1() == SHA1; let a3 = Sha224() == SHA224; let a4 = Sha256() == SHA256; let a5 = Sha384() == SHA384; let a6 = Sha512() == SHA512; let a7 = Sha3224() == SHA3224; let a8 = Sha3256() == SHA3256; let a9 = Sha3384() == SHA3384; let a10 = Sha3512() == SHA3512; a0 && a1 && a2 && a3 && a4 && a5 && a6 && a7 && a8 && a9 && a10`, `AwQAAAACYTAJAAAAAAAAAgkBAAAABU5vQWxnAAAAAAUAAAAFTk9BTEcEAAAAAmExCQAAAAAAAAIJAQAAAANNZDUAAAAABQAAAANNRDUEAAAAAmEyCQAAAAAAAAIJAQAAAARTaGExAAAAAAUAAAAEU0hBMQQAAAACYTMJAAAAAAAAAgkBAAAABlNoYTIyNAAAAAAFAAAABlNIQTIyNAQAAAACYTQJAAAAAAAAAgkBAAAABlNoYTI1NgAAAAAFAAAABlNIQTI1NgQAAAACYTUJAAAAAAAAAgkBAAAABlNoYTM4NAAAAAAFAAAABlNIQTM4NAQAAAACYTYJAAAAAAAAAgkBAAAABlNoYTUxMgAAAAAFAAAABlNIQTUxMgQAAAACYTcJAAAAAAAAAgkBAAAAB1NoYTMyMjQAAAAABQAAAAdTSEEzMjI0BAAAAAJhOAkAAAAAAAACCQEAAAAHU2hhMzI1NgAAAAAFAAAAB1NIQTMyNTYEAAAAAmE5CQAAAAAAAAIJAQAAAAdTaGEzMzg0AAAAAAUAAAAHU0hBMzM4NAQAAAADYTEwCQAAAAAAAAIJAQAAAAdTaGEzNTEyAAAAAAUAAAAHU0hBMzUxMgMDAwMDAwMDAwMFAAAAAmEwBQAAAAJhMQcFAAAAAmEyBwUAAAACYTMHBQAAAAJhNAcFAAAAAmE1BwUAAAACYTYHBQAAAAJhNwcFAAAAAmE4BwUAAAACYTkHBQAAAANhMTAHRc/wAA==`, env, true}, + {`Unit() == unit`, `AwkAAAAAAAACCQEAAAAEVW5pdAAAAAAFAAAABHVuaXTstg1G`, env, true}, } { src, err := base64.StdEncoding.DecodeString(test.source) require.NoError(t, err, test.comment) @@ -84,76 +110,1405 @@ func TestSimpleScriptsCompilation(t *testing.T) { require.NoError(t, err, test.comment) assert.NotNil(t, tree, test.comment) - rideScript, err := Compile(tree) + tree = MustExpand(tree) + + script, err := CompileTree("", tree) + + require.True(t, tree.Expanded) + require.NoError(t, err, test.comment) - assert.NotNil(t, rideScript, test.comment) - script, ok := rideScript.(*SimpleScript) - require.True(t, ok, test.comment) + assert.NotNil(t, script, test.comment) - code := hex.EncodeToString(script.Code) - assert.Equal(t, test.code, code, test.comment) - assert.ElementsMatch(t, test.constants, script.Constants, test.comment) + res, err := script.Verify(test.env) + require.NoError(t, err, test.comment) + assert.NotNil(t, res, test.comment) + r, ok := res.(ScriptResult) + assert.True(t, ok, test.comment) + assert.Equal(t, test.res, r.Result(), test.comment) } } -func TestDAppScriptsCompilation(t *testing.T) { - for _, test := range []struct { - comment string - source string - code string - constants []rideType - entries map[string]callable - }{ - {`@Verifier(tx) func verify() = false`, "AAIDAAAAAAAAAAIIAQAAAAAAAAAAAAAAAQAAAAJ0eAEAAAAGdmVyaWZ5AAAAAAcysh6J", - "0500", nil, map[string]callable{"": {0, "tx"}}}, - {`let a = 1\n@Verifier(tx) func verify() = false`, "AAIDAAAAAAAAAAIIAQAAAAEAAAAAAWEAAAAAAAAAAAEAAAAAAAAAAQAAAAJ0eAEAAAAGdmVyaWZ5AAAAAAdVrdkQ", - "020000010500", c(rideInt(1)), map[string]callable{"": {4, "tx"}}}, - {`let a = 1\nfunc inc(v: Int) = {v + 1}\n@Verifier(tx) func verify() = false`, "AAIDAAAAAAAAAAIIAQAAAAIAAAAAAWEAAAAAAAAAAAEBAAAAA2luYwAAAAEAAAABdgkAAGQAAAACBQAAAAF2AAAAAAAAAAABAAAAAAAAAAEAAAACdHgBAAAABnZlcmlmeQAAAAAHDMc8rg==", - "020000010d00000200010900050002010500", c(rideInt(1), rideInt(1)), map[string]callable{"": {16, "tx"}}}, - {`let a = 1\nfunc inc(v: Int) = {v + 1}\n@Verifier(tx) func verify() = inc(a) == 2`, "AAIDAAAAAAAAAAIIAQAAAAIAAAAAAWEAAAAAAAAAAAEBAAAAA2luYwAAAAEAAAABdgkAAGQAAAACBQAAAAF2AAAAAAAAAAABAAAAAAAAAAEAAAACdHgBAAAABnZlcmlmeQAAAAAJAAAAAAAAAgkBAAAAA2luYwAAAAEFAAAAAWEAAAAAAAAAAAJtD5WX", - "020000010d00000200010900050002010c00000a00040001020002090003000200", c(rideInt(1), rideInt(1), rideInt(2)), - map[string]callable{"": {16, "tx"}}}, - {`let a = 1\nlet b = 1\nfunc inc(v: Int) = {v + 1}\nfunc add(x: Int, y: Int) = {x + y}\n@Verifier(tx) func verify() = inc(a) == add(a, b)`, "AAIDAAAAAAAAAAIIAQAAAAQAAAAAAWEAAAAAAAAAAAEAAAAAAWIAAAAAAAAAAAEBAAAAA2luYwAAAAEAAAABdgkAAGQAAAACBQAAAAF2AAAAAAAAAAABAQAAAANhZGQAAAACAAAAAXgAAAABeQkAAGQAAAACBQAAAAF4BQAAAAF5AAAAAAAAAAEAAAACdHgBAAAABnZlcmlmeQAAAAAJAAAAAAAAAgkBAAAAA2luYwAAAAEFAAAAAWEJAQAAAANhZGQAAAACBQAAAAFhBQAAAAFiDbIkmw==", - "02000001020001010d00000200020900050002010d00000d00010900050002010c00000a000800010c00000c00040a00140002090003000200", - c(rideInt(1), rideInt(1), rideInt(1)), - map[string]callable{"": {32, "tx"}}}, - {`let a = 1\nlet b = 1\nlet messages = ["INFO", "WARN"]\nfunc inc(v: Int) = {v + 1}\nfunc add(x: Int, y: Int) = {x + y}\nfunc msg(i: Int) = {messages[i]}\n@Verifier(tx) func verify() = if inc(a) == add(a, b) then throw(msg(a)) else throw(msg(b))`, "AAIDAAAAAAAAAAIIAQAAAAYAAAAAAWEAAAAAAAAAAAEAAAAAAWIAAAAAAAAAAAEAAAAACG1lc3NhZ2VzCQAETAAAAAICAAAABElORk8JAARMAAAAAgIAAAAEV0FSTgUAAAADbmlsAQAAAANpbmMAAAABAAAAAXYJAABkAAAAAgUAAAABdgAAAAAAAAAAAQEAAAADYWRkAAAAAgAAAAF4AAAAAXkJAABkAAAAAgUAAAABeAUAAAABeQEAAAADbXNnAAAAAQAAAAFpCQABkQAAAAIFAAAACG1lc3NhZ2VzBQAAAAFpAAAAAAAAAAEAAAACdHgBAAAABnZlcmlmeQAAAAADCQAAAAAAAAIJAQAAAANpbmMAAAABBQAAAAFhCQEAAAADYWRkAAAAAgUAAAABYQUAAAABYgkAAAIAAAABCQEAAAADbXNnAAAAAQUAAAABYQkAAAIAAAABCQEAAAADbXNnAAAAAQUAAAABYvi7IpM=", - "02000001020001010200020200030b001609001e000209001e0002010d00000200040900050002010d00000d00010900050002010c00080d00000900320002010c00000a001c00010c00000c00040a00280002090003000207006c030c00000a00340001090028000106007a030c00040a00340001090028000100", - c(rideInt(1), rideInt(1), rideString("INFO"), rideString("WARN"), rideInt(1)), - map[string]callable{"": {64, "tx"}}}, - {`@Callable(i)func f() = {WriteSet([DataEntry("YYY", "XXX")]}`, "AAIDAAAAAAAAAAQIARIAAAAAAAAAAAEAAAABaQEAAAABZgAAAAAJAQAAAAhXcml0ZVNldAAAAAEJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAAA1lZWQIAAAADWFhYBQAAAANuaWwAAAAAeFguLA==", - "02000002000109005600020b001609001e000209006e000100", c(rideString("YYY"), rideString("XXX")), - map[string]callable{"f": {0, "i"}}}, - {`@Callable(i)func f() = {let callerAddress = toBase58String(i.caller.bytes); WriteSet([DataEntry(callerAddress, "XXX")]}`, "AAIDAAAAAAAAAAQIARIAAAAAAAAAAAEAAAABaQEAAAABZgAAAAAEAAAADWNhbGxlckFkZHJlc3MJAAJYAAAAAQgIBQAAAAFpAAAABmNhbGxlcgAAAAVieXRlcwkBAAAACFdyaXRlU2V0AAAAAQkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgUAAAANY2FsbGVyQWRkcmVzcwIAAAADWFhYBQAAAANuaWwAAAAAe3xtyw==", - "0d000008000008000109003d0001010c000002000209005600020b001609001e000209006e000100", - c(rideString("caller"), rideString("bytes"), rideString("XXX")), - map[string]callable{"f": {15, "i"}}}, - {`let messages = ["INFO", "WARN"]\nfunc msg(i: Int) = {messages[i]}\n@Callable(i)func tellme(x: Int) = {WriteSet([DataEntry("m", msg(x))]}`, "AAIDAAAAAAAAAAcIARIDCgEBAAAAAgAAAAAIbWVzc2FnZXMJAARMAAAAAgIAAAAESU5GTwkABEwAAAACAgAAAARXQVJOBQAAAANuaWwBAAAAA21zZwAAAAEAAAABaQkAAZEAAAACBQAAAAhtZXNzYWdlcwUAAAABaQAAAAEAAAABaQEAAAAGdGVsbG1lAAAAAQAAAAF4CQEAAAAIV3JpdGVTZXQAAAABCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACAgAAAAFtCQEAAAADbXNnAAAAAQUAAAABeAUAAAADbmlsAAAAAO4TltI=", - "0200000200010b001609001e000209001e0002010c00000d00000900320002010200020d00010a0014000109005600020b001609001e000209006e000100", c(rideString("INFO"), rideString("WARN"), rideString("m")), - map[string]callable{"tellme": {32, "i"}}}, - {`let messages = ["INFO", "WARN"]\nfunc msg(i: Int) = {messages[i]}\n@Callable(i)func tellme(x: Int, y: Int) = {WriteSet([DataEntry("m", msg(x))]}`, "AAIDAAAAAAAAAAgIARIECgIBAQAAAAIAAAAACG1lc3NhZ2VzCQAETAAAAAICAAAABElORk8JAARMAAAAAgIAAAAEV0FSTgUAAAADbmlsAQAAAANtc2cAAAABAAAAAWkJAAGRAAAAAgUAAAAIbWVzc2FnZXMFAAAAAWkAAAABAAAAAWkBAAAABnRlbGxtZQAAAAIAAAABeAAAAAF5CQEAAAAIV3JpdGVTZXQAAAABCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACAgAAAAFtCQEAAAADbXNnAAAAAQUAAAABeAUAAAADbmlsAAAAAD8Tlfs=", - "0200000200010b001609001e000209001e0002010c00000d00000900320002010200020d00010a0014000109005600020b001609001e000209006e000100", c(rideString("INFO"), rideString("WARN"), rideString("m")), - map[string]callable{"tellme": {32, "i"}}}, - {`let a = 1; let messages = ["INFO", "WARN"]; func msg(i: Int) = {messages[i]}; @Callable(i)func tellme(x: Int) = {let m = msg(x); let callerAddress = toBase58String(i.caller.bytes); WriteSet([DataEntry(callerAddress + "-m", m)]}`, "AAIDAAAAAAAAAAcIARIDCgEBAAAAAwAAAAABYQAAAAAAAAAAAQAAAAAIbWVzc2FnZXMJAARMAAAAAgIAAAAESU5GTwkABEwAAAACAgAAAARXQVJOBQAAAANuaWwBAAAAA21zZwAAAAEAAAABaQkAAZEAAAACBQAAAAhtZXNzYWdlcwUAAAABaQAAAAEAAAABaQEAAAAGdGVsbG1lAAAAAQAAAAF4BAAAAAFtCQEAAAADbXNnAAAAAQUAAAABeAQAAAANY2FsbGVyQWRkcmVzcwkAAlgAAAABCAgFAAAAAWkAAAAGY2FsbGVyAAAABWJ5dGVzCQEAAAAIV3JpdGVTZXQAAAABCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQABLAAAAAIFAAAADWNhbGxlckFkZHJlc3MCAAAAAi1tBQAAAAFtBQAAAANuaWwAAAAAgveN3A==", - "020000010200010200020b001609001e000209001e0002010c00040d00000900320002010d000008000308000409003d0001010d00010a00180001010c002402000509002d00020c003309005600020b001609001e000209006e000100", c(rideInt(1), rideString("INFO"), rideString("WARN"), rideString("caller"), rideString("bytes"), rideString("-m")), - map[string]callable{"tellme": {60, "i"}}}, - } { - src, err := base64.StdEncoding.DecodeString(test.source) - require.NoError(t, err, test.comment) +// 1 == 1 +func TestCallExternal(t *testing.T) { + n := &FunctionCallNode{ + Name: "0", + Arguments: []Node{ + &LongNode{ + Value: 1, + }, + &LongNode{ + Value: 1, + }, + }, + } + + f, err := compileFunction("", 3, []Node{n}, false, true) + require.NoError(t, err) + + require.Equal(t, + []byte{ + OpReturn, + OpReturn, + OpRef, 0, 1, + OpRef, 0, 1, + OpExternalCall, 0, 3, 0, 2, + OpReturn, + OpReturn, + }, + f.ByteCode) +} + +// let x = if (true) then true else false; x +func TestIfConditionRightByteCode(t *testing.T) { + n := &AssignmentNode{ + Name: "x", + Expression: &ConditionalNode{ + Condition: &BooleanNode{Value: true}, + TrueExpression: &BooleanNode{Value: true}, + FalseExpression: &BooleanNode{Value: false}, + }, + Block: &ReferenceNode{ + Name: "x", + }, + } + + f, err := compileFunction("", 3, []Node{n}, false, true) + require.NoError(t, err) + + /** + require.Equal(t, + []byte{ + OpReturn, + OpRef, 0, 1, + OpClearCache, 0, 1, + OpReturn, + OpRef, 0, 2, + OpJumpIfFalse, 0, 0x12, 0, 0x16, 0, 0x1a, + OpRef, 0, 3, + OpReturn, + OpRef, 0, 4, + OpReturn, + OpReturn, + }, + f.ByteCode) + + /**/ + + rs, err := f.Verify(nil) + require.NoError(t, err) + require.Equal(t, true, rs.Result()) +} + +// let i = 1; let s = "string"; toString(i) == s +func TestCall(t *testing.T) { + source := `BAQAAAABaQAAAAAAAAAAAQQAAAABcwIAAAAGc3RyaW5nCQAAAAAAAAIJAAGkAAAAAQUAAAABaQUAAAABc6Y8UOc=` + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(t, err) + + tree, err := Parse(src) + require.NoError(t, err) + assert.NotNil(t, tree) + + script, err := CompileVerifier("", tree) + require.NoError(t, err) + assert.NotNil(t, script) + + rs, err := script.Verify(nil) + require.NoError(t, err) + require.Equal(t, 2, len(rs.Calls())) + require.Equal(t, false, rs.Result()) +} + +//func a() = 1; a() == 1 +func TestDoubleCall(t *testing.T) { + n := &FunctionDeclarationNode{ + Name: "a", + Arguments: nil, + Body: &LongNode{ + Value: 1, + }, + Block: &FunctionCallNode{ + Name: "0", + Arguments: []Node{ + &FunctionCallNode{ + Name: "a", + Arguments: nil, + }, + &LongNode{ + Value: 1, + }, + }, + }, + } + + f, err := compileFunction("", 3, []Node{n}, false, true) + require.NoError(t, err) + + rs, err := f.Verify(nil) + require.NoError(t, err) + require.Equal(t, true, rs.Result()) +} + +// func id(v: Boolean) = v; id(true) +func TestCallWithConstArg(t *testing.T) { + n := &FunctionDeclarationNode{ + Name: "id", + Arguments: []string{"v"}, + Body: &ReferenceNode{Name: "v"}, + Block: &FunctionCallNode{ + Name: "id", + Arguments: []Node{ + &BooleanNode{ + Value: true, + }, + }, + }, + invocationParameter: "", + } + + f, err := compileFunction("", 3, []Node{n}, false, true) + require.NoError(t, err) + + rs, err := f.Verify(nil) + require.NoError(t, err) + require.Equal(t, true, rs.Result()) +} + +// func id(v: Boolean) = v && v; id(true) +func TestMultipleCallConstantFuncArgument(t *testing.T) { + source := `BAoBAAAAAmlkAAAAAQAAAAF2AwUAAAABdgUAAAABdgcJAQAAAAJpZAAAAAEG3g2xRQ==` + + state := &MockSmartState{NewestTransactionByIDFunc: func(_ []byte) (proto.Transaction, error) { + return byte_helpers.TransferWithProofs.Transaction, nil + }} + env := &MockRideEnvironment{ + transactionFunc: testTransferObject, + stateFunc: func() types.SmartState { + return state + }, + schemeFunc: func() byte { + return 'T' + }, + checkMessageLengthFunc: func(in1 int) bool { + return true + }, + } + + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(t, err) + + tree, err := Parse(src) + require.NoError(t, err) + assert.NotNil(t, tree) + + script, err := CompileVerifier("", tree) + require.NoError(t, err) + assert.NotNil(t, script) + + res, err := script.Verify(env) + require.NoError(t, err) + assert.NotNil(t, res) + r, ok := res.(ScriptResult) + assert.True(t, ok) + assert.Equal(t, true, r.Result()) +} + +/* +{-# STDLIB_VERSION 4 #-} +{-# CONTENT_TYPE EXPRESSION #-} +{-# SCRIPT_TYPE ACCOUNT #-} + +func id(v: Boolean) = { + if (v) then { + let x = throw("a") + 1 + } else { + let x = throw("b") + 2 + } +} + +1 == id(true) + +*/ +func TestIfStmt(t *testing.T) { + source := `BAoBAAAAAmlkAAAAAQAAAAF2AwUAAAABdgQAAAABeAkAAAIAAAABAgAAAAFhAAAAAAAAAAABBAAAAAF4CQAAAgAAAAECAAAAAWIAAAAAAAAAAAIJAAAAAAAAAgAAAAAAAAAAAQkBAAAAAmlkAAAAAQYYAiEb` + state := &MockSmartState{ + NewestTransactionByIDFunc: func(_ []byte) (proto.Transaction, error) { + return byte_helpers.TransferWithProofs.Transaction, nil + }, + } + env := &MockRideEnvironment{ + transactionFunc: testTransferObject, + stateFunc: func() types.SmartState { + return state + }, + schemeFunc: func() byte { + return 'T' + }, + checkMessageLengthFunc: func(in1 int) bool { + return true + }, + } + + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(t, err) + + tree, err := Parse(src) + require.NoError(t, err) + assert.NotNil(t, tree) + + script, err := CompileVerifier("", tree) + require.NoError(t, err) + require.NotNil(t, script) + + res, err := script.Verify(env) + require.NoError(t, err) + require.NotNil(t, res) + r, ok := res.(ScriptResult) + require.True(t, ok) + + for _, l := range r.calls { + t.Log(l) + } + + assert.Equal(t, true, r.Result()) +} + +/* +{-# STDLIB_VERSION 3 #-} +{-# CONTENT_TYPE DAPP #-} +{-# SCRIPT_TYPE ACCOUNT #-} + +@Callable(i) +func abc(question: String) = { + WriteSet([ + DataEntry("a", 5) + ]) +} + +@Callable(i) +func cba(question: String) = { + WriteSet([ + DataEntry("a", 6) + ]) +} +*/ +func TestDappMultipleFunctions(t *testing.T) { + source := "AAIDAAAAAAAAAAwIARIDCgEIEgMKAQgAAAAAAAAAAgAAAAFpAQAAAANhYmMAAAABAAAACHF1ZXN0aW9uCQEAAAAIV3JpdGVTZXQAAAABCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACAgAAAAFhAAAAAAAAAAAFBQAAAANuaWwAAAABaQEAAAADY2JhAAAAAQAAAAhxdWVzdGlvbgkBAAAACFdyaXRlU2V0AAAAAQkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAABYQAAAAAAAAAABgUAAAADbmlsAAAAAFEpRso=" + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(t, err) + + tree, err := Parse(src) + require.NoError(t, err) + assert.NotNil(t, tree) + + script, err := CompileDapp("", tree) + require.NoError(t, err) + assert.NotNil(t, script) + + rs, err := script.Invoke(defaultEnv, "abc", []rideType{rideString("")}) + require.NoError(t, err) + + require.Equal(t, true, rs.Result()) + require.Equal(t, + []proto.ScriptAction{ + &proto.DataEntryScriptAction{ + Entry: &proto.IntegerDataEntry{Value: 5, Key: "a"}, + }, + }, []proto.ScriptAction(rs.ScriptActions())) + + rs, err = script.Invoke(defaultEnv, "cba", []rideType{rideString("")}) + require.NoError(t, err) + + require.Equal(t, true, rs.Result()) + require.Equal(t, + []proto.ScriptAction{ + &proto.DataEntryScriptAction{ + Entry: &proto.IntegerDataEntry{Value: 6, Key: "a"}, + }, + }, []proto.ScriptAction(rs.ScriptActions())) +} + +/* + +func finalizeCurrentPrice() { + let prices = 1100( + getOracleProvideHeight( + 401(oraclesList,0), + height + ), + 1100(getOracleProvideHeight(401(oraclesList,1),height), + 1100(getOracleProvideHeight(401(oraclesList,2,),height,), + 1100(getOracleProvideHeight(401(oraclesList,3,),height,), + 1100(getOracleProvideHeight(401(oraclesList,4,),height,),nil,),),),),); + let priceProvidingCount = ((((if (!=(401(prices,0,),0,)) { 1 } else { 0 } + if (!=(401(prices,1,),0,)) { 1 } else { 0 }) + if (!=(401(prices,2,),0,)) { 1 } else { 0 }) + if (!=(401(prices,3,),0,)) { 1 } else { 0 }) + if (!=(401(prices,4,),0,)) { 1 } else { 0 }); + let priceSum = ((((401(prices,0,) + 401(prices,1,)) + 401(prices,2,)) + 401(prices,3,)) + 401(prices,4,)); + let newPrice = 105(priceSum,priceProvidingCount,); + if (isBlocked) { + 2("contract is blocked") + } else { + if (102(bftCoefficientOracle,priceProvidingCount)) { + 2( + 300( + 300( + 420(bftCoefficientOracle), + "/5 oracles need to set a price " + ), + 420(priceProvidingCount) + ) + ) + } else { + if (if (103(newPrice,(price + 105(104(price,percentPriceOffset,),100,)),)) { true } else { 103((price - 105(104(price,percentPriceOffset,),100,)),newPrice,) }) { WriteSet(1100(DataEntry(IsBlockedKey,true,),1100(DataEntry(getBlackSwarmPriceKey(height,),newPrice,),nil,),),) } else { let newPriceIndex = (priceIndex + 1); WriteSet(1100(DataEntry(PriceKey,newPrice,),1100(DataEntry(getPriceHistoryKey(height,),newPrice,),1100(DataEntry(PriceIndexKey,newPriceIndex,),1100(DataEntry(getHeightPriceByIndexKey(newPriceIndex,),height,),nil,),),),),) } } } } + + +*/ + +func Test777(t *testing.T) { + source := `BAQAAAALb3JhY2xlc0xpc3QJAARMAAAAAgIAAAAjM01TTk1jcXl3ZWlNOWNXcHZmNEZuOEdBV2V1UHN0eGoyaEsFAAAAA25pbAoBAAAAGGdldE51bWJlckJ5QWRkcmVzc0FuZEtleQAAAAIAAAAHYWRkcmVzcwAAAANrZXkAAAAAAAAAAAAKAQAAABZnZXRPcmFjbGVQcm92aWRlSGVpZ2h0AAAAAgAAAAVvd25lcgAAAAZoZWlnaHQJAQAAABhnZXROdW1iZXJCeUFkZHJlc3NBbmRLZXkAAAACCQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABBQAAAAVvd25lcgUAAAAGaGVpZ2h0CQAAAAAAAAIJAQAAABZnZXRPcmFjbGVQcm92aWRlSGVpZ2h0AAAAAgkAAZEAAAACBQAAAAtvcmFjbGVzTGlzdAAAAAAAAAAAAAUAAAAGaGVpZ2h0AAAAAAAAAAABHUHhjA==` + + state := &MockSmartState{ + NewestTransactionByIDFunc: func(_ []byte) (proto.Transaction, error) { + return byte_helpers.TransferWithProofs.Transaction, nil + }, + RetrieveNewestBinaryEntryFunc: func(account proto.Recipient, key string) (*proto.BinaryDataEntry, error) { + t.Log("key: ", key) + return nil, errors.New("not found") + }, + RetrieveNewestIntegerEntryFunc: func(account proto.Recipient, key string) (*proto.IntegerDataEntry, error) { + t.Logf("acc: %q, key %s", account, key) + return &proto.IntegerDataEntry{ + Value: 0, + }, nil + }, + } + env := &MockRideEnvironment{ + transactionFunc: testTransferObject, + stateFunc: func() types.SmartState { + return state + }, + schemeFunc: func() byte { + return 'T' + }, + thisFunc: func() rideType { + return rideAddress{} + }, + heightFunc: func() rideInt { + return 100500 + }, + } + + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(t, err) + + tree, err := Parse(src) + require.NoError(t, err) + assert.NotNil(t, tree) + + script, err := CompileVerifier("", tree) + require.NoError(t, err) + assert.NotNil(t, script) + + res, err := script.Verify(env) + require.NoError(t, err) + assert.NotNil(t, res) + r, ok := res.(ScriptResult) + assert.True(t, ok) + assert.Equal(t, false, r.Result()) +} + +/* +func abc() = 5 +func cba() = 10 +if abc() == cba() then { + true +} else { + false +} +*/ +func Test888(t *testing.T) { + source := `BAoBAAAAA2FiYwAAAAAAAAAAAAAAAAUKAQAAAANjYmEAAAAAAAAAAAAAAAAKAwkAAAAAAAACCQEAAAADYWJjAAAAAAkBAAAAA2NiYQAAAAAGB0hjUOM=` + + state := &MockSmartState{ + NewestTransactionByIDFunc: func(_ []byte) (proto.Transaction, error) { + return byte_helpers.TransferWithProofs.Transaction, nil + }, + RetrieveNewestBinaryEntryFunc: func(account proto.Recipient, key string) (*proto.BinaryDataEntry, error) { + t.Log("key: ", key) + return nil, errors.New("not found") + }, + RetrieveNewestIntegerEntryFunc: func(account proto.Recipient, key string) (*proto.IntegerDataEntry, error) { + t.Logf("acc: %q, key %s", account, key) + return &proto.IntegerDataEntry{ + Value: 0, + }, nil + }, + } + env := &MockRideEnvironment{ + transactionFunc: testTransferObject, + stateFunc: func() types.SmartState { + return state + }, + schemeFunc: func() byte { + return 'T' + }, + thisFunc: func() rideType { + return rideAddress{} + }, + heightFunc: func() rideInt { + return 1 + }, + } + + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(t, err) + + tree, err := Parse(src) + require.NoError(t, err) + assert.NotNil(t, tree) + + script, err := CompileVerifier("", tree) + require.NoError(t, err) + assert.NotNil(t, script) + + /** + require.Equal(t, + []byte{ + OpReturn, + OpRef, 0, 0, + OpRef, 0, 0, + OpCall, 0, 0, 0, 2, + OpJumpIfFalse, 0, 0, 0, 0, 0, 0, + OpRef, 0, 0, OpReturn, //true branch + OpRef, 0, 0, OpReturn, //false branch + OpReturn, + OpRef, 0, 0, OpReturn, // function cba + OpRef, 0, 0, OpReturn, // function abc + }, + script.ByteCode) + /**/ + + rs, _ := script.Verify(env) + require.Equal(t, rs.Result(), false) + //require.Equal(t, err.Error(), "terminated execution by throw with message \"1\"") +} + +/* + +{-# STDLIB_VERSION 3 #-} +{-# SCRIPT_TYPE ACCOUNT #-} +{-# CONTENT_TYPE DAPP #-} + +func getStringByAddressAndKey(address: Address, key: String) = match getString(address, key) { + case a: String => + a + case _ => + "" +} + +func getStringByKey(key: String) = match getString(this, key) { + case a: String => + a + case _ => + "" +} + +let LastConfirmTxKey = "last_confirm_tx" +let NeutrinoContractKey = "neutrino_contract" +let ControlContractKey = "control_contract" +let neutrinoContract = addressFromStringValue(getStringByKey(NeutrinoContractKey)) +let controlContract = addressFromStringValue(getStringByAddressAndKey(neutrinoContract, ControlContractKey)) +let lastConfirmTx = getStringByAddressAndKey(controlContract, LastConfirmTxKey) + +@Verifier(tx) +func verify () = (lastConfirmTx == toBase58String(tx.id)) + +*/ +func TestNoDuplicateCallToState(t *testing.T) { + source := `AAIDAAAAAAAAAAIIAQAAAAgBAAAAGGdldFN0cmluZ0J5QWRkcmVzc0FuZEtleQAAAAIAAAAHYWRkcmVzcwAAAANrZXkEAAAAByRtYXRjaDAJAAQdAAAAAgUAAAAHYWRkcmVzcwUAAAADa2V5AwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAAZTdHJpbmcEAAAAAWEFAAAAByRtYXRjaDAFAAAAAWECAAAAAAEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABAAAAA2tleQQAAAAHJG1hdGNoMAkABB0AAAACBQAAAAR0aGlzBQAAAANrZXkDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAABlN0cmluZwQAAAABYQUAAAAHJG1hdGNoMAUAAAABYQIAAAAAAAAAABBMYXN0Q29uZmlybVR4S2V5AgAAAA9sYXN0X2NvbmZpcm1fdHgAAAAAE05ldXRyaW5vQ29udHJhY3RLZXkCAAAAEW5ldXRyaW5vX2NvbnRyYWN0AAAAABJDb250cm9sQ29udHJhY3RLZXkCAAAAEGNvbnRyb2xfY29udHJhY3QAAAAAEG5ldXRyaW5vQ29udHJhY3QJAQAAABxAZXh0clVzZXIoYWRkcmVzc0Zyb21TdHJpbmcpAAAAAQkBAAAADmdldFN0cmluZ0J5S2V5AAAAAQUAAAATTmV1dHJpbm9Db250cmFjdEtleQAAAAAPY29udHJvbENvbnRyYWN0CQEAAAAcQGV4dHJVc2VyKGFkZHJlc3NGcm9tU3RyaW5nKQAAAAEJAQAAABhnZXRTdHJpbmdCeUFkZHJlc3NBbmRLZXkAAAACBQAAABBuZXV0cmlub0NvbnRyYWN0BQAAABJDb250cm9sQ29udHJhY3RLZXkAAAAADWxhc3RDb25maXJtVHgJAQAAABhnZXRTdHJpbmdCeUFkZHJlc3NBbmRLZXkAAAACBQAAAA9jb250cm9sQ29udHJhY3QFAAAAEExhc3RDb25maXJtVHhLZXkAAAAAAAAAAQAAAAJ0eAEAAAAGdmVyaWZ5AAAAAAkAAAAAAAACBQAAAA1sYXN0Q29uZmlybVR4CQACWAAAAAEIBQAAAAJ0eAAAAAJpZJO+lgc=` + + state := &MockSmartState{ + NewestTransactionByIDFunc: func(_ []byte) (proto.Transaction, error) { + return byte_helpers.TransferWithProofs.Transaction, nil + }, + //RetrieveNewestBinaryEntryFunc: func(account proto.Recipient, key string) (*proto.BinaryDataEntry, error) { + // t.Log("key: ", key) + // return nil, errors.New("not found") + //}, + RetrieveNewestStringEntryFunc: func(account proto.Recipient, key string) (*proto.StringDataEntry, error) { + switch key { + case "neutrino_contract": + return &proto.StringDataEntry{Value: "3MVHscMp4C3JjeaEiZB6fxeomPZdYEHyamY"}, nil + case "control_contract": + return &proto.StringDataEntry{Value: "3MQdbE6dK59FHxh5rf4biQdyXhdEf3L1R5W"}, nil + case "last_confirm_tx": + return &proto.StringDataEntry{Value: "3M9uzVzrAAYEKSHXzKaPhw7iQjwDi9BRJysHZHpbqXJm"}, nil + + } + panic(key) + }, + RetrieveNewestIntegerEntryFunc: func(account proto.Recipient, key string) (*proto.IntegerDataEntry, error) { + v, err := strconv.ParseInt(key, 10, 64) + if err != nil { + return nil, err + } + return &proto.IntegerDataEntry{ + Value: v, + }, nil + }, + } + env := &MockRideEnvironment{ + transactionFunc: testTransferObject, + stateFunc: func() types.SmartState { + return state + }, + schemeFunc: func() byte { + return 'S' + }, + thisFunc: func() rideType { + b := [26]byte{1, 83, 122, 149, 83, 66, 227, 147, 59, 198, 33, 214, 105, 255, 17, 4, 168, 100, 213, 112, 143, 31, 192, 98, 166, 126} + return rideAddress(b) + }, + heightFunc: func() rideInt { + return 1 + }, + } + + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(t, err) + + tree, err := Parse(src) + require.NoError(t, err) + assert.NotNil(t, tree) + + script, err := CompileVerifier("", tree) + require.NoError(t, err) + assert.NotNil(t, script) + + rs, err := script.Verify(env) + require.NoError(t, err) + for _, c := range rs.Calls() { + t.Log(c) + } + require.NoError(t, err) + require.False(t, rs.Result()) +} + +/* +{-# STDLIB_VERSION 3 #-} +{-# SCRIPT_TYPE ACCOUNT #-} +{-# CONTENT_TYPE DAPP #-} + +@Verifier(tx) +func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey) +*/ +func TestDappVerifyVm(t *testing.T) { + source := `AAIDAAAAAAAAAAIIAQAAAAAAAAAAAAAAAQAAAAJ0eAEAAAAGdmVyaWZ5AAAAAAkAAfQAAAADCAUAAAACdHgAAAAJYm9keUJ5dGVzCQABkQAAAAIIBQAAAAJ0eAAAAAZwcm9vZnMAAAAAAAAAAAAIBQAAAAJ0eAAAAA9zZW5kZXJQdWJsaWNLZXlQ99ml` + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(t, err) + + env := &MockRideEnvironment{ + transactionFunc: testTransferObject, + schemeFunc: func() byte { + return 'S' + }, + checkMessageLengthFunc: func(in1 int) bool { + return true + }, + } + + tree, err := Parse(src) + require.NoError(t, err) + assert.NotNil(t, tree) + + script, err := CompileVerifier("", tree) + require.NoError(t, err) + assert.NotNil(t, script) + + rs, err := script.Verify(env) + require.NoError(t, err) + require.Equal(t, rs.Result(), true) +} + +/* +{-# STDLIB_VERSION 3 #-} +{-# SCRIPT_TYPE ACCOUNT #-} +{-# CONTENT_TYPE EXPRESSION #-} + +match (tx) { + case e:ExchangeTransaction => isDefined(e.sellOrder.assetPair.priceAsset) + case _ => throw("err") + } +*/ +func TestMultipleProperty(t *testing.T) { + source := `AwQAAAAHJG1hdGNoMAUAAAACdHgDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAE0V4Y2hhbmdlVHJhbnNhY3Rpb24EAAAAAWUFAAAAByRtYXRjaDAJAQAAAAlpc0RlZmluZWQAAAABCAgIBQAAAAFlAAAACXNlbGxPcmRlcgAAAAlhc3NldFBhaXIAAAAKcHJpY2VBc3NldAkAAAIAAAABAgAAAANlcnIsqB0K` + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(t, err) + + tree, err := Parse(src) + require.NoError(t, err) + assert.NotNil(t, tree) + + script, err := CompileVerifier("", tree) + require.NoError(t, err) + assert.NotNil(t, script) + + env := &MockRideEnvironment{ + transactionFunc: testExchangeWithProofsToObject, + } + + rs, err := script.Verify(env) + require.NoError(t, err) + require.Equal(t, rs.Result(), true) +} + +func TestProperty(t *testing.T) { + t.Run("test simple property", func(t *testing.T) { + n := &PropertyNode{ + Name: "id", + Object: &ReferenceNode{Name: "tx"}, + } + tree := &Tree{ + LibVersion: 3, + AppVersion: scriptApplicationVersion, + Verifier: n, + } + + script, err := CompileVerifier("", tree) + require.NoError(t, err) + assert.NotNil(t, script) + + env := &MockRideEnvironment{ + transactionFunc: testExchangeWithProofsToObject, + } + + require.Equal(t, + []byte{ + OpReturn, + OpReturn, + OpRef, 255, 255, + OpRef, 0, 202, + OpProperty, + OpReturn, + OpReturn, + OpReturn, + }, + script.ByteCode) + _, err = script.run(env, nil) + require.NoError(t, err) + }) + t.Run("test multiple property", func(t *testing.T) { + n := &PropertyNode{ + Name: "assetPair", + Object: &PropertyNode{ + Name: "sellOrder", + Object: &ReferenceNode{Name: "tx"}, + }} + tree := &Tree{ + LibVersion: 3, + AppVersion: scriptApplicationVersion, + Verifier: n, + } + + script, err := CompileVerifier("", tree) + require.NoError(t, err) + assert.NotNil(t, script) + env := &MockRideEnvironment{ + transactionFunc: testExchangeWithProofsToObject, + } + + require.Equal(t, + []byte{ + OpReturn, + OpReturn, + OpRef, 0, 203, + OpRef, 0, 204, + OpProperty, + OpReturn, + OpReturn, + OpReturn, + + OpRef, 255, 255, + OpRef, 0, 205, + OpProperty, + OpReturn, + OpReturn, + }, + script.ByteCode) + _, err = script.run(env, nil) + require.NoError(t, err) + }) +} + +/* +{-# STDLIB_VERSION 4 #-} +{-# CONTENT_TYPE EXPRESSION #-} +{-# SCRIPT_TYPE ACCOUNT #-} + +let x = 1 + 1 +x == x +*/ +func TestCacheInMain(t *testing.T) { + source := `BAQAAAABeAkAAGQAAAACAAAAAAAAAAABAAAAAAAAAAABCQAAAAAAAAIFAAAAAXgFAAAAAXgu3TzS` + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(t, err) + + tree, err := Parse(src) + require.NoError(t, err) + assert.NotNil(t, tree) + + script, err := CompileVerifier("", tree) + require.NoError(t, err) + assert.NotNil(t, script) + + env := &MockRideEnvironment{ + transactionFunc: testExchangeWithProofsToObject, + } + + /** + require.Equal(t, []byte{ + OpReturn, + 0xe, 0x0, 0xc9, + OpReturn, + OpRef, 0x0, 0xc9, + OpCache, 0x0, 0xc9, + OpRef, 0x0, 0xc9, + OpCache, 0x0, 0xc9, + OpExternalCall, 0x0, 0x3, 0x0, 0x2, OpReturn, + }, script.ByteCode) + /**/ + + rs, err := script.Verify(env) + require.NoError(t, err) + require.Equal(t, 2, len(rs.Calls())) // plus & eq + require.Equal(t, rs.Result(), true) +} + +/* +{-# STDLIB_VERSION 4 #-} +{-# CONTENT_TYPE EXPRESSION #-} +{-# SCRIPT_TYPE ACCOUNT #-} +func abc() = { + 1 + 1 +} +let info = abc() +info == info +*/ +func TestCacheFunctionArgumentsCalls(t *testing.T) { + source := `BAoBAAAAA2FiYwAAAAAJAABkAAAAAgAAAAAAAAAAAQAAAAAAAAAAAQQAAAAEaW5mbwkBAAAAA2FiYwAAAAAJAAAAAAAAAgUAAAAEaW5mbwUAAAAEaW5mby35E+E=` + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(t, err) + + tree, err := Parse(src) + require.NoError(t, err) + assert.NotNil(t, tree) + + script, err := CompileVerifier("", tree) + require.NoError(t, err) + assert.NotNil(t, script) + + env := &MockRideEnvironment{ + transactionFunc: testExchangeWithProofsToObject, + } + + rs, err := script.Verify(env) + require.NoError(t, err) + require.Equal(t, 2, len(rs.Calls())) + require.Equal(t, true, rs.Result()) +} + +/* +{-# STDLIB_VERSION 4 #-} +{-# CONTENT_TYPE EXPRESSION #-} +{-# SCRIPT_TYPE ACCOUNT #-} + +func abc() = { + let x = 1 + 1 + x == x +} +abc() +*/ +func TestCacheInFunc(t *testing.T) { + source := `BAoBAAAAA2FiYwAAAAAEAAAAAXgJAABkAAAAAgAAAAAAAAAAAQAAAAAAAAAAAQkAAAAAAAACBQAAAAF4BQAAAAF4CQEAAAADYWJjAAAAAJz8J24=` + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(t, err) + + tree, err := Parse(src) + require.NoError(t, err) + assert.NotNil(t, tree) + + script, err := CompileVerifier("", tree) + require.NoError(t, err) + assert.NotNil(t, script) + + env := &MockRideEnvironment{ + transactionFunc: testExchangeWithProofsToObject, + } + + rs, err := script.Verify(env) + require.NoError(t, err) + require.Equal(t, 2, len(rs.Calls())) + require.Equal(t, rs.Result(), true) +} + +/* +{-# STDLIB_VERSION 4 #-} +{-# CONTENT_TYPE EXPRESSION #-} +{-# SCRIPT_TYPE ACCOUNT #-} +func abc(x: Int) = x == x +let y = getIntegerValue(this, "a") +abc(y) +*/ +func TestCacheFuncArgs(t *testing.T) { + source := `BAoBAAAAA2FiYwAAAAEAAAABeAkAAAAAAAACBQAAAAF4BQAAAAF4BAAAAAF5CQEAAAARQGV4dHJOYXRpdmUoMTA1MCkAAAACBQAAAAR0aGlzAgAAAAFhCQEAAAADYWJjAAAAAQUAAAABeYsrE7g=` + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(t, err) + + tree, err := Parse(src) + require.NoError(t, err) + assert.NotNil(t, tree) + + script, err := CompileVerifier("", tree) + require.NoError(t, err) + assert.NotNil(t, script) + state := &MockSmartState{ + RetrieveNewestIntegerEntryFunc: func(account proto.Recipient, key string) (*proto.IntegerDataEntry, error) { + return &proto.IntegerDataEntry{ + Value: 1, + }, nil + }, + } + env := &MockRideEnvironment{ + stateFunc: func() types.SmartState { + return state + }, + thisFunc: func() rideType { + return rideAddress{} + }, + } + + rs, err := script.Verify(env) + require.NoError(t, err) + require.Equal(t, true, rs.Result()) + require.Equal(t, 2, len(rs.Calls())) + // only 1 native call to state + require.Equal(t, "@extrNative(1050)", rs.Calls()[0].name) + // native compare + require.Equal(t, "0", rs.Calls()[1].name) +} + +/* +let x = { + let y = true; + y; +} +x +*/ +func TestLetInLet(t *testing.T) { + source := `BAQAAAABeAQAAAABeQYFAAAAAXkFAAAAAXhCPj2C` + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(t, err) + + tree, err := Parse(src) + require.NoError(t, err) + assert.NotNil(t, tree) + + script, err := CompileVerifier("", tree) + t.Log(Decompiler(tree.Verifier)) + require.NoError(t, err) + assert.NotNil(t, script) + + env := &MockRideEnvironment{ + transactionFunc: testExchangeWithProofsToObject, + } + + /* * + require.Equal(t, + []byte{ + OpReturn, + OpRef, 0, 1, + OpClearCache, 0, 2, + OpClearCache, 0, 1, + OpReturn, + OpRef, 0, 2, + //OpReturn, + }, + script.ByteCode[:11]) + /**/ + + rs, err := script.Verify(env) + require.NoError(t, err) + require.Equal(t, true, rs.Result()) +} + +/* +{-# STDLIB_VERSION 3 #-} +{-# SCRIPT_TYPE ACCOUNT #-} +{-# CONTENT_TYPE DAPP #-} + + +@Callable(i) +func deposit () = { + let pmt = extract(i.payment) + if (isDefined(pmt.assetId)) + then throw("can hold waves only at the moment") + else { + let currentKey = toBase58String(i.caller.bytes) + let currentAmount = match getInteger(this, currentKey) { + case a: Int => + a + case _ => + 0 + } + let newAmount = (currentAmount + pmt.amount) + WriteSet([DataEntry(currentKey, newAmount)]) + } + } + + + +@Callable(i) +func withdraw (amount) = { + let currentKey = toBase58String(i.caller.bytes) + let currentAmount = match getInteger(this, currentKey) { + case a: Int => + a + case _ => + 0 + } + let newAmount = (currentAmount - amount) + if ((0 > amount)) + then throw("Can't withdraw negative amount") + else if ((0 > newAmount)) + then throw("Not enough balance") + else ScriptResult(WriteSet([DataEntry(currentKey, newAmount)]), TransferSet([ScriptTransfer(i.caller, amount, unit)])) + } + + +@Verifier(tx) +func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey) +*/ +func TestDDaa(t *testing.T) { + source := `AAIDAAAAAAAAAAkIARIAEgMKAQEAAAAAAAAAAgAAAAFpAQAAAAdkZXBvc2l0AAAAAAQAAAADcG10CQEAAAAHZXh0cmFjdAAAAAEIBQAAAAFpAAAAB3BheW1lbnQDCQEAAAAJaXNEZWZpbmVkAAAAAQgFAAAAA3BtdAAAAAdhc3NldElkCQAAAgAAAAECAAAAIWNhbiBob2xkIHdhdmVzIG9ubHkgYXQgdGhlIG1vbWVudAQAAAAKY3VycmVudEtleQkAAlgAAAABCAgFAAAAAWkAAAAGY2FsbGVyAAAABWJ5dGVzBAAAAA1jdXJyZW50QW1vdW50BAAAAAckbWF0Y2gwCQAEGgAAAAIFAAAABHRoaXMFAAAACmN1cnJlbnRLZXkDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAA0ludAQAAAABYQUAAAAHJG1hdGNoMAUAAAABYQAAAAAAAAAAAAQAAAAJbmV3QW1vdW50CQAAZAAAAAIFAAAADWN1cnJlbnRBbW91bnQIBQAAAANwbXQAAAAGYW1vdW50CQEAAAAIV3JpdGVTZXQAAAABCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACBQAAAApjdXJyZW50S2V5BQAAAAluZXdBbW91bnQFAAAAA25pbAAAAAFpAQAAAAh3aXRoZHJhdwAAAAEAAAAGYW1vdW50BAAAAApjdXJyZW50S2V5CQACWAAAAAEICAUAAAABaQAAAAZjYWxsZXIAAAAFYnl0ZXMEAAAADWN1cnJlbnRBbW91bnQEAAAAByRtYXRjaDAJAAQaAAAAAgUAAAAEdGhpcwUAAAAKY3VycmVudEtleQMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAADSW50BAAAAAFhBQAAAAckbWF0Y2gwBQAAAAFhAAAAAAAAAAAABAAAAAluZXdBbW91bnQJAABlAAAAAgUAAAANY3VycmVudEFtb3VudAUAAAAGYW1vdW50AwkAAGYAAAACAAAAAAAAAAAABQAAAAZhbW91bnQJAAACAAAAAQIAAAAeQ2FuJ3Qgd2l0aGRyYXcgbmVnYXRpdmUgYW1vdW50AwkAAGYAAAACAAAAAAAAAAAABQAAAAluZXdBbW91bnQJAAACAAAAAQIAAAASTm90IGVub3VnaCBiYWxhbmNlCQEAAAAMU2NyaXB0UmVzdWx0AAAAAgkBAAAACFdyaXRlU2V0AAAAAQkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgUAAAAKY3VycmVudEtleQUAAAAJbmV3QW1vdW50BQAAAANuaWwJAQAAAAtUcmFuc2ZlclNldAAAAAEJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAAWkAAAAGY2FsbGVyBQAAAAZhbW91bnQFAAAABHVuaXQFAAAAA25pbAAAAAEAAAACdHgBAAAABnZlcmlmeQAAAAAJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAAACAUAAAACdHgAAAAPc2VuZGVyUHVibGljS2V54232jg==` + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(t, err) + + tree, err := Parse(src) + require.NoError(t, err) + assert.NotNil(t, tree) + + script, err := CompileTree("", tree) + require.NoError(t, err) + require.NotNil(t, script) + require.Equal(t, 4, len(script.EntryPoints)) +} + +func BenchmarkVm(b *testing.B) { + source := "BAoBAAAABmdldEludAAAAAEAAAADa2V5BAAAAAckbWF0Y2gwCQAEGgAAAAIFAAAABHRoaXMFAAAAA2tleQMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAADSW50BAAAAAF4BQAAAAckbWF0Y2gwBQAAAAF4AAAAAAAAAAAABAAAAAFhCQEAAAAGZ2V0SW50AAAAAQIAAAABNQQAAAABYgkBAAAABmdldEludAAAAAECAAAAATYJAAAAAAAAAgUAAAABYQUAAAABYkOIJQA=" + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(b, err) + + tree, err := Parse(src) + require.NoError(b, err) + + script, err := CompileTree("", tree) + require.NoError(b, err) + + state := &MockSmartState{ + NewestTransactionByIDFunc: func(_ []byte) (proto.Transaction, error) { + return byte_helpers.TransferWithProofs.Transaction, nil + }, + RetrieveNewestBinaryEntryFunc: func(account proto.Recipient, key string) (*proto.BinaryDataEntry, error) { + return nil, errors.New("not found") + }, + RetrieveNewestIntegerEntryFunc: func(account proto.Recipient, key string) (*proto.IntegerDataEntry, error) { + v, err := strconv.ParseInt(key, 10, 64) + if err != nil { + return nil, err + } + return &proto.IntegerDataEntry{ + Value: v, + }, nil + }, + } + + env := &MockRideEnvironment{ + transactionFunc: testExchangeWithProofsToObject, + checkMessageLengthFunc: func(in1 int) bool { + return true + }, + stateFunc: func() types.SmartState { + return state + }, + thisFunc: func() rideType { + return rideAddress{} + }, + } + + b.ReportAllocs() + b.StopTimer() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + b.StartTimer() + rs, err := script.Verify(env) + require.Equal(b, 5, len(rs.Calls())) + b.StopTimer() + require.NoError(b, err) + } +} + +func BenchmarkTree(b *testing.B) { + source := "BAoBAAAABmdldEludAAAAAEAAAADa2V5BAAAAAckbWF0Y2gwCQAEGgAAAAIFAAAABHRoaXMFAAAAA2tleQMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAADSW50BAAAAAF4BQAAAAckbWF0Y2gwBQAAAAF4AAAAAAAAAAAABAAAAAFhCQEAAAAGZ2V0SW50AAAAAQIAAAABNQQAAAABYgkBAAAABmdldEludAAAAAECAAAAATYJAAAAAAAAAgUAAAABYQUAAAABYkOIJQA=" + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(b, err) + + tree, err := Parse(src) + require.NoError(b, err) + + state := &MockSmartState{ + NewestTransactionByIDFunc: func(_ []byte) (proto.Transaction, error) { + return byte_helpers.TransferWithProofs.Transaction, nil + }, + RetrieveNewestBinaryEntryFunc: func(account proto.Recipient, key string) (*proto.BinaryDataEntry, error) { + return nil, errors.New("not found") + }, + RetrieveNewestIntegerEntryFunc: func(account proto.Recipient, key string) (*proto.IntegerDataEntry, error) { + v, err := strconv.ParseInt(key, 10, 64) + if err != nil { + return nil, err + } + return &proto.IntegerDataEntry{ + Value: v, + }, nil + }, + } + + env := &MockRideEnvironment{ + transactionFunc: testExchangeWithProofsToObject, + checkMessageLengthFunc: func(in1 int) bool { + return true + }, + stateFunc: func() types.SmartState { + return state + }, + thisFunc: func() rideType { + return rideAddress{} + }, + } + + b.ReportAllocs() + b.StopTimer() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + b.StartTimer() + rs, err := CallTreeVerifier(env, tree) + b.StopTimer() + require.NoError(b, err) + require.Equal(b, 5, len(rs.Calls())) + + } +} + +func BenchmarkVmWithDeserialize(b *testing.B) { + source := "BAoBAAAABmdldEludAAAAAEAAAADa2V5BAAAAAckbWF0Y2gwCQAEGgAAAAIFAAAABHRoaXMFAAAAA2tleQMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAADSW50BAAAAAF4BQAAAAckbWF0Y2gwBQAAAAF4AAAAAAAAAAAABAAAAAFhCQEAAAAGZ2V0SW50AAAAAQIAAAABNQQAAAABYgkBAAAABmdldEludAAAAAECAAAAATYJAAAAAAAAAgUAAAABYQUAAAABYkOIJQA=" + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(b, err) + + tree, err := Parse(src) + require.NoError(b, err) + + script, err := CompileTree("", tree) + require.NoError(b, err) + + ser := NewSerializer() + err = script.Serialize(ser) + require.NoError(b, err) + + bts := ser.Source() + + state := &MockSmartState{ + NewestTransactionByIDFunc: func(_ []byte) (proto.Transaction, error) { + return byte_helpers.TransferWithProofs.Transaction, nil + }, + RetrieveNewestBinaryEntryFunc: func(account proto.Recipient, key string) (*proto.BinaryDataEntry, error) { + return nil, errors.New("not found") + }, + RetrieveNewestIntegerEntryFunc: func(account proto.Recipient, key string) (*proto.IntegerDataEntry, error) { + v, err := strconv.ParseInt(key, 10, 64) + if err != nil { + return nil, err + } + return &proto.IntegerDataEntry{ + Value: v, + }, nil + }, + } + + env := &MockRideEnvironment{ + transactionFunc: testExchangeWithProofsToObject, + checkMessageLengthFunc: func(in1 int) bool { + return true + }, + stateFunc: func() types.SmartState { + return state + }, + thisFunc: func() rideType { + return rideAddress{} + }, + } + + b.ReportAllocs() + b.StopTimer() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + b.StartTimer() + exe, err := DeserializeExecutable(bts) + require.NoError(b, err) + rs, err := exe.Verify(env) + require.Equal(b, 5, len(rs.Calls())) + b.StopTimer() + require.NoError(b, err) + } +} + +func BenchmarkTreeWithDeserialize(b *testing.B) { + source := "BAoBAAAABmdldEludAAAAAEAAAADa2V5BAAAAAckbWF0Y2gwCQAEGgAAAAIFAAAABHRoaXMFAAAAA2tleQMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAADSW50BAAAAAF4BQAAAAckbWF0Y2gwBQAAAAF4AAAAAAAAAAAABAAAAAFhCQEAAAAGZ2V0SW50AAAAAQIAAAABNQQAAAABYgkBAAAABmdldEludAAAAAECAAAAATYJAAAAAAAAAgUAAAABYQUAAAABYkOIJQA=" + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(b, err) + + state := &MockSmartState{ + NewestTransactionByIDFunc: func(_ []byte) (proto.Transaction, error) { + return byte_helpers.TransferWithProofs.Transaction, nil + }, + RetrieveNewestBinaryEntryFunc: func(account proto.Recipient, key string) (*proto.BinaryDataEntry, error) { + return nil, errors.New("not found") + }, + RetrieveNewestIntegerEntryFunc: func(account proto.Recipient, key string) (*proto.IntegerDataEntry, error) { + v, err := strconv.ParseInt(key, 10, 64) + if err != nil { + return nil, err + } + return &proto.IntegerDataEntry{ + Value: v, + }, nil + }, + } + + env := &MockRideEnvironment{ + transactionFunc: testExchangeWithProofsToObject, + checkMessageLengthFunc: func(in1 int) bool { + return true + }, + stateFunc: func() types.SmartState { + return state + }, + thisFunc: func() rideType { + return rideAddress{} + }, + } + + b.ReportAllocs() + b.StopTimer() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + b.StartTimer() tree, err := Parse(src) - require.NoError(t, err, test.comment) - assert.NotNil(t, tree, test.comment) + require.NoError(b, err) + rs, err := CallTreeVerifier(env, tree) + b.StopTimer() + require.NoError(b, err) + require.Equal(b, 5, len(rs.Calls())) + } +} - rideScript, err := Compile(tree) - require.NoError(t, err, test.comment) - assert.NotNil(t, rideScript, test.comment) - script, ok := rideScript.(*DAppScript) - require.True(t, ok, test.comment) +/* +{-# STDLIB_VERSION 4 #-} +{-# CONTENT_TYPE EXPRESSION #-} +{-# SCRIPT_TYPE ACCOUNT #-} + +if (true) then { + func a() = { + true + } + a() +} else { + func b() = { + false + } + b() +} +*/ + +func TestFuncInCondState(t *testing.T) { + source := `BAMGCgEAAAABYQAAAAAGCQEAAAABYQAAAAAKAQAAAAFiAAAAAAcJAQAAAAFiAAAAAObLaEQ=` + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(t, err) + state := &MockSmartState{ + NewestTransactionByIDFunc: func(_ []byte) (proto.Transaction, error) { + return byte_helpers.TransferWithProofs.Transaction, nil + }, + RetrieveNewestBinaryEntryFunc: func(account proto.Recipient, key string) (*proto.BinaryDataEntry, error) { + return nil, errors.New("not found") + }, + RetrieveNewestIntegerEntryFunc: func(account proto.Recipient, key string) (*proto.IntegerDataEntry, error) { + v, err := strconv.ParseInt(key, 10, 64) + if err != nil { + return nil, err + } + return &proto.IntegerDataEntry{ + Value: v, + }, nil + }, + NewestAccountBalanceFunc: func(account proto.Recipient, asset []byte) (uint64, error) { + return 0, nil + }, + } + + env := &MockRideEnvironment{ + transactionFunc: testExchangeWithProofsToObject, + checkMessageLengthFunc: func(in1 int) bool { + return true + }, + stateFunc: func() types.SmartState { + return state + }, + thisFunc: func() rideType { + return rideAddress{} + }, + } + + tree, err := Parse(src) + require.NoError(t, err) + rs1, _ := CallTreeVerifier(env, tree) + for i, c := range rs1.Calls() { + t.Log(i, " ", c) + } + + exe, err := CompileTree("", tree) + require.NoError(t, err) + + rs2, err := exe.Verify(env) + require.NoError(t, err) + for i, c := range rs2.Calls() { + t.Log(i, " ", c) + } + require.True(t, rs1.Eq(rs2)) +} + +/* + + */ + +func Test111111(t *testing.T) { + source := `AwoBAAAAA2luYwAAAAEAAAABdgkAAGQAAAACBQAAAAF2AAAAAAAAAAABCgEAAAAEY2FsbAAAAAEAAAADaW5jCQEAAAADaW5jAAAAAQUAAAADaW5jCQAAAAAAAAIJAQAAAARjYWxsAAAAAQAAAAAAAAAAAgAAAAAAAAAAAxgTXMY=` + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(t, err) + state := &MockSmartState{ + NewestTransactionByIDFunc: func(_ []byte) (proto.Transaction, error) { + return byte_helpers.TransferWithProofs.Transaction, nil + }, + RetrieveNewestBinaryEntryFunc: func(account proto.Recipient, key string) (*proto.BinaryDataEntry, error) { + return nil, errors.New("not found") + }, + RetrieveNewestIntegerEntryFunc: func(account proto.Recipient, key string) (*proto.IntegerDataEntry, error) { + v, err := strconv.ParseInt(key, 10, 64) + if err != nil { + return nil, err + } + return &proto.IntegerDataEntry{ + Value: v, + }, nil + }, + NewestAccountBalanceFunc: func(account proto.Recipient, asset []byte) (uint64, error) { + return 0, nil + }, + } - code := hex.EncodeToString(script.Code) - assert.Equal(t, test.code, code, test.comment) - assert.ElementsMatch(t, test.constants, script.Constants, test.comment) - assert.Equal(t, test.entries, script.EntryPoints, test.comment) + env := &MockRideEnvironment{ + transactionFunc: testExchangeWithProofsToObject, + checkMessageLengthFunc: func(in1 int) bool { + return true + }, + stateFunc: func() types.SmartState { + return state + }, + thisFunc: func() rideType { + return rideAddress{} + }, + invocationFunc: func() rideObject { + return rideObject{} + }, } + + tree, err := Parse(src) + require.NoError(t, err) + + exe, err := CompileTree("", tree) + require.NoError(t, err) + rs, err := exe.Verify(env) + require.NoError(t, err) + for i, c := range rs.Calls() { + t.Log(i, " ", c) + } +} + +/** +let height = height +height != 0 +*/ +func TestShadowedVariable(t *testing.T) { + source := `AwoBAAAAD2dldFByaWNlSGlzdG9yeQAAAAEAAAAGaGVpZ2h0BQAAAAZoZWlnaHQJAQAAAAIhPQAAAAIJAQAAAA9nZXRQcmljZUhpc3RvcnkAAAABBQAAAAZoZWlnaHQAAAAAAAAAAADe0Skk` + + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(t, err) + + tree, err := Parse(src) + require.NoError(t, err) + tree = MustExpand(tree) + require.Equal(t, "(let height$getPriceHistory = { height }; height$getPriceHistory != 0)", DecompileTree(tree)) + + script, err := CompileTree("", tree) + require.NoError(t, err) + + rs, err := script.Verify(defaultEnv) + require.NoError(t, err) + require.Equal(t, true, rs.Result()) +} + +/** +{-# STDLIB_VERSION 3 #-} +{-# SCRIPT_TYPE ACCOUNT #-} +{-# CONTENT_TYPE EXPRESSION #-} + +let prevOrder = false +func internal(prevOrder: Boolean) = { + if (prevOrder) + then false + else true +} +if (false) + then false + else internal(prevOrder) +*/ +func TestShadowedVariableInConditionStmt(t *testing.T) { + source := `AwQAAAAJcHJldk9yZGVyBwoBAAAACGludGVybmFsAAAAAQAAAAlwcmV2T3JkZXIDBQAAAAlwcmV2T3JkZXIHBgMHBwkBAAAACGludGVybmFsAAAAAQUAAAAJcHJldk9yZGVyxqI+QQ==` + + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(t, err) + + tree, err := Parse(src) + require.NoError(t, err) + tree = MustExpand(tree) + require.True(t, tree.Expanded) + script, err := CompileTree("", tree) + require.NoError(t, err) + + rs, err := script.Verify(defaultEnv) + require.NoError(t, err) + require.Equal(t, true, rs.Result()) } diff --git a/pkg/ride/decompiler.go b/pkg/ride/decompiler.go new file mode 100644 index 000000000..a93a07f7b --- /dev/null +++ b/pkg/ride/decompiler.go @@ -0,0 +1,209 @@ +package ride + +import ( + "fmt" + "strings" + + "github.com/mr-tron/base58" +) + +type detreeType = func(s *strings.Builder, tree Node) + +func prefix(s *strings.Builder, name string, nodes []Node, f detreeType) { + s.WriteString(name) + s.WriteString("(") + for i, a := range nodes { + f(s, a) + if i+1 != len(nodes) { + s.WriteString(",") + } + } + s.WriteString(")") +} + +func infix(s *strings.Builder, name string, nodes []Node, f detreeType) { + s.WriteString("(") + f(s, nodes[0]) + s.WriteString(fmt.Sprintf(" %s ", name)) + f(s, nodes[1]) + s.WriteString(")") +} + +var defuncs = map[string]func(s *strings.Builder, name string, nodes []Node, f detreeType){ + "0": func(s *strings.Builder, name string, nodes []Node, f detreeType) { + s.WriteString("(") + f(s, nodes[0]) + s.WriteString(" == ") + f(s, nodes[1]) + s.WriteString(")") + }, + "!=": func(s *strings.Builder, name string, nodes []Node, f detreeType) { + s.WriteString("(") + f(s, nodes[0]) + s.WriteString(" != ") + f(s, nodes[1]) + s.WriteString(")") + }, + "100": func(s *strings.Builder, name string, nodes []Node, f detreeType) { + infix(s, "+", nodes, f) + }, + "101": func(s *strings.Builder, name string, nodes []Node, f detreeType) { + infix(s, "-", nodes, f) + }, + "102": func(s *strings.Builder, name string, nodes []Node, f detreeType) { + infix(s, ">", nodes, f) + }, + "103": func(s *strings.Builder, name string, nodes []Node, f detreeType) { + infix(s, ">=", nodes, f) + }, + "104": func(s *strings.Builder, name string, nodes []Node, f detreeType) { + infix(s, "*", nodes, f) + }, + "105": func(s *strings.Builder, name string, nodes []Node, f detreeType) { + infix(s, "/", nodes, f) + }, + "200": func(s *strings.Builder, name string, nodes []Node, f detreeType) { + prefix(s, "size", nodes, f) + }, + "201": func(s *strings.Builder, name string, nodes []Node, f detreeType) { + prefix(s, "take", nodes, f) + }, + "202": func(s *strings.Builder, name string, nodes []Node, f detreeType) { + prefix(s, "drop", nodes, f) + }, + "203": func(s *strings.Builder, name string, nodes []Node, f detreeType) { + infix(s, "+", nodes, f) + }, + "300": func(s *strings.Builder, name string, nodes []Node, f detreeType) { + infix(s, "+", nodes, f) + }, + "1": func(s *strings.Builder, name string, nodes []Node, f detreeType) { + prefix(s, "instanceOf", nodes, f) + }, + "401": func(s *strings.Builder, name string, nodes []Node, f detreeType) { + prefix(s, "getList", nodes, f) + }, + "410": func(s *strings.Builder, name string, nodes []Node, f detreeType) { + prefix(s, "toBytes", nodes, f) + }, + "411": func(s *strings.Builder, name string, nodes []Node, f detreeType) { + prefix(s, "toBytes", nodes, f) + }, + "420": func(s *strings.Builder, name string, nodes []Node, f detreeType) { + prefix(s, "toString", nodes, f) + }, + "500": func(s *strings.Builder, name string, nodes []Node, f detreeType) { + prefix(s, "sigVerify", nodes, f) + }, + "504": func(s *strings.Builder, name string, nodes []Node, f detreeType) { + prefix(s, "rsaVerify", nodes, f) + }, + "600": func(s *strings.Builder, name string, nodes []Node, f detreeType) { + prefix(s, "toBase58String", nodes, f) + }, + "604": func(s *strings.Builder, name string, nodes []Node, f detreeType) { + prefix(s, "fromBase64String", nodes, f) + }, + "2": func(s *strings.Builder, name string, nodes []Node, f detreeType) { + prefix(s, "throw", nodes, f) + }, + "1050": func(s *strings.Builder, name string, nodes []Node, f detreeType) { + prefix(s, "getInteger", nodes, f) + }, + "1052": func(s *strings.Builder, name string, nodes []Node, f detreeType) { + prefix(s, "getBinary", nodes, f) + }, + "1201": func(s *strings.Builder, name string, nodes []Node, f detreeType) { + prefix(s, "toInt", nodes, f) + }, +} + +func defunc(s *strings.Builder, name string, nodes []Node, f detreeType) { + if v, ok := defuncs[name]; ok { + v(s, name, nodes, f) + } else { + s.WriteString(name) + s.WriteString("(") + for i, a := range nodes { + detree(s, a) + if len(nodes)-1 != i { + s.WriteString(",") + } + } + s.WriteString(")") + } +} + +func DecompileTree(t *Tree) string { + var s strings.Builder + for _, v := range t.Declarations { + s.WriteString(Decompiler(v)) + } + for _, v := range t.Functions { + s.WriteString(Decompiler(v)) + } + s.WriteString(Decompiler(t.Verifier)) + return strings.TrimSpace(s.String()) +} + +func Decompiler(tree Node) string { + s := &strings.Builder{} + detree(s, tree) + return s.String() +} + +func detree(s *strings.Builder, tree Node) { + switch n := tree.(type) { + case *FunctionDeclarationNode: + if n.invocationParameter != "" { + s.WriteString("@" + n.invocationParameter + "\\n") + } + s.WriteString(fmt.Sprintf("func %s(", n.Name)) + for i, a := range n.Arguments { + s.WriteString(a) + if i+1 != len(n.Arguments) { + s.WriteString(",") + } + } + s.WriteString(") { ") + detree(s, n.Body) + s.WriteString(" } ") + detree(s, n.Block) + case *AssignmentNode: + s.WriteString(fmt.Sprintf("let %s = { ", n.Name)) + detree(s, n.Expression) + s.WriteString(" }; ") + detree(s, n.Block) + case *ConditionalNode: + s.WriteString("if (") + detree(s, n.Condition) + s.WriteString(") { ") + detree(s, n.TrueExpression) + s.WriteString(" } else { ") + detree(s, n.FalseExpression) + s.WriteString(" }") + case *FunctionCallNode: + defunc(s, n.Name, n.Arguments, detree) + case *ReferenceNode: + s.WriteString(n.Name) + case *StringNode: + s.WriteString(`"`) + s.WriteString(n.Value) + s.WriteString(`"`) + case *PropertyNode: + detree(s, n.Object) + s.WriteString(".") + s.WriteString(n.Name) + case *BooleanNode: + s.WriteString(fmt.Sprintf("%t", n.Value)) + case *LongNode: + s.WriteString(fmt.Sprintf("%d", n.Value)) + case *BytesNode: + s.WriteString("b58:") + s.WriteString(base58.Encode(n.Value)) + case nil: + // nothing + default: + panic(fmt.Sprintf("unknown type %T", n)) + } +} diff --git a/pkg/ride/deserializer.go b/pkg/ride/deserializer.go new file mode 100644 index 000000000..f230ba18d --- /dev/null +++ b/pkg/ride/deserializer.go @@ -0,0 +1,184 @@ +package ride + +import ( + "encoding/binary" + + "github.com/pkg/errors" + "github.com/wavesplatform/gowaves/pkg/proto" +) + +type Deserializer struct { + source []byte +} + +func NewDeserializer(source []byte) *Deserializer { + return &Deserializer{source: source} +} + +func (a *Deserializer) readn(n int) ([]byte, error) { + if len(a.source) >= n { + out := a.source[:n] + a.source = a.source[n:] + return out, nil + } + return nil, errors.New("insufficient length") +} + +func (a *Deserializer) Uint16() (uint16, error) { + b, err := a.readn(2) + if err != nil { + return 0, err + } + return binary.BigEndian.Uint16(b), nil +} + +func (a *Deserializer) Byte() (byte, error) { + b, err := a.readn(1) + if err != nil { + return 0, err + } + return b[0], nil +} + +func (a *Deserializer) Bool() (bool, error) { + b, err := a.Byte() + if err != nil { + return false, err + } + switch b { + case sTrue: + return true, nil + case sFalse: + return false, nil + default: + return false, errors.New("unknown byte") + } +} + +func (a *Deserializer) Bytes() ([]byte, error) { + ln, err := a.Uint16() + if err != nil { + return nil, err + } + // This hack is required for correct type assertion. + if ln == 0 { + return []byte(nil), nil + } + return a.readn(int(ln)) +} + +func (a *Deserializer) Map() (uint16, error) { + b, err := a.Byte() + if err != nil { + return 0, err + } + if b != sMap { + return 0, errors.Errorf("expected `Map` byte, found %d", b) + } + size, err := a.Uint16() + return size, err +} + +func (a *Deserializer) RideString() (string, error) { + b, err := a.Byte() + if err != nil { + return "", err + } + if b != sString { + return "", errors.Errorf("expected `String` byte %d, found %d", sString, b) + } + return a.String() +} + +func (a *Deserializer) String() (string, error) { + bts, err := a.Bytes() + if err != nil { + return "", err + } + return string(bts), nil +} + +func (a *Deserializer) Int64() (int64, error) { + bts, err := a.readn(8) + if err != nil { + return 0, err + } + v := binary.BigEndian.Uint64(bts) + return int64(v), nil +} + +func (a *Deserializer) RideValue() (rideType, error) { + b, err := a.Byte() + if err != nil { + return nil, err + } + switch b { + case sNoValue: + return nil, nil + case sTrue: + return rideBoolean(true), nil + case sFalse: + return rideBoolean(false), nil + case sInt: + v, err := a.Int64() + return rideInt(v), err + case sString: + v, err := a.String() + return rideString(v), err + case sBytes: + v, err := a.Bytes() + return rideBytes(v), err + case sAddress: + v, err := a.Bytes() + if err != nil { + return nil, err + } + addr, err := proto.NewAddressFromBytes(v) + if err != nil { + return nil, err + } + return rideAddress(addr), err + case sNamedType: + v, err := a.String() + return rideNamedType{name: v}, err + case sUnit: + return newUnit(nil), nil + case sList: + size, err := a.Uint16() + if err != nil { + return nil, err + } + lst := make(rideList, size) + for i := uint16(0); i < size; i++ { + v, err := a.RideValue() + if err != nil { + return nil, err + } + lst[i] = v + } + return lst, nil + case sObject: + size, err := a.Map() + if err != nil { + return nil, err + } + obj := make(rideObject, size) + for i := uint16(0); i < size; i++ { + key, err := a.String() + if err != nil { + return nil, err + } + value, err := a.RideValue() + if err != nil { + return nil, err + } + obj[key] = value + } + return obj, nil + default: + if b <= 100 { + return rideInt(b), nil + } + return nil, errors.Errorf("unknown type %d", b) + } +} diff --git a/pkg/ride/deserializer_test.go b/pkg/ride/deserializer_test.go new file mode 100644 index 000000000..420a58ce1 --- /dev/null +++ b/pkg/ride/deserializer_test.go @@ -0,0 +1,130 @@ +package ride + +import ( + "testing" + + "github.com/stretchr/testify/require" + "github.com/wavesplatform/gowaves/pkg/proto" +) + +func TestSerialization(t *testing.T) { + t.Run("uint16", func(t *testing.T) { + s := NewSerializer() + s.Uint16(10) + + d := NewDeserializer(s.Source()) + rs, _ := d.Uint16() + require.Equal(t, uint16(10), rs) + }) + t.Run("string", func(t *testing.T) { + s := NewSerializer() + _ = s.RideString("some string") + + d := NewDeserializer(s.Source()) + rs, _ := d.RideString() + require.Equal(t, "some string", rs) + }) + t.Run("entrypoint", func(t *testing.T) { + e := Entrypoint{ + name: "name", + at: 1050, + argn: 2, + } + s := NewSerializer() + err := e.Serialize(s) + require.NoError(t, err) + + d := NewDeserializer(s.Source()) + e2, err := deserializeEntrypoint(d) + require.NoError(t, err) + require.Equal(t, e, e2) + }) + t.Run("point", func(t *testing.T) { + e := point{ + position: 1050, + value: rideString("ss"), + fn: 1, + } + s := NewSerializer() + err := e.Serialize(s) + require.NoError(t, err) + + d := NewDeserializer(s.Source()) + e2, err := deserializePoint(d) + require.NoError(t, err) + require.Equal(t, e, e2) + }) + t.Run("address", func(t *testing.T) { + addr := rideAddress(proto.MustAddressFromString("3PKRnKhEmJbhGLDszhLmK8tptzBNjbw6wi4")) + s := NewSerializer() + require.NoError(t, addr.Serialize(s)) + + d := NewDeserializer(s.Source()) + v, err := d.RideValue() + require.NoError(t, err) + require.Equal(t, addr, v) + }) + t.Run("NamedType", func(t *testing.T) { + namedType := newDown(nil) + s := NewSerializer() + require.NoError(t, namedType.Serialize(s)) + + d := NewDeserializer(s.Source()) + v, err := d.RideValue() + require.NoError(t, err) + require.Equal(t, namedType, v) + }) + t.Run("Unit", func(t *testing.T) { + v1 := newUnit(nil) + s := NewSerializer() + require.NoError(t, v1.Serialize(s)) + + d := NewDeserializer(s.Source()) + v2, err := d.RideValue() + require.NoError(t, err) + require.Equal(t, v1, v2) + }) + t.Run("List", func(t *testing.T) { + v1 := rideList{rideInt(1), rideInt(2)} + s := NewSerializer() + require.NoError(t, v1.Serialize(s)) + + d := NewDeserializer(s.Source()) + v2, err := d.RideValue() + require.NoError(t, err) + require.Equal(t, v1, v2) + }) + t.Run("Object", func(t *testing.T) { + v1 := rideObject{"key": rideString("value")} + s := NewSerializer() + require.NoError(t, v1.Serialize(s)) + + d := NewDeserializer(s.Source()) + v2, err := d.RideValue() + require.NoError(t, err) + require.Equal(t, v1, v2) + }) + t.Run("bytes", func(t *testing.T) { + v1 := rideBytes(nil) + s := NewSerializer() + require.NoError(t, v1.Serialize(s)) + + d := NewDeserializer(s.Source()) + v2, err := d.RideValue() + require.NoError(t, err) + require.Equal(t, v1, v2) + }) +} + +func TestSerdeTransaction(t *testing.T) { + obj := testExchangeWithProofsToObject() + + s := NewSerializer() + require.NoError(t, obj.Serialize(s)) + + d := NewDeserializer(s.Source()) + v, err := d.RideValue() + require.NoError(t, err) + + require.Equal(t, obj, v) +} diff --git a/pkg/ride/errors.go b/pkg/ride/errors.go new file mode 100644 index 000000000..62f260e73 --- /dev/null +++ b/pkg/ride/errors.go @@ -0,0 +1,20 @@ +package ride + +import "github.com/pkg/errors" + +type ThrowError struct { + msg string +} + +func NewThrowError(msg string) *ThrowError { + return &ThrowError{msg: msg} +} + +func (a *ThrowError) Error() string { + return a.msg +} + +func IsThrowErr(err error) bool { + _, ok := errors.Cause(err).(*ThrowError) + return ok +} diff --git a/pkg/ride/errors_test.go b/pkg/ride/errors_test.go new file mode 100644 index 000000000..6047e4d4f --- /dev/null +++ b/pkg/ride/errors_test.go @@ -0,0 +1,14 @@ +package ride_test + +import ( + "testing" + + "github.com/pkg/errors" + "github.com/stretchr/testify/require" + "github.com/wavesplatform/gowaves/pkg/ride" +) + +func TestIsThrowErr(t *testing.T) { + require.False(t, ride.IsThrowErr(errors.New(""))) + require.True(t, ride.IsThrowErr(ride.NewThrowError(""))) +} diff --git a/pkg/ride/evaluation_result.go b/pkg/ride/evaluation_result.go new file mode 100644 index 000000000..184fb47aa --- /dev/null +++ b/pkg/ride/evaluation_result.go @@ -0,0 +1,28 @@ +package ride + +type EvaluationResult struct { +} + +func (a EvaluationResult) IsInterrupted() bool { + panic("unimplemented!") +} + +func (a EvaluationResult) Interrupted() *Executable { + panic("unimplemented!") +} + +func (a EvaluationResult) IsResult() bool { + panic("unimplemented!") +} + +func (a EvaluationResult) Result() ScriptResult { + panic("unimplemented!") +} + +func (a EvaluationResult) IsError() bool { + panic("unimplemented!") +} + +func (a EvaluationResult) Error() error { + panic("unimplemented!") +} diff --git a/pkg/ride/executable.go b/pkg/ride/executable.go new file mode 100644 index 000000000..ff684b5c5 --- /dev/null +++ b/pkg/ride/executable.go @@ -0,0 +1,257 @@ +package ride + +import ( + "github.com/pkg/errors" + "github.com/wavesplatform/gowaves/pkg/proto" +) + +type Executable struct { + LibVersion int + IsDapp bool + hasVerifier bool + position int // Non-default value assumes interrupted evaluation. + ByteCode []byte + EntryPoints map[string]Entrypoint + References map[uniqueid]point +} + +func (a *Executable) HasVerifier() bool { + return a.hasVerifier +} + +func (a *Executable) Interrupted() bool { + return a.position != 0 +} + +func (a *Executable) Continue() (RideResult, error) { + panic("unimplemented!") +} + +func (a *Executable) Verify(environment RideEnvironment) (RideResult, error) { + if a.Interrupted() { + return nil, errors.New("illegal `Verify` call on interrupted state") + } + if a.IsDapp { + if !a.HasVerifier() { + return nil, errors.Errorf("no verifier attached to script") + } + if environment == nil { + return nil, errors.Errorf("expect to get env.transaction(), but env is nil") + } + return a.runWithoutChecks(environment, "", []rideType{environment.transaction()}) + } + return a.runWithoutChecks(environment, "", nil) +} + +func (a *Executable) Entrypoint(name string) (Entrypoint, error) { + if a.Interrupted() { + return Entrypoint{}, errors.New("illegal `Entrypoint` call on interrupted state") + } + v, ok := a.EntryPoints[name] + if !ok { + return Entrypoint{}, errors.Errorf("entrypoint %s not found", name) + } + return v, nil +} + +func (a *Executable) runWithoutChecks(environment RideEnvironment, name string, arguments []rideType) (RideResult, error) { + fcall, ok := a.EntryPoints[name] + if !ok { + return nil, errors.Errorf("function %s not found", name) + } + vm, err := a.makeVm(environment, int(fcall.at), arguments) + if err != nil { + return nil, err + } + v, err := vm.run() + if err != nil { + return ScriptResult{res: false, msg: "", calls: vm.calls, refs: vm.ref, operations: vm.numOperations}, err + } + switch tv := v.(type) { + case rideThrow: + if a.IsDapp { + return DAppResult{res: false, msg: string(tv), calls: vm.calls, refs: vm.ref}, nil + } + return ScriptResult{res: false, msg: string(tv), calls: vm.calls, refs: vm.ref}, nil + case rideBoolean: + return ScriptResult{res: bool(tv), operations: vm.numOperations, calls: vm.calls, refs: vm.ref}, nil + case rideObject: + actions, err := objectToActions(vm.env, tv) + if err != nil { + return nil, errors.Wrap(err, "failed to convert evaluation result") + } + return DAppResult{res: true, actions: actions, msg: "", calls: vm.calls, refs: vm.ref}, nil + case rideList: + actions := make([]proto.ScriptAction, len(tv)) + for i, item := range tv { + a, err := convertToAction(vm.env, item) + if err != nil { + return nil, errors.Wrap(err, "failed to convert evaluation result") + } + actions[i] = a + } + return DAppResult{res: true, actions: actions, calls: vm.calls, refs: vm.ref}, nil + default: + return ScriptResult{calls: vm.calls}, errors.Errorf("unexpected result value '%v' of type '%T'", v, v) + } +} + +func (a *Executable) Invoke(env RideEnvironment, name string, arguments []rideType) (RideResult, error) { + if a.Interrupted() { + return nil, errors.New("illegal `Invoke` call on interrupted state") + } + if name == "" { + return nil, errors.Errorf("expected func name, found \"\"") + } + fcall, ok := a.EntryPoints[name] + if !ok { + return nil, errors.Errorf("function %s not found", name) + } + arguments = append([]rideType{env.invocation()}, arguments...) + if len(arguments) != int(fcall.argn)+1 { + return nil, errors.Errorf("func `%s` requires %d arguments(1 invoke + %d args), but provided %d", name, fcall.argn+1, fcall.argn, len(arguments)) + } + return a.runWithoutChecks(env, name, arguments) +} + +func (a *Executable) run(environment RideEnvironment, arguments []rideType) (rideType, error) { + vm, err := a.makeVm(environment, int(a.EntryPoints[""].at), arguments) + if err != nil { + return nil, err + } + return vm.run() +} + +func (a *Executable) makeVm(environment RideEnvironment, entrypoint int, arguments []rideType) (*vm, error) { + refs := copyReferences(a.References) + return &vm{ + code: a.ByteCode, + ip: entrypoint, + env: environment, + ref: refs, + stack: arguments, + jmps: []int{1}, + libVersion: a.LibVersion, + }, nil +} + +func (a *Executable) Serialize(s Serializer) error { + var magicNumber byte = 202 + s.Byte(magicNumber) + s.Uint16(uint16(a.LibVersion)) + s.Bool(a.IsDapp) + s.Bool(a.hasVerifier) + err := s.Bytes(a.ByteCode) + if err != nil { + return err + } + // entrypoints + err = s.Map(len(a.EntryPoints), func(m Map) error { + for k, v := range a.EntryPoints { + err := m.RideString(rideString(k)) + if err != nil { + return err + } + err = v.Serialize(s) + if err != nil { + return err + } + } + return nil + }) + if err != nil { + return err + } + // references + err = s.Map(len(a.References), func(m Map) error { + for k, v := range a.References { + m.Uint16(k) + err := v.Serialize(s) + if err != nil { + return err + } + } + return nil + }) + if err != nil { + return err + } + return nil +} + +func DeserializeExecutable(source []byte) (*Executable, error) { + d := NewDeserializer(source) + magic, err := d.Byte() + if err != nil { + return nil, err + } + if magic != 202 { + return nil, errors.New("invalid magic number") + } + libVersion, err := d.Uint16() + if err != nil { + return nil, err + } + isDapp, err := d.Bool() + if err != nil { + return nil, err + } + hasVerifier, err := d.Bool() + if err != nil { + return nil, err + } + byteCode, err := d.Bytes() + if err != nil { + return nil, err + } + size, err := d.Map() + if err != nil { + return nil, err + } + entrypoints := make(map[string]Entrypoint, size) + for i := uint16(0); i < size; i++ { + name, err := d.RideString() + if err != nil { + return nil, err + } + entrypoint, err := deserializeEntrypoint(d) + if err != nil { + return nil, err + } + entrypoints[name] = entrypoint + } + + size, err = d.Map() + if err != nil { + return nil, err + } + references := make(map[uniqueid]point, size) + for i := uint16(0); i < size; i++ { + id, err := d.Uint16() + if err != nil { + return nil, err + } + p, err := deserializePoint(d) + if err != nil { + return nil, err + } + references[id] = p + } + + return &Executable{ + LibVersion: int(libVersion), + IsDapp: isDapp, + ByteCode: byteCode, + hasVerifier: hasVerifier, + EntryPoints: entrypoints, + References: references, + }, nil +} + +func copyReferences(refs Refs) Refs { + out := make(Refs, len(refs)) + for k, v := range refs { + out[k] = v + } + return out +} diff --git a/pkg/ride/executable_test.go b/pkg/ride/executable_test.go new file mode 100644 index 000000000..ee0b29d4c --- /dev/null +++ b/pkg/ride/executable_test.go @@ -0,0 +1,31 @@ +package ride + +import ( + "encoding/base64" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestExecutableSerialization(t *testing.T) { + t.Skip() + source := `AAIDAAAAAAAAAAkIARIAEgMKAQEAAAAAAAAAAgAAAAFpAQAAAAdkZXBvc2l0AAAAAAQAAAADcG10CQEAAAAHZXh0cmFjdAAAAAEIBQAAAAFpAAAAB3BheW1lbnQDCQEAAAAJaXNEZWZpbmVkAAAAAQgFAAAAA3BtdAAAAAdhc3NldElkCQAAAgAAAAECAAAAIWNhbiBob2xkIHdhdmVzIG9ubHkgYXQgdGhlIG1vbWVudAQAAAAKY3VycmVudEtleQkAAlgAAAABCAgFAAAAAWkAAAAGY2FsbGVyAAAABWJ5dGVzBAAAAA1jdXJyZW50QW1vdW50BAAAAAckbWF0Y2gwCQAEGgAAAAIFAAAABHRoaXMFAAAACmN1cnJlbnRLZXkDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAA0ludAQAAAABYQUAAAAHJG1hdGNoMAUAAAABYQAAAAAAAAAAAAQAAAAJbmV3QW1vdW50CQAAZAAAAAIFAAAADWN1cnJlbnRBbW91bnQIBQAAAANwbXQAAAAGYW1vdW50CQEAAAAIV3JpdGVTZXQAAAABCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACBQAAAApjdXJyZW50S2V5BQAAAAluZXdBbW91bnQFAAAAA25pbAAAAAFpAQAAAAh3aXRoZHJhdwAAAAEAAAAGYW1vdW50BAAAAApjdXJyZW50S2V5CQACWAAAAAEICAUAAAABaQAAAAZjYWxsZXIAAAAFYnl0ZXMEAAAADWN1cnJlbnRBbW91bnQEAAAAByRtYXRjaDAJAAQaAAAAAgUAAAAEdGhpcwUAAAAKY3VycmVudEtleQMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAADSW50BAAAAAFhBQAAAAckbWF0Y2gwBQAAAAFhAAAAAAAAAAAABAAAAAluZXdBbW91bnQJAABlAAAAAgUAAAANY3VycmVudEFtb3VudAUAAAAGYW1vdW50AwkAAGYAAAACAAAAAAAAAAAABQAAAAZhbW91bnQJAAACAAAAAQIAAAAeQ2FuJ3Qgd2l0aGRyYXcgbmVnYXRpdmUgYW1vdW50AwkAAGYAAAACAAAAAAAAAAAABQAAAAluZXdBbW91bnQJAAACAAAAAQIAAAASTm90IGVub3VnaCBiYWxhbmNlCQEAAAAMU2NyaXB0UmVzdWx0AAAAAgkBAAAACFdyaXRlU2V0AAAAAQkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgUAAAAKY3VycmVudEtleQUAAAAJbmV3QW1vdW50BQAAAANuaWwJAQAAAAtUcmFuc2ZlclNldAAAAAEJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAAWkAAAAGY2FsbGVyBQAAAAZhbW91bnQFAAAABHVuaXQFAAAAA25pbAAAAAEAAAACdHgBAAAABnZlcmlmeQAAAAAJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAAACAUAAAACdHgAAAAPc2VuZGVyUHVibGljS2V54232jg==` + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(t, err) + + tree, err := Parse(src) + require.NoError(t, err) + + script, err := CompileTree("", tree) + require.NoError(t, err) + + s := NewSerializer() + + err = script.Serialize(s) + require.NoError(t, err) + + script2, err := DeserializeExecutable(s.Source()) + require.NoError(t, err) + + require.Equal(t, script, script2) +} diff --git a/pkg/ride/functions_predefined.go b/pkg/ride/functions_predefined.go new file mode 100644 index 000000000..2d4f6f1e6 --- /dev/null +++ b/pkg/ride/functions_predefined.go @@ -0,0 +1,69 @@ +package ride + +import ( + "math" +) + +func tx(env RideEnvironment, _ ...rideType) (rideType, error) { + return newTx(env), nil +} + +func this(env RideEnvironment, _ ...rideType) (rideType, error) { + return newThis(env), nil +} + +func height(env RideEnvironment, _ ...rideType) (rideType, error) { + return env.height(), nil +} + +func nilFunc(env RideEnvironment, _ ...rideType) (rideType, error) { + var out rideList = nil + return out, nil +} + +func lastBlock(env RideEnvironment, _ ...rideType) (rideType, error) { + return env.block(), nil +} + +// Order is important! Only add, avoid changes. +var predefinedFunctions = []predefFunc{ + {"tx", tx}, + {"unit", unit}, + {"NOALG", createNoAlg}, + {"this", this}, + {"height", height}, + {"nil", nilFunc}, + {"lastBlock", lastBlock}, + {"UP", createUp}, + {"DOWN", createDown}, + {"HALFDOWN", createHalfDown}, + {"HALFUP", createHalfUp}, + {"MD5", createMd5}, + {"SHA1", createSha1}, + {"SHA224", createSha224}, + {"SHA256", createSha256}, + {"SHA384", createSha384}, + {"SHA512", createSha512}, + {"SHA3224", createSha3224}, + {"SHA3256", createSha3256}, + {"SHA3384", createSha3384}, + {"SHA3512", createSha3512}, + {"Buy", createBuy}, + {"Sell", createSell}, + {"CEILING", createCeiling}, + {"HALFEVEN", createHalfEven}, +} + +var predefined *predef + +func init() { + predefined = newPredef(nil) + for k, v := range predefinedFunctions { + predefined.set(v.name, uint16(math.MaxUint16-k), v.f) + } +} + +type Functions interface { + function(int) rideFunction + name(int) string +} diff --git a/pkg/ride/functions_proto_test.go b/pkg/ride/functions_proto_test.go index 9c452cdc4..2a861c96e 100644 --- a/pkg/ride/functions_proto_test.go +++ b/pkg/ride/functions_proto_test.go @@ -117,6 +117,19 @@ func TestAddressFromRecipient(t *testing.T) { t.SkipNow() } +func TestWriteSet(t *testing.T) { + _, err := writeSet(nil, nil) + require.Error(t, err) + + _, err = writeSet(nil, rideList{}) + require.NoError(t, err) + + var lst rideList = nil + _, err = writeSet(nil, lst) + require.NoError(t, err) + +} + func TestSigVerify(t *testing.T) { msg, err := hex.DecodeString("135212a9cf00d0a05220be7323bfa4a5ba7fc5465514007702121a9c92e46bd473062f00841af83cb7bc4b2cd58dc4d5b151244cc8293e795796835ed36822c6e09893ec991b38ada4b21a06e691afa887db4e9d7b1d2afc65ba8d2f5e6926ff53d2d44d55fa095f3fad62545c714f0f3f59e4bfe91af8") require.NoError(t, err) diff --git a/pkg/ride/generate/main.go b/pkg/ride/generate/main.go index f310832a3..176e9300d 100644 --- a/pkg/ride/generate/main.go +++ b/pkg/ride/generate/main.go @@ -726,6 +726,14 @@ func createTuples(sb *strings.Builder) { sb.WriteString("}\n") sb.WriteString(fmt.Sprintf("return %s\n", strings.Join(comparisons, " && "))) sb.WriteString("}\n\n") + // serialize + sb.WriteString(fmt.Sprintf("func (a tuple%d) Serialize(serializer Serializer) error {\n", n)) + sb.WriteString(" return serializer.Tuple(") + for i := 1; i <= n; i++ { + sb.WriteString(fmt.Sprintf("a.el%d,", i)) + } + sb.WriteString(")\n}\n") + } } diff --git a/pkg/ride/opcodes.go b/pkg/ride/opcodes.go index 57a654eb2..74e9b21ab 100644 --- a/pkg/ride/opcodes.go +++ b/pkg/ride/opcodes.go @@ -14,9 +14,14 @@ const ( OpJumpIfFalse //07 - Moves instruction pointer to new position if value on stack is False. One parameter: new position. OpProperty //08 - Puts value of object's property on stack. One parameter: constant ID that holds name of the property. OpExternalCall //09 - Call a standard library function. Two parameters: function ID, number of arguments. - OpCall //0a - Call a function declared at given address. Two parameters: position of function declaration, number of arguments. - OpGlobal //0b - Load global constant. One parameter: global constant ID. - OpLoad //0c - Evaluates an expression that declared at address. One parameter: position of declaration. - OpLoadLocal //0d - Load an argument of function call on stack. One parameter: argument number. - OpRef //0e - Put reference to expression/function on stack. One parameter: position of declaration. + OpCall //10 Obsolete! 0xa - Call a function declared at given address. One parameter: position of function declaration. + OpSetArg //11 0xb - FROM (global) -> TO (local): Set value into cell. Two parameters: constant id and cell id. + OpCache //12 0xc - Put constant on stack. One parameter: constant ID. + OpRef //13 0xd = ref id + OpClearCache //14 0xe = ref id + + // odd, will be removed. + OpGlobal + OpLoadLocal + OpLoad ) diff --git a/pkg/ride/program.go b/pkg/ride/program.go deleted file mode 100644 index e384d7b9b..000000000 --- a/pkg/ride/program.go +++ /dev/null @@ -1,100 +0,0 @@ -package ride - -import "github.com/pkg/errors" - -type callable struct { - entryPoint int - parameterName string -} - -type RideScript interface { - Run(env RideEnvironment) (RideResult, error) - code() []byte -} - -type SimpleScript struct { - LibVersion int - EntryPoint int - Code []byte - Constants []rideType -} - -func (s *SimpleScript) Run(env RideEnvironment) (RideResult, error) { - fs, err := selectFunctions(s.LibVersion) - if err != nil { - return nil, errors.Wrap(err, "simple script execution failed") - } - gcs, err := selectConstants(s.LibVersion) - if err != nil { - return nil, errors.Wrap(err, "simple script execution failed") - } - np, err := selectFunctionNameProvider(s.LibVersion) - if err != nil { - return nil, errors.Wrap(err, "simple script execution failed") - } - m := vm{ - env: env, - code: s.Code, - ip: 0, - constants: s.Constants, - functions: fs, - globals: gcs, - stack: make([]rideType, 0, 2), - calls: make([]frame, 0, 2), - functionName: np, - } - r, err := m.run() - if err != nil { - return nil, errors.Wrap(err, "simple script execution failed") - } - return r, nil -} - -func (s *SimpleScript) code() []byte { - return s.Code -} - -type DAppScript struct { - LibVersion int - Code []byte - Constants []rideType - EntryPoints map[string]callable -} - -func (s *DAppScript) Run(env RideEnvironment) (RideResult, error) { - if _, ok := s.EntryPoints[""]; !ok { - return nil, errors.Errorf("no verifier") - } - fs, err := selectFunctions(s.LibVersion) - if err != nil { - return nil, errors.Wrap(err, "script execution failed") - } - gcs, err := selectConstants(s.LibVersion) - if err != nil { - return nil, errors.Wrap(err, "script execution failed") - } - np, err := selectFunctionNameProvider(s.LibVersion) - if err != nil { - return nil, errors.Wrap(err, "script execution failed") - } - m := vm{ - env: env, - code: s.Code, - ip: 0, - constants: s.Constants, - functions: fs, - globals: gcs, - stack: make([]rideType, 0, 2), - calls: make([]frame, 0, 2), - functionName: np, - } - r, err := m.run() - if err != nil { - return nil, errors.Wrap(err, "script execution failed") - } - return r, nil -} - -func (s *DAppScript) code() []byte { - return s.Code -} diff --git a/pkg/ride/result.go b/pkg/ride/result.go index 703ed35e3..c224f20be 100644 --- a/pkg/ride/result.go +++ b/pkg/ride/result.go @@ -1,44 +1,88 @@ package ride -import "github.com/wavesplatform/gowaves/pkg/proto" +import ( + "github.com/wavesplatform/gowaves/pkg/proto" +) type RideResult interface { Result() bool UserError() string - ScriptActions() []proto.ScriptAction + ScriptActions() proto.ScriptActions + Eq(RideResult) bool + Calls() []callLog + Refs() Refs } type ScriptResult struct { - res bool - msg string + res bool + msg string + operations int + calls []callLog + refs Refs } func (r ScriptResult) Result() bool { return r.res } +func (r ScriptResult) Refs() Refs { + return r.refs +} + +func (r ScriptResult) Calls() []callLog { + return r.calls +} + func (r ScriptResult) UserError() string { return r.msg } -func (r ScriptResult) ScriptActions() []proto.ScriptAction { +func (r ScriptResult) ScriptActions() proto.ScriptActions { return nil } +func (r ScriptResult) Eq(other RideResult) bool { + switch a := other.(type) { + case ScriptResult: + return a.res == r.res && a.msg == r.msg + default: + return false + } +} + type DAppResult struct { res bool // true - success, false - call failed, read msg - actions []proto.ScriptAction + actions proto.ScriptActions msg string + calls []callLog + refs Refs } func (r DAppResult) Result() bool { return r.res } +func (r DAppResult) Refs() Refs { + return r.refs +} + +func (r DAppResult) Calls() []callLog { + return r.calls +} + func (r DAppResult) UserError() string { return r.msg } -func (r DAppResult) ScriptActions() []proto.ScriptAction { +func (r DAppResult) ScriptActions() proto.ScriptActions { return r.actions } + +func (r DAppResult) Eq(other RideResult) bool { + switch v := other.(type) { + case DAppResult: + return r.res == v.res && r.actions.Eq(v.actions) + default: + return false + } +} diff --git a/pkg/ride/result_test.go b/pkg/ride/result_test.go new file mode 100644 index 000000000..97e982b64 --- /dev/null +++ b/pkg/ride/result_test.go @@ -0,0 +1,11 @@ +package ride + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestResult_Eq(t *testing.T) { + require.True(t, ScriptResult{}.Eq(ScriptResult{})) +} diff --git a/pkg/ride/runtime.go b/pkg/ride/runtime.go index f12850dd1..d71d0f524 100644 --- a/pkg/ride/runtime.go +++ b/pkg/ride/runtime.go @@ -14,10 +14,19 @@ type rideType interface { instanceOf() string eq(other rideType) bool get(prop string) (rideType, error) + Serialize(Serializer) error +} + +func RideTypes(types ...rideType) []rideType { + return types } type rideThrow string +func (a rideThrow) Serialize(serializer Serializer) error { + panic("implement me") +} + func (a rideThrow) instanceOf() string { return "Throw" } @@ -40,6 +49,14 @@ func (a rideThrow) get(prop string) (rideType, error) { type rideBoolean bool +func RideBoolean(b bool) rideBoolean { + return rideBoolean(b) +} + +func (b rideBoolean) Serialize(serializer Serializer) error { + return serializer.RideBool(b) +} + func (b rideBoolean) instanceOf() string { return "Boolean" } @@ -57,6 +74,14 @@ func (b rideBoolean) get(prop string) (rideType, error) { type rideInt int64 +func RideInt(i int64) rideInt { + return rideInt(i) +} + +func (l rideInt) Serialize(serializer Serializer) error { + return serializer.RideInt(l) +} + func (l rideInt) instanceOf() string { return "Int" } @@ -74,6 +99,14 @@ func (l rideInt) get(prop string) (rideType, error) { type rideString string +func RideString(s string) rideString { + return rideString(s) +} + +func (s rideString) Serialize(serializer Serializer) error { + return serializer.RideString(s) +} + func (s rideString) instanceOf() string { return "String" } @@ -91,6 +124,10 @@ func (s rideString) get(prop string) (rideType, error) { type rideBytes []byte +func (b rideBytes) Serialize(serializer Serializer) error { + return serializer.RideBytes(b) +} + func (b rideBytes) instanceOf() string { return "ByteVector" } @@ -108,6 +145,23 @@ func (b rideBytes) get(prop string) (rideType, error) { type rideObject map[string]rideType +func (o rideObject) Serialize(s Serializer) error { + if err := s.Type(sObject); err != nil { + return err + } + return s.Map(len(o), func(m Map) error { + for k, v := range o { + if err := m.String(k); err != nil { + return err + } + if err := v.Serialize(s); err != nil { + return err + } + } + return nil + }) +} + func (o rideObject) instanceOf() string { if s, ok := o[instanceFieldName].(rideString); ok { return string(s) @@ -141,6 +195,13 @@ func (o rideObject) get(prop string) (rideType, error) { type rideAddress proto.Address +func (a rideAddress) Serialize(s Serializer) error { + if err := s.Type(sAddress); err != nil { + return err + } + return s.Bytes(a[:]) +} + func (a rideAddress) instanceOf() string { return "Address" } @@ -169,6 +230,10 @@ func (a rideAddress) get(prop string) (rideType, error) { type rideAddressLike []byte +func (a rideAddressLike) Serialize(serializer Serializer) error { + panic("implement me") +} + func (a rideAddressLike) instanceOf() string { return "Address" } @@ -197,6 +262,10 @@ func (a rideAddressLike) get(prop string) (rideType, error) { type rideRecipient proto.Recipient +func (a rideRecipient) Serialize(serializer Serializer) error { + panic("rideRecipient Serialize implement me") +} + func (a rideRecipient) instanceOf() string { switch { case a.Address != nil: @@ -211,7 +280,7 @@ func (a rideRecipient) instanceOf() string { func (a rideRecipient) eq(other rideType) bool { switch o := other.(type) { case rideRecipient: - return a.Address == o.Address && a.Alias == o.Alias + return proto.Recipient(a).Eq(proto.Recipient(o)) case rideAddress: return a.Address != nil && bytes.Equal(a.Address[:], o[:]) case rideAlias: @@ -247,6 +316,10 @@ func (a rideRecipient) String() string { type rideAlias proto.Alias +func (a rideAlias) Serialize(Serializer) error { + panic("implement me") +} + func (a rideAlias) instanceOf() string { return "Alias" } @@ -273,6 +346,10 @@ func (a rideAlias) get(prop string) (rideType, error) { type rideUnit struct{} +func (a rideUnit) Serialize(s Serializer) error { + return s.RideUnit() +} + func (a rideUnit) instanceOf() string { return "Unit" } @@ -289,6 +366,13 @@ type rideNamedType struct { name string } +func (a rideNamedType) Serialize(s Serializer) error { + if err := s.Type(sNamedType); err != nil { + return err + } + return s.String(a.name) +} + func (a rideNamedType) instanceOf() string { return a.name } @@ -303,6 +387,18 @@ func (a rideNamedType) get(prop string) (rideType, error) { type rideList []rideType +func (a rideList) Serialize(s Serializer) error { + if err := s.RideList(uint16(len(a))); err != nil { + return err + } + for _, v := range a { + if err := v.Serialize(s); err != nil { + return err + } + } + return nil +} + func (a rideList) instanceOf() string { return "List[Any]" } diff --git a/pkg/ride/serializer.go b/pkg/ride/serializer.go new file mode 100644 index 000000000..d3b0042ee --- /dev/null +++ b/pkg/ride/serializer.go @@ -0,0 +1,154 @@ +package ride + +import ( + "bytes" + "encoding/binary" + "math" + + "github.com/pkg/errors" +) + +const ( + sTrue byte = 101 + sFalse byte = 102 + sInt byte = 103 + sBytes byte = 105 + sString byte = 106 + sPoint byte = 107 + sMap byte = 108 + sNoValue byte = 109 + sAddress byte = 110 + sNamedType byte = 111 + sUnit byte = 112 + sList byte = 113 + sObject byte = 114 +) + +type Serializer struct { + b *bytes.Buffer +} + +func NewSerializer() Serializer { + return Serializer{b: &bytes.Buffer{}} +} + +func (a *Serializer) RideInt(v rideInt) error { + if v >= 0 && v <= 100 { + a.b.WriteByte(byte(v)) + return nil + } + a.b.WriteByte(sInt) + b := make([]byte, 8) + binary.BigEndian.PutUint64(b, uint64(v)) + a.b.Write(b) + return nil +} + +func (a *Serializer) RideNoValue() error { + return a.b.WriteByte(sNoValue) +} + +func (a *Serializer) Tuple(...rideType) error { + panic("not implemented") +} + +func (a *Serializer) Uint16(v uint16) { + b := make([]byte, 2) + binary.BigEndian.PutUint16(b, v) + a.b.Write(b) +} + +func (a *Serializer) Bool(v bool) { + if v { + a.b.WriteByte(sTrue) + } else { + a.b.WriteByte(sFalse) + } +} + +func (a *Serializer) Point(p point) { + a.b.WriteByte(sPoint) + a.Uint16(p.position) +} + +func (a *Serializer) Byte(b byte) { + a.b.WriteByte(b) +} + +func (a *Serializer) RideBytes(v rideBytes) error { + a.b.WriteByte(sBytes) + return a.Bytes(v) +} + +func (a *Serializer) Type(t byte) error { + return a.b.WriteByte(t) +} + +func (a *Serializer) Bytes(v []byte) error { + if len(v) > math.MaxUint16 { + return errors.New("bytes length overflow") + } + a.Uint16(uint16(len(v))) + a.b.Write(v) + return nil +} + +func (a *Serializer) Source() []byte { + return a.b.Bytes() +} + +func (a *Serializer) RideMap(size int) error { + a.b.WriteByte(sMap) + if size > math.MaxUint16 { + return errors.New("size overflow") + } + a.Uint16(uint16(size)) + return nil +} + +func (a *Serializer) RideString(v rideString) error { + a.b.WriteByte(sString) + return a.String(string(v)) +} + +func (a *Serializer) RideUnit() error { + return a.Type(sUnit) +} + +func (a *Serializer) String(v string) error { + if len(v) > math.MaxUint16 { + return errors.New("bytes length overflow") + } + a.Uint16(uint16(len(v))) + a.b.Write([]byte(v)) + return nil +} + +func (a Serializer) RideBool(v rideBoolean) error { + a.Bool(bool(v)) + return nil +} + +func (a *Serializer) Map(size int, f func(Map) error) error { + err := a.RideMap(size) + if err != nil { + return err + } + return f(a) +} + +func (a *Serializer) RideList(length uint16) error { + if err := a.Type(sList); err != nil { + return err + } + a.Uint16(length) + return nil +} + +type Map interface { + String(string) error + Uint16(v uint16) + RideInt(v rideInt) error + RideBytes(v rideBytes) error + RideString(v rideString) error +} diff --git a/pkg/ride/tree.go b/pkg/ride/tree.go index b270af1fa..6778ebeb7 100644 --- a/pkg/ride/tree.go +++ b/pkg/ride/tree.go @@ -1,8 +1,11 @@ package ride +import "github.com/pkg/errors" + type Node interface { node() SetBlock(node Node) + Clone() Node } type LongNode struct { @@ -13,6 +16,12 @@ func (*LongNode) node() {} func (*LongNode) SetBlock(Node) {} +func (a *LongNode) Clone() Node { + return &LongNode{ + Value: a.Value, + } +} + func NewLongNode(v int64) *LongNode { return &LongNode{Value: v} } @@ -25,6 +34,13 @@ func (*BytesNode) node() {} func (*BytesNode) SetBlock(Node) {} +func (a *BytesNode) Clone() Node { + return &BytesNode{ + // Bytes references to the same location. + Value: a.Value, + } +} + func NewBytesNode(v []byte) *BytesNode { return &BytesNode{Value: v} } @@ -37,6 +53,12 @@ func (*StringNode) node() {} func (*StringNode) SetBlock(Node) {} +func (a *StringNode) Clone() Node { + return &StringNode{ + Value: a.Value, + } +} + func NewStringNode(v string) *StringNode { return &StringNode{Value: v} } @@ -49,6 +71,12 @@ func (*BooleanNode) node() {} func (*BooleanNode) SetBlock(Node) {} +func (a *BooleanNode) Clone() Node { + return &BooleanNode{ + Value: a.Value, + } +} + func NewBooleanNode(v bool) *BooleanNode { return &BooleanNode{Value: v} } @@ -63,6 +91,14 @@ func (*ConditionalNode) node() {} func (*ConditionalNode) SetBlock(Node) {} +func (a *ConditionalNode) Clone() Node { + return &ConditionalNode{ + Condition: a.Condition.Clone(), + TrueExpression: a.TrueExpression.Clone(), + FalseExpression: a.FalseExpression.Clone(), + } +} + func NewConditionalNode(condition, trueExpression, falseExpression Node) *ConditionalNode { return &ConditionalNode{ Condition: condition, @@ -79,8 +115,16 @@ type AssignmentNode struct { func (*AssignmentNode) node() {} -func (n *AssignmentNode) SetBlock(node Node) { - n.Block = node +func (a *AssignmentNode) SetBlock(node Node) { + a.Block = node +} + +func (a *AssignmentNode) Clone() Node { + return &AssignmentNode{ + Name: a.Name, + Expression: a.Expression.Clone(), + Block: a.Block.Clone(), + } } func NewAssignmentNode(name string, expression, block Node) *AssignmentNode { @@ -99,6 +143,10 @@ func (*ReferenceNode) node() {} func (*ReferenceNode) SetBlock(Node) {} +func (a *ReferenceNode) Clone() Node { + return &ReferenceNode{Name: a.Name} +} + func NewReferenceNode(name string) *ReferenceNode { return &ReferenceNode{Name: name} } @@ -117,6 +165,36 @@ func (n *FunctionDeclarationNode) SetBlock(node Node) { n.Block = node } +func clone(n Node) Node { + if n == nil { + return n + } + return n.Clone() +} + +func cloneFuncDecl(n *FunctionDeclarationNode, body Node, block Node) *FunctionDeclarationNode { + return &FunctionDeclarationNode{ + Name: n.Name, + Arguments: n.Arguments, + Body: body, + Block: block, + invocationParameter: n.invocationParameter, + } +} + +func (n *FunctionDeclarationNode) Clone() Node { + args := make([]string, len(n.Arguments)) + copy(args, n.Arguments) + + return &FunctionDeclarationNode{ + Name: n.Name, + Arguments: args, + Body: n.Body.Clone(), + Block: clone(n.Block), + invocationParameter: n.invocationParameter, + } +} + func NewFunctionDeclarationNode(name string, arguments []string, body, block Node) *FunctionDeclarationNode { return &FunctionDeclarationNode{ Name: name, @@ -126,15 +204,44 @@ func NewFunctionDeclarationNode(name string, arguments []string, body, block Nod } } +type Nodes []Node + +func (a Nodes) Clone() Nodes { + out := make(Nodes, 0, len(a)) + for _, v := range a { + out = append(out, v.Clone()) + } + return out +} + +func (a Nodes) Map(f func(Node) Node) Nodes { + args := make([]Node, 0, len(a)) + for _, v := range a { + args = append(args, f(v)) + } + return args +} + type FunctionCallNode struct { Name string - Arguments []Node + Arguments Nodes +} + +func (a *FunctionCallNode) ArgumentsCount() uint16 { + return uint16(len(a.Arguments)) } func (*FunctionCallNode) node() {} func (*FunctionCallNode) SetBlock(Node) {} +func (a *FunctionCallNode) Clone() Node { + return &FunctionCallNode{ + Name: a.Name, + Arguments: a.Arguments.Clone(), + } +} + func NewFunctionCallNode(name string, arguments []Node) *FunctionCallNode { return &FunctionCallNode{ Name: name, @@ -151,6 +258,13 @@ func (*PropertyNode) node() {} func (*PropertyNode) SetBlock(Node) {} +func (a *PropertyNode) Clone() Node { + return &PropertyNode{ + Name: a.Name, + Object: a.Object.Clone(), + } +} + func NewPropertyNode(name string, object Node) *PropertyNode { return &PropertyNode{ Name: name, @@ -172,6 +286,7 @@ type Tree struct { Declarations []Node Functions []Node Verifier Node + Expanded bool } func (t *Tree) HasVerifier() bool { @@ -181,3 +296,11 @@ func (t *Tree) HasVerifier() bool { func (t *Tree) IsDApp() bool { return t.AppVersion != scriptApplicationVersion } + +func (t *Tree) Invoke(env RideEnvironment, name string, arguments []rideType) (RideResult, error) { + e, err := treeFunctionEvaluator(env, t, name, arguments) + if err != nil { + return nil, errors.Wrapf(err, "failed to call function '%s'", name) + } + return e.evaluate() +} diff --git a/pkg/ride/tree_estimatorV3.go b/pkg/ride/tree_estimatorV3.go index de4a443e7..44029fef2 100644 --- a/pkg/ride/tree_estimatorV3.go +++ b/pkg/ride/tree_estimatorV3.go @@ -8,6 +8,7 @@ type fd struct { cost int usages []string } + type fsV3 struct { parent *fsV3 functions map[string]fd @@ -67,7 +68,7 @@ func (s *estimationScopeV3) setFunction(id string, cost int, usages []string) { s.functions.set(id, cost, usages) } -func (s *estimationScopeV3) function(id string) (int, []string, error) { +func (s *estimationScopeV3) function(id string) (cost int, usages []string, err error) { if c, ok := s.builtin[id]; ok { return c, nil, nil } diff --git a/pkg/ride/tree_evaluation.go b/pkg/ride/tree_evaluation.go index 8112b46e5..170a06cb0 100644 --- a/pkg/ride/tree_evaluation.go +++ b/pkg/ride/tree_evaluation.go @@ -2,10 +2,12 @@ package ride import ( "github.com/pkg/errors" + "github.com/stretchr/testify/assert" "github.com/wavesplatform/gowaves/pkg/proto" + "go.uber.org/zap" ) -func CallVerifier(env RideEnvironment, tree *Tree) (RideResult, error) { +func CallTreeVerifier(env RideEnvironment, tree *Tree) (RideResult, error) { e, err := treeVerifierEvaluator(env, tree) if err != nil { return nil, errors.Wrap(err, "failed to call verifier") @@ -13,13 +15,130 @@ func CallVerifier(env RideEnvironment, tree *Tree) (RideResult, error) { return e.evaluate() } -func CallFunction(env RideEnvironment, tree *Tree, name string, args proto.Arguments) (RideResult, error) { - if name == "" { - name = "default" +func CallVmVerifier(txID string, env RideEnvironment, compiled *Executable) (RideResult, error) { + if env == nil { + return nil, errors.Errorf("env is nil") + } + return compiled.Verify(env) +} + +func CallVerifier(txID string, env RideEnvironment, tree *Tree, exe *Executable) (RideResult, error) { + tree = MustExpand(tree) + r1, err := CallTreeVerifier(env, tree) + if err != nil { + return nil, errors.Wrap(err, "tree verifier") + } + r2, err := CallVmVerifier(txID, env, exe) + if err != nil { + return nil, errors.Wrap(err, "vm verifier") } - e, err := treeFunctionEvaluator(env, tree, name, args) + if !r1.Eq(r2) { + c1 := r1.Calls() + c2 := r2.Calls() + max := len(c1) + if len(c2) > len(c1) { + max = len(c2) + } + for i := 0; i < max; i++ { + //zap.S().Error("R1 != R2: failed to call account script on transaction ") + if i <= len(c1)-1 { + zap.S().Error(i, txID, " ", c1[i]) + } else { + zap.S().Error(i, txID, " ", "") + } + if i <= len(c2)-1 { + zap.S().Error(i, txID, " ", c2[i]) + } else { + zap.S().Error(i, txID, " ", "") + } + } + return nil, errors.New("R1 != R2: failed to call account script on transaction ") + } + + return r2, nil +} + +func CallTreeFunction(txID string, env RideEnvironment, tree *Tree, name string, args proto.Arguments) (RideResult, error) { + var types []rideType + for _, arg := range args { + a, err := convertArgument(arg) + if err != nil { + return nil, errors.Wrapf(err, "failed to call function '%s'", name) + } + types = append(types, a) + } + e, err := treeFunctionEvaluator(env, tree, name, types) if err != nil { return nil, errors.Wrapf(err, "failed to call function '%s'", name) } return e.evaluate() } + +func CallFunction(txID string, env RideEnvironment, exe *Executable, tree *Tree, name string, args proto.Arguments) (RideResult, error) { + tree = MustExpand(tree) + rs1, err := CallTreeFunction(txID, env, tree, name, args) + if err != nil { + return nil, errors.Wrap(err, "call function by tree") + } + /* */ + rs2, err := CallVmFunction(txID, env, exe, name, args) + if err != nil { + return rs2, errors.Wrap(err, "call function by vm") + } + if !rs1.Eq(rs2) { + c1 := rs1.Calls() + c2 := rs2.Calls() + max := len(c1) + if len(c2) > len(c1) { + max = len(c2) + } + for i := 0; i < max; i++ { + if i <= len(c1)-1 { + zap.S().Error(i, txID, " ", c1[i]) + } else { + zap.S().Error(i, txID, " ", "") + } + if i <= len(c2)-1 { + zap.S().Error(i, txID, " ", c2[i]) + } else { + zap.S().Error(i, txID, " ", "") + } + } + + ac1 := rs1.ScriptActions() + ac2 := rs2.ScriptActions() + for i := range ac1 { + zap.S().Errorf("%d %s Action %+v", i, txID, ac1[i].(*proto.DataEntryScriptAction).Entry.(*proto.BinaryDataEntry).Value) + zap.S().Errorf("%d %s Action %+v", i, txID, ac2[i].(*proto.DataEntryScriptAction).Entry.(*proto.BinaryDataEntry).Value) + zap.S().Errorf("Eq %+v", assert.ObjectsAreEqual(ac1[i].(*proto.DataEntryScriptAction).Entry.(*proto.BinaryDataEntry).Value, ac2[i].(*proto.DataEntryScriptAction).Entry.(*proto.BinaryDataEntry).Value)) + break + //zap.S().Errorf(i, txID, " Action ", ac2[i]) + } + + return nil, errors.New("R1 != R2: failed to call account script on transaction ") + } + /* */ + return rs1, nil +} + +func CallVmFunction(txID string, env RideEnvironment, e *Executable, name string, args proto.Arguments) (RideResult, error) { + if name == "" { + name = "default" + } + entry, err := e.Entrypoint(name) + if err != nil { + return nil, err + } + if l := len(args); l != int(entry.argn) { + return nil, errors.Errorf("invalid arguments count %d for function '%s'", l, name) + } + applyArgs := make([]rideType, 0, len(args)) + for _, arg := range args { + a, err := convertArgument(arg) + if err != nil { + return nil, errors.Wrapf(err, "failed to call function '%s'", name) + } + applyArgs = append(applyArgs, a) + } + return e.Invoke(env, name, applyArgs) +} diff --git a/pkg/ride/tree_evaluation_test.go b/pkg/ride/tree_evaluation_test.go index e8965cb93..fea2e6069 100644 --- a/pkg/ride/tree_evaluation_test.go +++ b/pkg/ride/tree_evaluation_test.go @@ -49,7 +49,7 @@ func TestSimpleScriptEvaluation(t *testing.T) { {`V3: let b = base16'0000000000000001'; func add(v: ByteVector) = toInt(v) + 1; add(b) == 2`, "AwQAAAABYgEAAAAIAAAAAAAAAAEKAQAAAANhZGQAAAABAAAAAXYJAABkAAAAAgkABLEAAAABBQAAAAF2AAAAAAAAAAABCQAAAAAAAAIJAQAAAANhZGQAAAABBQAAAAFiAAAAAAAAAAACI7gYxg==", nil, true}, {`V3: let b = base16'0000000000000001'; func add(v: ByteVector) = toInt(b) + 1; add(b) == 2`, "AwQAAAABYgEAAAAIAAAAAAAAAAEKAQAAAANhZGQAAAABAAAAAXYJAABkAAAAAgkABLEAAAABBQAAAAFiAAAAAAAAAAABCQAAAAAAAAIJAQAAAANhZGQAAAABBQAAAAFiAAAAAAAAAAAChRvwnQ==", nil, true}, {`V3: let data = base64'AAAAAAABhqAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWyt9GyysOW84u/u5V5Ah/SzLfef4c28UqXxowxFZS4SLiC6+XBh8D7aJDXyTTjpkPPED06ZPOzUE23V6VYCsLw=='; func getStock(data:ByteVector) = toInt(take(drop(data, 8), 8)); getStock(data) == 1`, `AwQAAAAEZGF0YQEAAABwAAAAAAABhqAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWyt9GyysOW84u/u5V5Ah/SzLfef4c28UqXxowxFZS4SLiC6+XBh8D7aJDXyTTjpkPPED06ZPOzUE23V6VYCsLwoBAAAACGdldFN0b2NrAAAAAQAAAARkYXRhCQAEsQAAAAEJAADJAAAAAgkAAMoAAAACBQAAAARkYXRhAAAAAAAAAAAIAAAAAAAAAAAICQAAAAAAAAIJAQAAAAhnZXRTdG9jawAAAAEFAAAABGRhdGEAAAAAAAAAAAFCtabi`, nil, true}, - {`V3: let ref = 999; func g(a: Int) = ref; func f(ref: Int) = g(ref); f(1) == 999`, "AwQAAAADcmVmAAAAAAAAAAPnCgEAAAABZwAAAAEAAAABYQUAAAADcmVmCgEAAAABZgAAAAEAAAADcmVmCQEAAAABZwAAAAEFAAAAA3JlZgkAAAAAAAACCQEAAAABZgAAAAEAAAAAAAAAAAEAAAAAAAAAA+fjknmW", nil, true}, + {`V3: let ref = 999; func g(a: Int) = ref; func f(ref: Int) = g(ref); f(1) == 999`, "AwQAAAADcmVmAAAAAAAAAAPnCgEAAAABZwAAAAEAAAABYQUAAAADcmVmCgEAAAABZgAAAAEAAAADcmVmCQEAAAABZwAAAAEFAAAAA3JlZgkAAAAAAAACCQEAAAABZgAAAAEAAAAAAAAAAAEAAAAAAAAAA+fjknmW", env, true}, {`let x = 5; 6 > 4`, `AQQAAAABeAAAAAAAAAAABQkAAGYAAAACAAAAAAAAAAAGAAAAAAAAAAAEYSW6XA==`, nil, true}, {`let x = 5; 6 > x`, `AQQAAAABeAAAAAAAAAAABQkAAGYAAAACAAAAAAAAAAAGBQAAAAF4Gh24hw==`, nil, true}, {`let x = 5; 6 >= x`, `AQQAAAABeAAAAAAAAAAABQkAAGcAAAACAAAAAAAAAAAGBQAAAAF4jlxXHA==`, nil, true}, @@ -57,7 +57,6 @@ func TestSimpleScriptEvaluation(t *testing.T) { {`let x = throw(); true`, `AQQAAAABeAkBAAAABXRocm93AAAAAAa7bgf4`, nil, true}, {`let x = throw(); true || x`, `AQQAAAABeAkBAAAABXRocm93AAAAAAMGBgUAAAABeKRnLds=`, nil, true}, {`tx.id == base58''`, `AQkAAAAAAAACCAUAAAACdHgAAAACaWQBAAAAAJBtD70=`, env, false}, - {`tx.id == base58'H5C8bRzbUTMePSDVVxjiNKDUwk6CKzfZGTP2Rs7aCjsV'`, `BAkAAAAAAAACCAUAAAACdHgAAAACaWQBAAAAIO7N5luRDUgN1SJ4kFmy/Ni8U2H6k7bpszok5tlLlRVgHwSHyg==`, env, true}, {`let x = tx.id == base58'a';true`, `AQQAAAABeAkAAAAAAAACCAUAAAACdHgAAAACaWQBAAAAASEGjR0kcA==`, env, true}, {`V4: if tx.proofs[0] != base58'' then tx.proofs[1] == base58'' else false`, `BAMJAQAAAAIhPQAAAAIJAAGRAAAAAggFAAAAAnR4AAAABnByb29mcwAAAAAAAAAAAAEAAAAACQAAAAAAAAIJAAGRAAAAAggFAAAAAnR4AAAABnByb29mcwAAAAAAAAAAAQEAAAAAB106gzM=`, env, true}, {`match tx {case t : TransferTransaction | MassTransferTransaction | ExchangeTransaction => true; case _ => false}`, `AQQAAAAHJG1hdGNoMAUAAAACdHgDAwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAABNFeGNoYW5nZVRyYW5zYWN0aW9uBgMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAXTWFzc1RyYW5zZmVyVHJhbnNhY3Rpb24GCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAE1RyYW5zZmVyVHJhbnNhY3Rpb24EAAAAAXQFAAAAByRtYXRjaDAGB6Ilvok=`, env, true}, @@ -82,7 +81,7 @@ func TestSimpleScriptEvaluation(t *testing.T) { require.NoError(t, err, test.comment) assert.NotNil(t, tree, test.comment) - res, err := CallVerifier(test.env, tree) + res, err := CallTreeVerifier(test.env, tree) require.NoError(t, err, test.comment) require.NotNil(t, res, test.comment) @@ -330,7 +329,7 @@ func TestFunctionsEvaluation(t *testing.T) { require.NoError(t, err, test.name) assert.NotNil(t, tree, test.name) - res, err := CallVerifier(test.env, tree) + res, err := CallTreeVerifier(test.env, tree) if test.error { assert.Error(t, err, "No error in "+test.name) } else { @@ -360,7 +359,7 @@ func TestOverlapping(t *testing.T) { require.NoError(t, err) assert.NotNil(t, tree) - res, err := CallVerifier(nil, tree) + res, err := CallTreeVerifier(nil, tree) require.NoError(t, err) r, ok := res.(ScriptResult) require.True(t, ok) @@ -383,7 +382,7 @@ func TestUserFunctionsInExpression(t *testing.T) { require.NoError(t, err) assert.NotNil(t, tree) - res, err := CallVerifier(nil, tree) + res, err := CallTreeVerifier(nil, tree) require.NoError(t, err) r, ok := res.(ScriptResult) require.True(t, ok) @@ -444,7 +443,7 @@ func TestDataFunctions(t *testing.T) { require.NoError(t, err, test.name) assert.NotNil(t, tree, test.name) - res, err := CallVerifier(env, tree) + res, err := CallTreeVerifier(env, tree) require.NoError(t, err, test.name) r, ok := res.(ScriptResult) require.True(t, ok, test.name) @@ -516,7 +515,7 @@ func TestDappCallable(t *testing.T) { require.NoError(t, err) assert.NotNil(t, tree) - res, err := CallFunction(env, tree, "tellme", proto.Arguments{proto.NewStringArgument("abc")}) + res, err := CallTreeFunction("", env, tree, "tellme", proto.Arguments{proto.NewStringArgument("abc")}) require.NoError(t, err) r, ok := res.(DAppResult) require.True(t, ok) @@ -583,7 +582,7 @@ func TestDappDefaultFunc(t *testing.T) { require.NoError(t, err) assert.NotNil(t, tree) - res, err := CallFunction(env, tree, "", proto.Arguments{}) + res, err := CallTreeFunction("", env, tree, "", proto.Arguments{}) require.NoError(t, err) r, ok := res.(DAppResult) require.True(t, ok) @@ -647,7 +646,7 @@ func TestDappVerify(t *testing.T) { require.NoError(t, err) assert.NotNil(t, tree) - res, err := CallVerifier(env, tree) + res, err := CallTreeVerifier(env, tree) require.NoError(t, err) r, ok := res.(ScriptResult) require.True(t, ok) @@ -679,7 +678,7 @@ func TestDappVerifySuccessful(t *testing.T) { require.NoError(t, err) assert.NotNil(t, tree) - res, err := CallVerifier(env, tree) + res, err := CallTreeVerifier(env, tree) require.NoError(t, err) r, ok := res.(ScriptResult) require.True(t, ok) @@ -708,7 +707,7 @@ func TestTransferSet(t *testing.T) { require.NoError(t, err) assert.NotNil(t, tree) - res, err := CallFunction(env, tree, "tellme", proto.Arguments{proto.NewIntegerArgument(100500)}) + res, err := CallTreeFunction("", env, tree, "tellme", proto.Arguments{proto.NewIntegerArgument(100500)}) require.NoError(t, err) r, ok := res.(DAppResult) require.True(t, ok) @@ -760,7 +759,7 @@ func TestScriptResult(t *testing.T) { require.NoError(t, err) assert.NotNil(t, tree) - res, err := CallFunction(env, tree, "tellme", proto.Arguments{proto.NewIntegerArgument(100)}) + res, err := CallTreeFunction("", env, tree, "tellme", proto.Arguments{proto.NewIntegerArgument(100)}) require.NoError(t, err) r, ok := res.(DAppResult) require.True(t, ok) @@ -854,7 +853,7 @@ func TestMatchOverwrite(t *testing.T) { require.NoError(t, err) assert.NotNil(t, tree) - res, err := CallVerifier(env, tree) + res, err := CallTreeVerifier(env, tree) require.NoError(t, err) r, ok := res.(ScriptResult) require.True(t, ok) @@ -913,7 +912,7 @@ func TestFailSript1(t *testing.T) { require.NoError(t, err) assert.NotNil(t, tree) - res, err := CallVerifier(env, tree) + res, err := CallTreeVerifier(env, tree) require.NoError(t, err) r, ok := res.(ScriptResult) require.True(t, ok) @@ -1025,7 +1024,7 @@ func TestFailSript2(t *testing.T) { require.NoError(t, err) assert.NotNil(t, tree) - res, err := CallVerifier(env, tree) + res, err := CallTreeVerifier(env, tree) require.NoError(t, err) r, ok := res.(ScriptResult) require.True(t, ok) @@ -1140,7 +1139,7 @@ func TestWhaleDApp(t *testing.T) { require.NoError(t, err) assert.NotNil(t, tree) - res, err := CallFunction(env, tree, "inviteuser", arguments) + res, err := CallTreeFunction("", env, tree, "inviteuser", arguments) require.NoError(t, err) r, ok := res.(DAppResult) require.True(t, ok) @@ -1266,7 +1265,7 @@ func TestExchangeDApp(t *testing.T) { require.NoError(t, err) assert.NotNil(t, tree) - res, err := CallFunction(env, tree, "cancel", arguments) + res, err := CallTreeFunction("", env, tree, "cancel", arguments) require.NoError(t, err) r, ok := res.(DAppResult) require.True(t, ok) @@ -1433,7 +1432,7 @@ func TestBankDApp(t *testing.T) { require.NoError(t, err) assert.NotNil(t, tree) - res, err := CallFunction(env, tree, "buyBack", proto.Arguments{}) + res, err := CallTreeFunction("", env, tree, "buyBack", proto.Arguments{}) require.NoError(t, err) _, ok := res.(DAppResult) require.True(t, ok) @@ -1577,7 +1576,7 @@ func TestLigaDApp1(t *testing.T) { require.NoError(t, err) assert.NotNil(t, tree) - res, err := CallFunction(env, tree, "stage2", proto.Arguments{}) + res, err := CallTreeFunction("", env, tree, "stage2", proto.Arguments{}) require.NoError(t, err) r, ok := res.(DAppResult) require.True(t, ok) @@ -1761,7 +1760,7 @@ func TestLigaDApp1(t *testing.T) { }, } - res, err = CallFunction(env, tree, "stage31", args2) + res, err = CallTreeFunction("", env, tree, "stage31", args2) require.NoError(t, err) r, ok = res.(DAppResult) require.True(t, ok) @@ -1890,7 +1889,7 @@ func TestTestingDApp(t *testing.T) { require.NoError(t, err) assert.NotNil(t, tree) - res, err := CallFunction(env, tree, "main", arguments) + res, err := CallTreeFunction("", env, tree, "main", arguments) require.NoError(t, err) r, ok := res.(DAppResult) require.True(t, ok) @@ -2003,7 +2002,7 @@ func TestDropElementDApp(t *testing.T) { require.NoError(t, err) assert.NotNil(t, tree) - res, err := CallFunction(env, tree, "dropElementInArray", arguments) + res, err := CallTreeFunction("", env, tree, "dropElementInArray", arguments) require.NoError(t, err) r, ok := res.(DAppResult) require.True(t, ok) @@ -2117,7 +2116,7 @@ func TestMathDApp(t *testing.T) { require.NoError(t, err) assert.NotNil(t, tree) - res, err := CallFunction(env, tree, "coxRossRubinsteinCall", arguments) + res, err := CallTreeFunction("", env, tree, "coxRossRubinsteinCall", arguments) require.NoError(t, err) r, ok := res.(DAppResult) require.True(t, ok) @@ -2243,7 +2242,7 @@ func TestDAppWithInvalidAddress(t *testing.T) { tree, err := Parse(src) require.NoError(t, err) assert.NotNil(t, tree) - res, err := CallFunction(env, tree, "deposit", arguments) + res, err := CallTreeFunction("", env, tree, "deposit", arguments) require.NoError(t, err) r, ok := res.(DAppResult) require.True(t, ok) @@ -2372,7 +2371,7 @@ func Test8Ball(t *testing.T) { tree, err := Parse(src) require.NoError(t, err) assert.NotNil(t, tree) - res, err := CallFunction(env, tree, "tellme", arguments) + res, err := CallTreeFunction("", env, tree, "tellme", arguments) require.NoError(t, err) r, ok := res.(DAppResult) require.True(t, ok) @@ -2480,7 +2479,7 @@ func TestIntegerEntry(t *testing.T) { tree, err := Parse(src) require.NoError(t, err) assert.NotNil(t, tree) - _, err = CallFunction(env, tree, "tellme", arguments) + _, err = CallTreeFunction("", env, tree, "tellme", arguments) assert.Error(t, err) } @@ -2535,7 +2534,7 @@ func TestAssetInfoV3V4(t *testing.T) { require.NoError(t, err) assert.NotNil(t, treeV3) - res, err := CallVerifier(env, treeV3) + res, err := CallTreeVerifier(env, treeV3) require.NoError(t, err) r, ok := res.(ScriptResult) require.True(t, ok) @@ -2556,7 +2555,7 @@ func TestAssetInfoV3V4(t *testing.T) { require.NoError(t, err) assert.NotNil(t, treeV3) - res, err = CallVerifier(env, treeV4) + res, err = CallTreeVerifier(env, treeV4) require.NoError(t, err) r, ok = res.(ScriptResult) require.True(t, ok) @@ -2572,7 +2571,7 @@ func TestJSONParsing(t *testing.T) { require.NoError(t, err) assert.NotNil(t, tree) - res, err := CallVerifier(nil, tree) + res, err := CallTreeVerifier(nil, tree) require.NoError(t, err) r, ok := res.(ScriptResult) require.True(t, ok) @@ -2594,7 +2593,7 @@ func TestDAppWithFullIssue(t *testing.T) { return rideBytes(id) }, } - res, err := CallFunction(env, tree, "issue", proto.Arguments{&proto.StringArgument{Value: "xxx"}}) + res, err := CallTreeFunction("", env, tree, "issue", proto.Arguments{&proto.StringArgument{Value: "xxx"}}) require.NoError(t, err) r, ok := res.(DAppResult) require.True(t, ok) @@ -2620,7 +2619,7 @@ func TestDAppWithSimpleIssue(t *testing.T) { return rideBytes(id) }, } - res, err := CallFunction(env, tree, "issue", proto.Arguments{&proto.StringArgument{Value: "xxx"}}) + res, err := CallTreeFunction("", env, tree, "issue", proto.Arguments{&proto.StringArgument{Value: "xxx"}}) require.NoError(t, err) r, ok := res.(DAppResult) require.True(t, ok) @@ -2722,7 +2721,7 @@ func TestBadType(t *testing.T) { tree, err := Parse(src) require.NoError(t, err) assert.NotNil(t, tree) - res, err := CallFunction(env, tree, "initDraw", arguments) + res, err := CallTreeFunction("", env, tree, "initDraw", arguments) require.NoError(t, err) r, ok := res.(DAppResult) require.True(t, ok) @@ -2884,7 +2883,7 @@ func TestNoDeclaration(t *testing.T) { tree, err := Parse(src) require.NoError(t, err) assert.NotNil(t, tree) - res, err := CallFunction(env, tree, "settle", arguments) + res, err := CallTreeFunction("", env, tree, "settle", arguments) require.NoError(t, err) r, ok := res.(DAppResult) require.True(t, ok) @@ -3071,7 +3070,7 @@ func TestZeroReissue(t *testing.T) { tree, err := Parse(src) require.NoError(t, err) assert.NotNil(t, tree) - res, err := CallFunction(env, tree, "replenishment", arguments) + res, err := CallTreeFunction("", env, tree, "replenishment", arguments) require.NoError(t, err) r, ok := res.(DAppResult) require.True(t, ok) @@ -3291,7 +3290,7 @@ func TestStageNet2(t *testing.T) { tree, err := Parse(src) require.NoError(t, err) assert.NotNil(t, tree) - res, err := CallFunction(env, tree, "purchaseToken", arguments) + res, err := CallTreeFunction("", env, tree, "purchaseToken", arguments) require.NoError(t, err) r, ok := res.(DAppResult) require.True(t, ok) @@ -3375,7 +3374,7 @@ func TestRecipientAddressToString(t *testing.T) { checkMessageLengthFunc: v3check, } - res, err := CallVerifier(env, tree) + res, err := CallTreeVerifier(env, tree) require.NoError(t, err) r, ok := res.(ScriptResult) require.True(t, ok) @@ -3425,7 +3424,7 @@ func TestScriptPaymentPublicKey(t *testing.T) { require.NoError(t, err) assert.NotNil(t, tree) - res, err := CallVerifier(env, tree) + res, err := CallTreeVerifier(env, tree) require.NoError(t, err) r, ok := res.(ScriptResult) require.True(t, ok) @@ -3489,7 +3488,7 @@ func TestInvalidAssetInTransferScriptAction(t *testing.T) { tree, err := Parse(src) require.NoError(t, err) assert.NotNil(t, tree) - res, err := CallFunction(env, tree, "swapRKMTToWAVES", arguments) + res, err := CallTreeFunction("", env, tree, "swapRKMTToWAVES", arguments) require.NoError(t, err) r, ok := res.(DAppResult) require.True(t, ok) @@ -3515,3 +3514,58 @@ func TestInvalidAssetInTransferScriptAction(t *testing.T) { } assert.Equal(t, expectedResult, sr) } + +/** +let height = height +height != 0 +*/ +func TestTreeShadowedVariable(t *testing.T) { + source := `AwoBAAAAD2dldFByaWNlSGlzdG9yeQAAAAEAAAAGaGVpZ2h0BQAAAAZoZWlnaHQJAQAAAAIhPQAAAAIJAQAAAA9nZXRQcmljZUhpc3RvcnkAAAABBQAAAAZoZWlnaHQAAAAAAAAAAADe0Skk` + + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(t, err) + + tree, err := Parse(src) + require.NoError(t, err) + tree = MustExpand(tree) + //require.Equal(t, "(let height = { height }; height != 0)", DecompileTree(tree)) + + result, err := CallTreeVerifier(defaultEnv, tree) + require.NoError(t, err) + require.Equal(t, true, result.Result()) +} + +/** +{-# STDLIB_VERSION 3 #-} +{-# SCRIPT_TYPE ACCOUNT #-} +{-# CONTENT_TYPE EXPRESSION #-} +func xx(height: Int) = { + height +} + +func yy(height: Int) = { + xx(height) +} + +yy(height) == 1 +*/ +func TestTreeShadowedVariable2(t *testing.T) { + source := `AwoBAAAAAnh4AAAAAQAAAAZoZWlnaHQFAAAABmhlaWdodAoBAAAAAnl5AAAAAQAAAAZoZWlnaHQJAQAAAAJ4eAAAAAEFAAAABmhlaWdodAkAAAAAAAACCQEAAAACeXkAAAABBQAAAAZoZWlnaHQAAAAAAAAAAAHVMsKD` + + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(t, err) + + tree, err := Parse(src) + require.NoError(t, err) + tree = MustExpand(tree) + require.Equal(t, "(let height$yy = { height }; let height$xx = { height$yy }; height$xx == 1)", DecompileTree(tree)) + + result, err := CallTreeVerifier(defaultEnv, tree) + require.NoError(t, err) + require.Equal(t, false, result.Result()) +} + +func TestTtt(t *testing.T) { + r := newNameReplacements().addAll("$yy", []string{"address", "key"}) + _ = r +} diff --git a/pkg/ride/tree_evaluator.go b/pkg/ride/tree_evaluator.go index 618cb315c..9a0072afc 100644 --- a/pkg/ride/tree_evaluator.go +++ b/pkg/ride/tree_evaluator.go @@ -1,10 +1,73 @@ package ride import ( + im "github.com/frozen/immutable_map" "github.com/pkg/errors" "github.com/wavesplatform/gowaves/pkg/proto" ) +type varsCtx struct { + im *im.Map +} + +func (a varsCtx) add(name string, n Node, funcCtx funcCtx) varsCtx { + return varsCtx{ + im: a.im.Insert([]byte(name), &esValue{ + value: nil, + expression: n, + varsCtx: a, + funcCtx: funcCtx, + }), + } +} + +func (a varsCtx) addValue(name string, n rideType, funcCtx funcCtx) varsCtx { + return varsCtx{ + im: a.im.Insert([]byte(name), &esValue{ + value: n, + varsCtx: a, + funcCtx: funcCtx, + }), + } +} + +func (a varsCtx) get(name string) *esValue { + v := a.im.Get1([]byte(name)) + if v != nil { + return v.(*esValue) + } + return nil +} + +func newVarsCtx() varsCtx { + return varsCtx{im: im.New()} +} + +type funcCtx struct { + im *im.Map +} + +func (a funcCtx) add(name string, n *FunctionDeclarationNode, varsCtx varsCtx) funcCtx { + return funcCtx{ + im: a.im.Insert([]byte(name), &esFunction{ + fn: n, + varsCtx: varsCtx, + }), + } +} + +func (a funcCtx) get(name string) *esFunction { + v := a.im.Get1([]byte(name)) + if v == nil { + return nil + } + return v.(*esFunction) +} + +func newFuncCtx() funcCtx { + return funcCtx{im: im.New()} +} + type esConstant struct { value rideType c rideConstructor @@ -14,45 +77,39 @@ type esValue struct { id string value rideType expression Node + varsCtx varsCtx + funcCtx funcCtx } type esFunction struct { - fn *FunctionDeclarationNode - sp int + fn *FunctionDeclarationNode + varsCtx varsCtx } type evaluationScope struct { env RideEnvironment constants map[string]esConstant - cs [][]esValue + cs varsCtx + fs funcCtx system map[string]rideFunction - user []esFunction cl int } func (s *evaluationScope) declare(n Node) error { switch d := n.(type) { case *FunctionDeclarationNode: - s.pushUserFunction(d) + s.fs = s.fs.add(d.Name, d, s.cs) return nil case *AssignmentNode: - s.pushExpression(d.Name, d.Expression) + s.cs = s.cs.add(d.Name, d.Expression, s.fs) return nil default: return errors.Errorf("not a declaration '%T'", n) } } -func (s *evaluationScope) pushExpression(id string, n Node) { - s.cs[len(s.cs)-1] = append(s.cs[len(s.cs)-1], esValue{id: id, expression: n}) -} - func (s *evaluationScope) pushValue(id string, v rideType) { - s.cs[len(s.cs)-1] = append(s.cs[len(s.cs)-1], esValue{id: id, value: v}) -} - -func (s *evaluationScope) popValue() { - s.cs[len(s.cs)-1] = s.cs[len(s.cs)-1][:len(s.cs[len(s.cs)-1])-1] + s.cs = s.cs.addValue(id, v, s.fs) } func (s *evaluationScope) constant(id string) (rideType, bool) { @@ -67,54 +124,6 @@ func (s *evaluationScope) constant(id string) (rideType, bool) { return nil, false } -func lookup(s []esValue, id string) (esValue, bool) { - for i := len(s) - 1; i >= 0; i-- { - if v := s[i]; v.id == id { - return v, true - } - } - return esValue{}, false -} - -func (s *evaluationScope) value(id string) (esValue, bool) { - if p := len(s.cs) - 1; p >= 0 { - v, ok := lookup(s.cs[p], id) - if ok { - return v, true - } - } - for i := s.cl - 1; i >= 0; i-- { - v, ok := lookup(s.cs[i], id) - if ok { - return v, true - } - } - return esValue{}, false -} - -func (s *evaluationScope) pushUserFunction(uf *FunctionDeclarationNode) { - s.user = append(s.user, esFunction{fn: uf, sp: len(s.cs)}) -} - -func (s *evaluationScope) popUserFunction() error { - l := len(s.user) - if l == 0 { - return errors.New("empty user functions scope") - } - s.user = s.user[:l-1] - return nil -} - -func (s *evaluationScope) userFunction(id string) (*FunctionDeclarationNode, int, error) { - for i := len(s.user) - 1; i >= 0; i-- { - uf := s.user[i] - if uf.fn.Name == id { - return uf.fn, uf.sp, nil - } - } - return nil, 0, errors.Errorf("user function '%s' is not found", id) -} - func newEvaluationScope(v int, env RideEnvironment) (evaluationScope, error) { constants, err := selectConstantNames(v) if err != nil { @@ -159,7 +168,8 @@ func newEvaluationScope(v int, env RideEnvironment) (evaluationScope, error) { return evaluationScope{ constants: cs, system: fs, - cs: [][]esValue{make([]esValue, 0)}, + cs: newVarsCtx(), + fs: newFuncCtx(), env: env, }, nil } @@ -200,34 +210,39 @@ func selectFunctionNames(v int) ([]string, error) { } } +type callLog struct { + name string + args []rideType + result rideType +} + type treeEvaluator struct { - dapp bool - //limit int - //cost int - f Node - s evaluationScope - env RideEnvironment + dapp bool + f Node + s evaluationScope + env RideEnvironment + calls []callLog } func (e *treeEvaluator) evaluate() (RideResult, error) { - r, err := e.walk(e.f) + r, err := e.walk(e.f, e.s.cs, e.s.fs) if err != nil { return nil, err } switch res := r.(type) { case rideThrow: if e.dapp { - return DAppResult{res: false, msg: string(res)}, nil + return DAppResult{res: false, msg: string(res), calls: e.calls}, nil } - return ScriptResult{res: false, msg: string(res)}, nil + return ScriptResult{res: false, msg: string(res), calls: e.calls}, nil case rideBoolean: - return ScriptResult{res: bool(res)}, nil + return ScriptResult{res: bool(res), calls: e.calls}, nil case rideObject: actions, err := objectToActions(e.env, res) if err != nil { return nil, errors.Wrap(err, "failed to convert evaluation result") } - return DAppResult{true, actions, ""}, nil + return DAppResult{res: true, actions: actions, msg: "", calls: e.calls}, nil case rideList: actions := make([]proto.ScriptAction, len(res)) for i, item := range res { @@ -237,22 +252,17 @@ func (e *treeEvaluator) evaluate() (RideResult, error) { } actions[i] = a } - return DAppResult{res: true, actions: actions}, nil + return DAppResult{res: true, actions: actions, calls: e.calls}, nil default: return nil, errors.Errorf("unexpected result type '%T'", r) } } -// -//func (e *treeEvaluator) exceeded() bool { -// return e.limit > 0 && e.cost >= e.limit -//} - func isThrow(r rideType) bool { return r.instanceOf() == "Throw" } -func (e *treeEvaluator) walk(node Node) (rideType, error) { +func (e *treeEvaluator) walk(node Node, varsCtx varsCtx, funcCtx funcCtx) (rideType, error) { switch n := node.(type) { case *LongNode: return rideInt(n.Value), nil @@ -267,7 +277,7 @@ func (e *treeEvaluator) walk(node Node) (rideType, error) { return rideString(n.Value), nil case *ConditionalNode: - ce, err := e.walk(n.Condition) + ce, err := e.walk(n.Condition, varsCtx, funcCtx) if err != nil { return nil, errors.Wrap(err, "failed to estimate the condition of if") } @@ -279,28 +289,26 @@ func (e *treeEvaluator) walk(node Node) (rideType, error) { return nil, errors.Errorf("not a boolean") } if cr { - return e.walk(n.TrueExpression) + return e.walk(n.TrueExpression, varsCtx, funcCtx) } else { - return e.walk(n.FalseExpression) + return e.walk(n.FalseExpression, varsCtx, funcCtx) } case *AssignmentNode: id := n.Name - e.s.pushExpression(id, n.Expression) - r, err := e.walk(n.Block) + r, err := e.walk(n.Block, varsCtx.add(id, n.Expression, funcCtx), funcCtx) if err != nil { return nil, errors.Wrapf(err, "failed to evaluate block after declaration of variable '%s'", id) } if isThrow(r) { return r, nil } - e.s.popValue() return r, nil case *ReferenceNode: id := n.Name - v, ok := e.s.value(id) - if !ok { + v := varsCtx.get(id) + if v == nil { if v, ok := e.s.constant(id); ok { return v, nil } @@ -310,32 +318,27 @@ func (e *treeEvaluator) walk(node Node) (rideType, error) { if v.expression == nil { return nil, errors.Errorf("scope value '%s' is empty", id) } - r, err := e.walk(v.expression) + r, err := e.walk(v.expression, v.varsCtx, v.funcCtx) if err != nil { return nil, errors.Wrapf(err, "failed to evaluate expression of scope value '%s'", id) } if isThrow(r) { return r, nil } - e.s.pushValue(id, r) + v.value = r return r, nil } return v.value, nil case *FunctionDeclarationNode: id := n.Name - e.s.pushUserFunction(n) - r, err := e.walk(n.Block) + r, err := e.walk(n.Block, varsCtx, funcCtx.add(id, n, varsCtx)) if err != nil { return nil, errors.Wrapf(err, "failed to evaluate block after declaration of function '%s'", id) } if isThrow(r) { return r, nil } - err = e.s.popUserFunction() - if err != nil { - return nil, errors.Wrapf(err, "failed to evaluate declaration of function '%s'", id) - } return r, nil case *FunctionCallNode: @@ -344,7 +347,7 @@ func (e *treeEvaluator) walk(node Node) (rideType, error) { if ok { // System function args := make([]rideType, len(n.Arguments)) for i, arg := range n.Arguments { - a, err := e.walk(arg) // materialize argument + a, err := e.walk(arg, varsCtx, funcCtx) // materialize argument if err != nil { return nil, errors.Wrapf(err, "failed to materialize argument %d of system function '%s'", i+1, id) } @@ -354,22 +357,28 @@ func (e *treeEvaluator) walk(node Node) (rideType, error) { args[i] = a } r, err := f(e.env, args...) + e.calls = append(e.calls, callLog{ + name: id, + args: args, + result: r, + }) if err != nil { return nil, errors.Wrapf(err, "failed to call system function '%s'", id) } return r, nil } - uf, cl, err := e.s.userFunction(id) - if err != nil { - return nil, errors.Wrapf(err, "failed to call function '%s'", id) + uf := funcCtx.get(id) + if uf == nil { + return nil, errors.Errorf("failed to call function '%s'", id) } - if len(n.Arguments) != len(uf.Arguments) { + if len(n.Arguments) != len(uf.fn.Arguments) { return nil, errors.Errorf("mismatched arguments number of user function '%s'", id) } + localVars := uf.varsCtx args := make([]esValue, len(n.Arguments)) for i, arg := range n.Arguments { - an := uf.Arguments[i] - av, err := e.walk(arg) // materialize argument + an := uf.fn.Arguments[i] + av, err := e.walk(arg, varsCtx, funcCtx) // materialize argument if err != nil { return nil, errors.Wrapf(err, "failed to materialize argument '%s' of user function '%s", an, id) } @@ -377,24 +386,19 @@ func (e *treeEvaluator) walk(node Node) (rideType, error) { return av, nil } args[i] = esValue{id: an, value: av} - } - e.s.cs = append(e.s.cs, make([]esValue, len(args))) - for i, arg := range args { - e.s.cs[len(e.s.cs)-1][i] = arg + localVars = localVars.addValue(an, av, funcCtx) } var tmp int - tmp, e.s.cl = e.s.cl, cl - r, err := e.walk(uf.Body) + r, err := e.walk(uf.fn.Body, localVars, funcCtx) if err != nil { return nil, errors.Wrapf(err, "failed to evaluate function '%s' body", id) } - e.s.cs = e.s.cs[:len(e.s.cs)-1] e.s.cl = tmp return r, nil case *PropertyNode: name := n.Name - obj, err := e.walk(n.Object) + obj, err := e.walk(n.Object, varsCtx, funcCtx) if err != nil { return nil, errors.Wrapf(err, "failed to evaluate an object to get property '%s' on it", name) } @@ -413,6 +417,7 @@ func (e *treeEvaluator) walk(node Node) (rideType, error) { } func treeVerifierEvaluator(env RideEnvironment, tree *Tree) (*treeEvaluator, error) { + s, err := newEvaluationScope(tree.LibVersion, env) if err != nil { return nil, errors.Wrap(err, "failed to create scope") @@ -447,7 +452,10 @@ func treeVerifierEvaluator(env RideEnvironment, tree *Tree) (*treeEvaluator, err }, nil } -func treeFunctionEvaluator(env RideEnvironment, tree *Tree, name string, args proto.Arguments) (*treeEvaluator, error) { +func treeFunctionEvaluator(env RideEnvironment, tree *Tree, name string, args []rideType) (*treeEvaluator, error) { + if name == "" { + name = "default" + } s, err := newEvaluationScope(tree.LibVersion, env) if err != nil { return nil, errors.Wrap(err, "failed to create scope") @@ -472,13 +480,14 @@ func treeFunctionEvaluator(env RideEnvironment, tree *Tree, name string, args pr return nil, errors.Errorf("invalid arguments count %d for function '%s'", l, name) } for i, arg := range args { - a, err := convertArgument(arg) - if err != nil { - return nil, errors.Wrapf(err, "failed to call function '%s'", name) - } - s.pushValue(function.Arguments[i], a) + s.pushValue(function.Arguments[i], arg) } - return &treeEvaluator{dapp: true, f: function.Body, s: s, env: env}, nil + return &treeEvaluator{ + dapp: true, + f: function.Body, + s: s, + env: env, + }, nil } } return nil, errors.Errorf("function '%s' not found", name) diff --git a/pkg/ride/tree_expand.go b/pkg/ride/tree_expand.go new file mode 100644 index 000000000..9f2e9134e --- /dev/null +++ b/pkg/ride/tree_expand.go @@ -0,0 +1,183 @@ +package ride + +import ( + "fmt" + + im "github.com/frozen/immutable_map" + "github.com/pkg/errors" +) + +type expandScope struct { + im *im.Map +} + +func newExpandScope() expandScope { + return expandScope{ + im: im.New(), + } +} + +func (a expandScope) add(name string, n *FunctionDeclarationNode) expandScope { + return expandScope{ + im: a.im.Insert([]byte(name), n), + } +} + +func (a expandScope) get(name string) (*FunctionDeclarationNode, bool) { + v, ok := a.im.Get([]byte(name)) + if ok { + return v.(*FunctionDeclarationNode), true + } + return nil, false +} + +func (a expandScope) get1(name string) *FunctionDeclarationNode { + v, ok := a.im.Get([]byte(name)) + if ok { + return v.(*FunctionDeclarationNode) + } + return nil +} + +type nameReplacements struct { + im *im.Map +} + +func newNameReplacements() nameReplacements { + return nameReplacements{ + im: im.New(), + } +} + +func (a nameReplacements) add(original string, replacement string) nameReplacements { + return nameReplacements{ + im: a.im.Insert([]byte(original), replacement), + } +} + +func (a nameReplacements) addAll(postfix string, args []string) nameReplacements { + tmp := a + for _, arg := range args { + tmp = tmp.add(arg, arg+postfix) + } + return tmp +} + +func (a nameReplacements) get(name string) string { + inf, ok := a.im.Get([]byte(name)) + if ok { + return inf.(string) + } + return name +} + +func Expand(t *Tree) (*Tree, error) { + if t.Expanded { + return t, nil + } + scope := newExpandScope() + declarations := make([]Node, 0, len(t.Declarations)) + for _, f := range t.Declarations { + v, ok := f.(*FunctionDeclarationNode) + if !ok { + declarations = append(declarations, expand(scope, f, newNameReplacements())) + continue + } + v2 := cloneFuncDecl(v, expand(scope, v.Body, newNameReplacements().addAll("$"+v.Name, v.Arguments)), nil) + scope = scope.add(v.Name, v2) + } + functions := make([]Node, 0, len(t.Functions)) + for _, f := range t.Functions { + v, ok := f.(*FunctionDeclarationNode) + if !ok { + return nil, errors.Errorf("can't expand tree. Expected function to be `*FunctionDeclarationNode`, found %T", f) + } + v2 := v.Clone().(*FunctionDeclarationNode) + v2.Body = expand(scope, v.Body, newNameReplacements()) + scope = scope.add(v.Name, v2) + functions = append(functions, v2) + } + var verifier Node + if t.IsDApp() && t.HasVerifier() { + verifier = cloneFuncDecl(t.Verifier.(*FunctionDeclarationNode), expand(scope, t.Verifier.(*FunctionDeclarationNode).Body, newNameReplacements()), nil) + } else { + verifier = expand(scope, t.Verifier, newNameReplacements()) + } + return &Tree{ + Digest: t.Digest, + AppVersion: t.AppVersion, + LibVersion: t.LibVersion, + HasBlockV2: t.HasBlockV2, + Meta: t.Meta, + Declarations: declarations, + Functions: functions, + Verifier: verifier, + Expanded: true, + }, nil +} + +func MustExpand(t *Tree) *Tree { + rs, err := Expand(t) + if err != nil { + panic(err) + } + return rs +} + +func expand(scope expandScope, node Node, replacements nameReplacements) Node { + switch v := node.(type) { + case *FunctionCallNode: + f, ok := scope.get(v.Name) + if ok { + root := f.Body + for i := len(v.Arguments) - 1; i >= 0; i-- { + root = &AssignmentNode{ + Name: fmt.Sprintf("%s$%s", f.Arguments[i], f.Name), + Expression: expand(scope, v.Arguments[i], replacements), + Block: root, + } + } + return root + } else { + return &FunctionCallNode{ + Name: v.Name, + Arguments: v.Arguments.Map(func(node Node) Node { + return expand(scope, node, replacements) + }), + } + } + + case *FunctionDeclarationNode: + + body := expand(scope, v.Body, replacements.addAll("$"+v.Name, v.Arguments)) + v2 := cloneFuncDecl(v, body, nil) + block := expand(scope.add(v.Name, v2), v.Block, replacements) + return block + + case *AssignmentNode: + return &AssignmentNode{ + Name: v.Name, + Block: expand(scope, v.Block, replacements), + Expression: expand(scope, v.Expression, replacements), + } + case nil: + return node + case *ConditionalNode: + return &ConditionalNode{ + Condition: expand(scope, v.Condition, replacements), + TrueExpression: expand(scope, v.TrueExpression, replacements), + FalseExpression: expand(scope, v.FalseExpression, replacements), + } + case *ReferenceNode: + return &ReferenceNode{Name: replacements.get(v.Name)} + case *StringNode, *LongNode, *BytesNode, *BooleanNode: + return v + case *PropertyNode: + return &PropertyNode{ + Name: v.Name, + Object: expand(scope, v.Object, replacements), + } + default: + panic(fmt.Sprintf("unknown %T", node)) + } +} diff --git a/pkg/ride/tree_expand_test.go b/pkg/ride/tree_expand_test.go new file mode 100644 index 000000000..bb911057c --- /dev/null +++ b/pkg/ride/tree_expand_test.go @@ -0,0 +1,295 @@ +package ride + +import ( + "bytes" + "encoding/base64" + "errors" + "fmt" + "strings" + "testing" + + "github.com/stretchr/testify/require" + "github.com/wavesplatform/gowaves/pkg/proto" + "github.com/wavesplatform/gowaves/pkg/types" +) + +func lines(ss ...string) string { + var s strings.Builder + for _, v := range ss { + s.WriteString(v) + s.WriteString(" ") + } + return strings.TrimSpace(s.String()) +} + +func TestTreeExpandWithArguments(t *testing.T) { + source := `AAIDAAAAAAAAAAgIARIECgIIAgAAAAIAAAAAAXoAAAAAAAAAAAUBAAAAAmYyAAAAAQAAAAF2CQEAAAAFdmFsdWUAAAABCQAEGgAAAAIFAAAABHRoaXMFAAAAAXYAAAABAAAAAWkBAAAAAmYxAAAAAgAAAAlzZXNzaW9uSWQAAAAHcnNhU2lnbgQAAAABeAkBAAAAAmYyAAAAAQIAAAABZQkBAAAACFdyaXRlU2V0AAAAAQUAAAADbmlsAAAAAN+I8mI=` + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(t, err) + + tree, err := Parse(src) + require.NoError(t, err) + + tree2, _ := Expand(tree) + + require.Equal(t, + lines( + `let z = { 5 };`, + `@i\nfunc f1(sessionId,rsaSign) { let x = { let v$f2 = { "e" }; value(getInteger(this,v$f2)) }; WriteSet(nil) }`, + ), + DecompileTree(tree2), + ) +} + +/** +{-# STDLIB_VERSION 3 #-} +{-# SCRIPT_TYPE ACCOUNT #-} +{-# CONTENT_TYPE DAPP #-} +func f2() = { + 5 +} + +@Callable(i) +func f1 () = { + WriteSet([DataEntry("key", f2())]) +} + +*/ +func TestTreeExpandAsArgument(t *testing.T) { + source := `AAIDAAAAAAAAAAQIARIAAAAAAQEAAAACZjIAAAAAAAAAAAAAAAAFAAAAAQAAAAFpAQAAAAJmMQAAAAAJAQAAAAhXcml0ZVNldAAAAAEJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAAA2tleQkBAAAAAmYyAAAAAAUAAAADbmlsAAAAABmdzZY=` + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(t, err) + + tree, err := Parse(src) + require.NoError(t, err) + + tree2, _ := Expand(tree) + + require.Equal(t, + `@i\nfunc f1() { WriteSet(1100(DataEntry("key",5),nil)) }`, + DecompileTree(tree2), + ) +} + +/** +{-# STDLIB_VERSION 3 #-} +{-# SCRIPT_TYPE ACCOUNT #-} +{-# CONTENT_TYPE DAPP #-} +func call(v: Int) = { + func f2() = { + 10 + } + f2() +} + +func f2() = { + 5 +} + +@Callable(i) +func callback () = { + let x = call(0) + WriteSet([DataEntry("key", f2())]) +} +*/ +func TestTreeExpandWithNamesIntersection(t *testing.T) { + source := `AAIDAAAAAAAAAAQIARIAAAAAAgEAAAAEY2FsbAAAAAEAAAABdgoBAAAAAmYyAAAAAAAAAAAAAAAACgkBAAAAAmYyAAAAAAEAAAACZjIAAAAAAAAAAAAAAAAFAAAAAQAAAAFpAQAAAAhjYWxsYmFjawAAAAAEAAAAAXgJAQAAAARjYWxsAAAAAQAAAAAAAAAAAAkBAAAACFdyaXRlU2V0AAAAAQkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAADa2V5CQEAAAACZjIAAAAABQAAAANuaWwAAAAA/C/YQQ==` + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(t, err) + + tree, err := Parse(src) + require.NoError(t, err) + + tree2, _ := Expand(tree) + + require.Equal(t, + `@i\nfunc callback() { let x = { let v$call = { 0 }; 10 }; WriteSet(1100(DataEntry("key",5),nil)) }`, + DecompileTree(tree2), + ) +} + +func TestTreeExpand(t *testing.T) { + t.Run("expand with variable and func name collision", func(t *testing.T) { + /** + {-# STDLIB_VERSION 3 #-} + {-# SCRIPT_TYPE ACCOUNT #-} + {-# CONTENT_TYPE EXPRESSION #-} + func inc(v: Int) = v + 1 + func call(inc: Int) = { + inc(inc) + } + call(2) == 3 + */ + source := `AwoBAAAAA2luYwAAAAEAAAABdgkAAGQAAAACBQAAAAF2AAAAAAAAAAABCgEAAAAEY2FsbAAAAAEAAAADaW5jCQEAAAADaW5jAAAAAQUAAAADaW5jCQAAAAAAAAIJAQAAAARjYWxsAAAAAQAAAAAAAAAAAgAAAAAAAAAAAxgTXMY=` + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(t, err) + + tree, err := Parse(src) + require.NoError(t, err) + + tree2, _ := Expand(tree) + + require.Equal(t, + `(let inc$call = { 2 }; let v$inc = { inc$call }; (v$inc + 1) == 3)`, + DecompileTree(tree2), + ) + rs, err := CallTreeVerifier(nil, tree2) + require.NoError(t, err) + require.Equal(t, true, rs.Result()) + }) + t.Run("expand 2 functions", func(t *testing.T) { + /** + {-# STDLIB_VERSION 3 #-} + {-# SCRIPT_TYPE ACCOUNT #-} + {-# CONTENT_TYPE EXPRESSION #-} + func inc() = true + func call() = { + inc() + } + call() + */ + source := `AwoBAAAAA2luYwAAAAAGCgEAAAAEY2FsbAAAAAAJAQAAAANpbmMAAAAACQEAAAAEY2FsbAAAAAByJ2Mb` + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(t, err) + + tree, err := Parse(src) + require.NoError(t, err) + + tree2, _ := Expand(tree) + + require.Equal(t, + `true`, + DecompileTree(tree2), + ) + rs, err := CallTreeVerifier(nil, tree2) + require.NoError(t, err) + require.Equal(t, true, rs.Result()) + }) + +} + +/** +{-# STDLIB_VERSION 3 #-} +{-# SCRIPT_TYPE ACCOUNT #-} +{-# CONTENT_TYPE EXPRESSION #-} +func f2() = { + 5 +} +f2() == f2() +*/ +func TestTreeExpandExpression(t *testing.T) { + source := `AwoBAAAAAmYyAAAAAAAAAAAAAAAABQkAAAAAAAACCQEAAAACZjIAAAAACQEAAAACZjIAAAAAIckc5A==` + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(t, err) + + tree, err := Parse(src) + require.NoError(t, err) + + tree2, _ := Expand(tree) + + require.Equal(t, + `(5 == 5)`, + DecompileTree(tree2), + ) +} + +func TestExpandScope(t *testing.T) { + m := newExpandScope(). + add("inc", &FunctionDeclarationNode{Name: "inc"}). + add("call", &FunctionDeclarationNode{Name: "call"}) + + require.NotNil(t, m.get1("call")) +} + +func TestExpand(t *testing.T) { + source := `AAIDAAAAAAAAAAQIARIAAAAAAwEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABAAAAA2tleQMJAAAAAAAAAgUAAAADa2V5AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAAAAEmdldFByaWNlSGlzdG9yeUtleQAAAAEAAAAFYmxvY2sJAAEsAAAAAgIAAAAGcHJpY2VfCQABpAAAAAEFAAAABWJsb2NrAQAAAA9nZXRQcmljZUhpc3RvcnkAAAABAAAABmhlaWdodAkBAAAADmdldE51bWJlckJ5S2V5AAAAAQkBAAAAEmdldFByaWNlSGlzdG9yeUtleQAAAAEFAAAABmhlaWdodAAAAAEAAAABaQEAAAAUZmluYWxpemVDdXJyZW50UHJpY2UAAAAAAwkBAAAAAiE9AAAAAgkBAAAAD2dldFByaWNlSGlzdG9yeQAAAAEFAAAABmhlaWdodAAAAAAAAAAAAAkAAAIAAAABAgAAAA93YWl0IG5leHQgYmxvY2sJAQAAAAhXcml0ZVNldAAAAAEFAAAAA25pbAAAAACFlzmA` + + src, err := base64.StdEncoding.DecodeString(source) + require.NoError(t, err) + + tree, err := Parse(src) + tree = MustExpand(tree) + t.Log(DecompileTree(tree)) + require.NoError(t, err) + require.NotNil(t, tree) + + script, err := CompileDapp("", tree) + require.NoError(t, err) + require.NotNil(t, script) + this := []byte{1, 83, 0, 150, 158, 207, 181, 8, 55, 66, 81, 31, 197, 85, 116, 80, 81, 99, 170, 84, 137, 245, 151, 194, 97, 213} + + state := &MockSmartState{ + //NewestTransactionByIDFunc: func(_ []byte) (proto.Transaction, error) { + // return byte_helpers.TransferWithProofs.Transaction, nil + //} + // 1050 + RetrieveNewestIntegerEntryFunc: func(account proto.Recipient, key string) (*proto.IntegerDataEntry, error) { + // 2 + if bytes.Equal([]byte{1, 83, 0, 150, 158, 207, 181, 8, 55, 66, 81, 31, 197, 85, 116, 80, 81, 99, 170, 84, 137, 245, 151, 194, 97, 213}, account.Address.Bytes()) && key == "coefficient_oracle" { + return &proto.IntegerDataEntry{Key: key, Value: 3}, nil + } + // 11 + if bytes.Equal([]byte{1, 83, 116, 45, 101, 110, 53, 200, 52, 21, 10, 84, 172, 243, 171, 35, 86, 210, 136, 52, 119, 25, 63, 230, 32, 147}, account.Address.Bytes()) && key == "price_209553" { + return &proto.IntegerDataEntry{Key: key, Value: 60}, nil + } + // 17 + if bytes.Equal([]byte{1, 83, 15, 138, 8, 31, 66, 12, 76, 206, 150, 15, 215, 66, 227, 143, 47, 204, 196, 97, 159, 62, 62, 71, 220, 58}, account.Address.Bytes()) && key == "price_209553" { + return &proto.IntegerDataEntry{Key: key, Value: 60}, nil + } + // 23 + if bytes.Equal([]byte{1, 83, 59, 25, 51, 179, 38, 169, 228, 134, 63, 30, 65, 161, 51, 193, 50, 252, 107, 192, 198, 211, 1, 181, 85, 155}, account.Address.Bytes()) && key == "price_209553" { + return &proto.IntegerDataEntry{Key: key, Value: 60}, nil + } + // 29 + if bytes.Equal([]byte{1, 83, 136, 55, 96, 43, 245, 23, 100, 121, 143, 9, 41, 146, 104, 231, 155, 80, 89, 107, 191, 124, 84, 104, 99, 235}, account.Address.Bytes()) && key == "price_209553" { + return nil, errors.New("not found") + } + panic(fmt.Sprintf("RetrieveNewestIntegerEntryFunc %+v %s", account.Address.Bytes(), key)) + }, + RetrieveNewestBooleanEntryFunc: func(account proto.Recipient, key string) (*proto.BooleanDataEntry, error) { + return nil, errors.New(key + " not found") + }, + // 1053 + RetrieveNewestStringEntryFunc: func(account proto.Recipient, key string) (*proto.StringDataEntry, error) { + if !bytes.Equal(account.Address.Bytes(), this) { + panic("not equal bytes") + } + switch key { + // 4 + case "oracles": + return &proto.StringDataEntry{Key: key, Value: "3MbAmZFN3uQ1j2SMj28K32esXKSre2uVVf8,3MRzeHJTxhcAw3FhPbwPSR2ZxA7M8hA5AzV,3MVxxrC79QE2tZufp3pdoWWpnNPpZw3Vw2A,3Mczj2UD9swFgFCyqpfPAacJpn2UTu43vVY,3MYzuVPkN2gaLa5RDUesuUQEq8wWh7Y71GR"}, nil + default: + panic("unknown key " + key) + } + }, + } + env := &MockRideEnvironment{ + transactionFunc: testTransferObject, + stateFunc: func() types.SmartState { + return state + }, + schemeFunc: func() byte { + return 'S' + }, + checkMessageLengthFunc: func(in1 int) bool { + return true + }, + thisFunc: func() rideType { + return rideBytes(this) + }, + invocationFunc: func() rideObject { + return nil + }, + heightFunc: func() rideInt { + return rideInt(209553) + }, + } + + rsT, err := CallTreeFunction("", env, tree, "finalizeCurrentPrice", nil) + require.NoError(t, err) + _ = rsT + + rs, err := script.Invoke(env, "finalizeCurrentPrice", nil) + require.NoError(t, err) + require.Equal(t, false, rs.Result()) +} diff --git a/pkg/ride/tuples.go b/pkg/ride/tuples.go index 5881bdf62..2a563cdca 100644 --- a/pkg/ride/tuples.go +++ b/pkg/ride/tuples.go @@ -57,6 +57,10 @@ func (a tuple2) eq(other rideType) bool { return a.el1.eq(o.el1) && a.el2.eq(o.el2) } +func (a tuple2) Serialize(serializer Serializer) error { + return serializer.Tuple(a.el1, a.el2) +} + type tuple3 struct { el1 rideType el2 rideType @@ -109,6 +113,10 @@ func (a tuple3) eq(other rideType) bool { return a.el1.eq(o.el1) && a.el2.eq(o.el2) && a.el3.eq(o.el3) } +func (a tuple3) Serialize(serializer Serializer) error { + return serializer.Tuple(a.el1, a.el2, a.el3) +} + type tuple4 struct { el1 rideType el2 rideType @@ -165,6 +173,10 @@ func (a tuple4) eq(other rideType) bool { return a.el1.eq(o.el1) && a.el2.eq(o.el2) && a.el3.eq(o.el3) && a.el4.eq(o.el4) } +func (a tuple4) Serialize(serializer Serializer) error { + return serializer.Tuple(a.el1, a.el2, a.el3, a.el4) +} + type tuple5 struct { el1 rideType el2 rideType @@ -225,6 +237,10 @@ func (a tuple5) eq(other rideType) bool { return a.el1.eq(o.el1) && a.el2.eq(o.el2) && a.el3.eq(o.el3) && a.el4.eq(o.el4) && a.el5.eq(o.el5) } +func (a tuple5) Serialize(serializer Serializer) error { + return serializer.Tuple(a.el1, a.el2, a.el3, a.el4, a.el5) +} + type tuple6 struct { el1 rideType el2 rideType @@ -289,6 +305,10 @@ func (a tuple6) eq(other rideType) bool { return a.el1.eq(o.el1) && a.el2.eq(o.el2) && a.el3.eq(o.el3) && a.el4.eq(o.el4) && a.el5.eq(o.el5) && a.el6.eq(o.el6) } +func (a tuple6) Serialize(serializer Serializer) error { + return serializer.Tuple(a.el1, a.el2, a.el3, a.el4, a.el5, a.el6) +} + type tuple7 struct { el1 rideType el2 rideType @@ -357,6 +377,10 @@ func (a tuple7) eq(other rideType) bool { return a.el1.eq(o.el1) && a.el2.eq(o.el2) && a.el3.eq(o.el3) && a.el4.eq(o.el4) && a.el5.eq(o.el5) && a.el6.eq(o.el6) && a.el7.eq(o.el7) } +func (a tuple7) Serialize(serializer Serializer) error { + return serializer.Tuple(a.el1, a.el2, a.el3, a.el4, a.el5, a.el6, a.el7) +} + type tuple8 struct { el1 rideType el2 rideType @@ -429,6 +453,10 @@ func (a tuple8) eq(other rideType) bool { return a.el1.eq(o.el1) && a.el2.eq(o.el2) && a.el3.eq(o.el3) && a.el4.eq(o.el4) && a.el5.eq(o.el5) && a.el6.eq(o.el6) && a.el7.eq(o.el7) && a.el8.eq(o.el8) } +func (a tuple8) Serialize(serializer Serializer) error { + return serializer.Tuple(a.el1, a.el2, a.el3, a.el4, a.el5, a.el6, a.el7, a.el8) +} + type tuple9 struct { el1 rideType el2 rideType @@ -505,6 +533,10 @@ func (a tuple9) eq(other rideType) bool { return a.el1.eq(o.el1) && a.el2.eq(o.el2) && a.el3.eq(o.el3) && a.el4.eq(o.el4) && a.el5.eq(o.el5) && a.el6.eq(o.el6) && a.el7.eq(o.el7) && a.el8.eq(o.el8) && a.el9.eq(o.el9) } +func (a tuple9) Serialize(serializer Serializer) error { + return serializer.Tuple(a.el1, a.el2, a.el3, a.el4, a.el5, a.el6, a.el7, a.el8, a.el9) +} + type tuple10 struct { el1 rideType el2 rideType @@ -585,6 +617,10 @@ func (a tuple10) eq(other rideType) bool { return a.el1.eq(o.el1) && a.el2.eq(o.el2) && a.el3.eq(o.el3) && a.el4.eq(o.el4) && a.el5.eq(o.el5) && a.el6.eq(o.el6) && a.el7.eq(o.el7) && a.el8.eq(o.el8) && a.el9.eq(o.el9) && a.el10.eq(o.el10) } +func (a tuple10) Serialize(serializer Serializer) error { + return serializer.Tuple(a.el1, a.el2, a.el3, a.el4, a.el5, a.el6, a.el7, a.el8, a.el9, a.el10) +} + type tuple11 struct { el1 rideType el2 rideType @@ -669,6 +705,10 @@ func (a tuple11) eq(other rideType) bool { return a.el1.eq(o.el1) && a.el2.eq(o.el2) && a.el3.eq(o.el3) && a.el4.eq(o.el4) && a.el5.eq(o.el5) && a.el6.eq(o.el6) && a.el7.eq(o.el7) && a.el8.eq(o.el8) && a.el9.eq(o.el9) && a.el10.eq(o.el10) && a.el11.eq(o.el11) } +func (a tuple11) Serialize(serializer Serializer) error { + return serializer.Tuple(a.el1, a.el2, a.el3, a.el4, a.el5, a.el6, a.el7, a.el8, a.el9, a.el10, a.el11) +} + type tuple12 struct { el1 rideType el2 rideType @@ -757,6 +797,10 @@ func (a tuple12) eq(other rideType) bool { return a.el1.eq(o.el1) && a.el2.eq(o.el2) && a.el3.eq(o.el3) && a.el4.eq(o.el4) && a.el5.eq(o.el5) && a.el6.eq(o.el6) && a.el7.eq(o.el7) && a.el8.eq(o.el8) && a.el9.eq(o.el9) && a.el10.eq(o.el10) && a.el11.eq(o.el11) && a.el12.eq(o.el12) } +func (a tuple12) Serialize(serializer Serializer) error { + return serializer.Tuple(a.el1, a.el2, a.el3, a.el4, a.el5, a.el6, a.el7, a.el8, a.el9, a.el10, a.el11, a.el12) +} + type tuple13 struct { el1 rideType el2 rideType @@ -849,6 +893,10 @@ func (a tuple13) eq(other rideType) bool { return a.el1.eq(o.el1) && a.el2.eq(o.el2) && a.el3.eq(o.el3) && a.el4.eq(o.el4) && a.el5.eq(o.el5) && a.el6.eq(o.el6) && a.el7.eq(o.el7) && a.el8.eq(o.el8) && a.el9.eq(o.el9) && a.el10.eq(o.el10) && a.el11.eq(o.el11) && a.el12.eq(o.el12) && a.el13.eq(o.el13) } +func (a tuple13) Serialize(serializer Serializer) error { + return serializer.Tuple(a.el1, a.el2, a.el3, a.el4, a.el5, a.el6, a.el7, a.el8, a.el9, a.el10, a.el11, a.el12, a.el13) +} + type tuple14 struct { el1 rideType el2 rideType @@ -945,6 +993,10 @@ func (a tuple14) eq(other rideType) bool { return a.el1.eq(o.el1) && a.el2.eq(o.el2) && a.el3.eq(o.el3) && a.el4.eq(o.el4) && a.el5.eq(o.el5) && a.el6.eq(o.el6) && a.el7.eq(o.el7) && a.el8.eq(o.el8) && a.el9.eq(o.el9) && a.el10.eq(o.el10) && a.el11.eq(o.el11) && a.el12.eq(o.el12) && a.el13.eq(o.el13) && a.el14.eq(o.el14) } +func (a tuple14) Serialize(serializer Serializer) error { + return serializer.Tuple(a.el1, a.el2, a.el3, a.el4, a.el5, a.el6, a.el7, a.el8, a.el9, a.el10, a.el11, a.el12, a.el13, a.el14) +} + type tuple15 struct { el1 rideType el2 rideType @@ -1045,6 +1097,10 @@ func (a tuple15) eq(other rideType) bool { return a.el1.eq(o.el1) && a.el2.eq(o.el2) && a.el3.eq(o.el3) && a.el4.eq(o.el4) && a.el5.eq(o.el5) && a.el6.eq(o.el6) && a.el7.eq(o.el7) && a.el8.eq(o.el8) && a.el9.eq(o.el9) && a.el10.eq(o.el10) && a.el11.eq(o.el11) && a.el12.eq(o.el12) && a.el13.eq(o.el13) && a.el14.eq(o.el14) && a.el15.eq(o.el15) } +func (a tuple15) Serialize(serializer Serializer) error { + return serializer.Tuple(a.el1, a.el2, a.el3, a.el4, a.el5, a.el6, a.el7, a.el8, a.el9, a.el10, a.el11, a.el12, a.el13, a.el14, a.el15) +} + type tuple16 struct { el1 rideType el2 rideType @@ -1149,6 +1205,10 @@ func (a tuple16) eq(other rideType) bool { return a.el1.eq(o.el1) && a.el2.eq(o.el2) && a.el3.eq(o.el3) && a.el4.eq(o.el4) && a.el5.eq(o.el5) && a.el6.eq(o.el6) && a.el7.eq(o.el7) && a.el8.eq(o.el8) && a.el9.eq(o.el9) && a.el10.eq(o.el10) && a.el11.eq(o.el11) && a.el12.eq(o.el12) && a.el13.eq(o.el13) && a.el14.eq(o.el14) && a.el15.eq(o.el15) && a.el16.eq(o.el16) } +func (a tuple16) Serialize(serializer Serializer) error { + return serializer.Tuple(a.el1, a.el2, a.el3, a.el4, a.el5, a.el6, a.el7, a.el8, a.el9, a.el10, a.el11, a.el12, a.el13, a.el14, a.el15, a.el16) +} + type tuple17 struct { el1 rideType el2 rideType @@ -1257,6 +1317,10 @@ func (a tuple17) eq(other rideType) bool { return a.el1.eq(o.el1) && a.el2.eq(o.el2) && a.el3.eq(o.el3) && a.el4.eq(o.el4) && a.el5.eq(o.el5) && a.el6.eq(o.el6) && a.el7.eq(o.el7) && a.el8.eq(o.el8) && a.el9.eq(o.el9) && a.el10.eq(o.el10) && a.el11.eq(o.el11) && a.el12.eq(o.el12) && a.el13.eq(o.el13) && a.el14.eq(o.el14) && a.el15.eq(o.el15) && a.el16.eq(o.el16) && a.el17.eq(o.el17) } +func (a tuple17) Serialize(serializer Serializer) error { + return serializer.Tuple(a.el1, a.el2, a.el3, a.el4, a.el5, a.el6, a.el7, a.el8, a.el9, a.el10, a.el11, a.el12, a.el13, a.el14, a.el15, a.el16, a.el17) +} + type tuple18 struct { el1 rideType el2 rideType @@ -1369,6 +1433,10 @@ func (a tuple18) eq(other rideType) bool { return a.el1.eq(o.el1) && a.el2.eq(o.el2) && a.el3.eq(o.el3) && a.el4.eq(o.el4) && a.el5.eq(o.el5) && a.el6.eq(o.el6) && a.el7.eq(o.el7) && a.el8.eq(o.el8) && a.el9.eq(o.el9) && a.el10.eq(o.el10) && a.el11.eq(o.el11) && a.el12.eq(o.el12) && a.el13.eq(o.el13) && a.el14.eq(o.el14) && a.el15.eq(o.el15) && a.el16.eq(o.el16) && a.el17.eq(o.el17) && a.el18.eq(o.el18) } +func (a tuple18) Serialize(serializer Serializer) error { + return serializer.Tuple(a.el1, a.el2, a.el3, a.el4, a.el5, a.el6, a.el7, a.el8, a.el9, a.el10, a.el11, a.el12, a.el13, a.el14, a.el15, a.el16, a.el17, a.el18) +} + type tuple19 struct { el1 rideType el2 rideType @@ -1485,6 +1553,10 @@ func (a tuple19) eq(other rideType) bool { return a.el1.eq(o.el1) && a.el2.eq(o.el2) && a.el3.eq(o.el3) && a.el4.eq(o.el4) && a.el5.eq(o.el5) && a.el6.eq(o.el6) && a.el7.eq(o.el7) && a.el8.eq(o.el8) && a.el9.eq(o.el9) && a.el10.eq(o.el10) && a.el11.eq(o.el11) && a.el12.eq(o.el12) && a.el13.eq(o.el13) && a.el14.eq(o.el14) && a.el15.eq(o.el15) && a.el16.eq(o.el16) && a.el17.eq(o.el17) && a.el18.eq(o.el18) && a.el19.eq(o.el19) } +func (a tuple19) Serialize(serializer Serializer) error { + return serializer.Tuple(a.el1, a.el2, a.el3, a.el4, a.el5, a.el6, a.el7, a.el8, a.el9, a.el10, a.el11, a.el12, a.el13, a.el14, a.el15, a.el16, a.el17, a.el18, a.el19) +} + type tuple20 struct { el1 rideType el2 rideType @@ -1605,6 +1677,10 @@ func (a tuple20) eq(other rideType) bool { return a.el1.eq(o.el1) && a.el2.eq(o.el2) && a.el3.eq(o.el3) && a.el4.eq(o.el4) && a.el5.eq(o.el5) && a.el6.eq(o.el6) && a.el7.eq(o.el7) && a.el8.eq(o.el8) && a.el9.eq(o.el9) && a.el10.eq(o.el10) && a.el11.eq(o.el11) && a.el12.eq(o.el12) && a.el13.eq(o.el13) && a.el14.eq(o.el14) && a.el15.eq(o.el15) && a.el16.eq(o.el16) && a.el17.eq(o.el17) && a.el18.eq(o.el18) && a.el19.eq(o.el19) && a.el20.eq(o.el20) } +func (a tuple20) Serialize(serializer Serializer) error { + return serializer.Tuple(a.el1, a.el2, a.el3, a.el4, a.el5, a.el6, a.el7, a.el8, a.el9, a.el10, a.el11, a.el12, a.el13, a.el14, a.el15, a.el16, a.el17, a.el18, a.el19, a.el20) +} + type tuple21 struct { el1 rideType el2 rideType @@ -1729,6 +1805,10 @@ func (a tuple21) eq(other rideType) bool { return a.el1.eq(o.el1) && a.el2.eq(o.el2) && a.el3.eq(o.el3) && a.el4.eq(o.el4) && a.el5.eq(o.el5) && a.el6.eq(o.el6) && a.el7.eq(o.el7) && a.el8.eq(o.el8) && a.el9.eq(o.el9) && a.el10.eq(o.el10) && a.el11.eq(o.el11) && a.el12.eq(o.el12) && a.el13.eq(o.el13) && a.el14.eq(o.el14) && a.el15.eq(o.el15) && a.el16.eq(o.el16) && a.el17.eq(o.el17) && a.el18.eq(o.el18) && a.el19.eq(o.el19) && a.el20.eq(o.el20) && a.el21.eq(o.el21) } +func (a tuple21) Serialize(serializer Serializer) error { + return serializer.Tuple(a.el1, a.el2, a.el3, a.el4, a.el5, a.el6, a.el7, a.el8, a.el9, a.el10, a.el11, a.el12, a.el13, a.el14, a.el15, a.el16, a.el17, a.el18, a.el19, a.el20, a.el21) +} + type tuple22 struct { el1 rideType el2 rideType @@ -1856,3 +1936,7 @@ func (a tuple22) eq(other rideType) bool { } return a.el1.eq(o.el1) && a.el2.eq(o.el2) && a.el3.eq(o.el3) && a.el4.eq(o.el4) && a.el5.eq(o.el5) && a.el6.eq(o.el6) && a.el7.eq(o.el7) && a.el8.eq(o.el8) && a.el9.eq(o.el9) && a.el10.eq(o.el10) && a.el11.eq(o.el11) && a.el12.eq(o.el12) && a.el13.eq(o.el13) && a.el14.eq(o.el14) && a.el15.eq(o.el15) && a.el16.eq(o.el16) && a.el17.eq(o.el17) && a.el18.eq(o.el18) && a.el19.eq(o.el19) && a.el20.eq(o.el20) && a.el21.eq(o.el21) && a.el22.eq(o.el22) } + +func (a tuple22) Serialize(serializer Serializer) error { + return serializer.Tuple(a.el1, a.el2, a.el3, a.el4, a.el5, a.el6, a.el7, a.el8, a.el9, a.el10, a.el11, a.el12, a.el13, a.el14, a.el15, a.el16, a.el17, a.el18, a.el19, a.el20, a.el21, a.el22) +} diff --git a/pkg/ride/vm.go b/pkg/ride/vm.go index 1cf82c282..567f163f6 100644 --- a/pkg/ride/vm.go +++ b/pkg/ride/vm.go @@ -6,102 +6,82 @@ import ( "github.com/pkg/errors" ) -type frame struct { - function bool - back int - args []rideType -} - -func newExpressionFrame(pos int) frame { - return frame{ - back: pos, - } -} - -func newFunctionFrame(pos int, args []rideType) frame { - return frame{ - function: true, - back: pos, - args: args, - } -} +const limitOperations = 200000 type vm struct { - env RideEnvironment - code []byte - ip int - constants []rideType - functions func(int) rideFunction - globals func(int) rideConstructor - stack []rideType - calls []frame - functionName func(int) string + env RideEnvironment + code []byte + ip int + stack []rideType + jmps []int + ref map[uint16]point + calls []callLog + numOperations int + libVersion int } -func (m *vm) run() (RideResult, error) { - if m.stack != nil { - m.stack = m.stack[0:0] - } - if m.calls != nil { - m.calls = m.calls[0:0] - } - m.ip = 0 +func (m *vm) run() (rideType, error) { for m.ip < len(m.code) { + if m.numOperations >= limitOperations { + return nil, errors.New("limit operations exceed") + } + m.numOperations++ + op := m.code[m.ip] m.ip++ switch op { - case OpPush: - m.push(m.constant()) case OpPop: _, err := m.pop() if err != nil { - return nil, errors.Wrap(err, "failed to pop value") + return nil, err } - case OpTrue: - m.push(rideBoolean(true)) - case OpFalse: - m.push(rideBoolean(false)) case OpJump: pos := m.arg16() + m.jmps = append(m.jmps, m.ip) m.ip = pos + case OpJumpIfFalse: - pos := m.arg16() - v, ok := m.current().(rideBoolean) + posTrue := m.arg16() + posFalse := m.arg16() + posNext := m.arg16() + m.jmps = append(m.jmps, posNext) + + val, err := m.pop() + if err != nil { + return nil, errors.Wrap(err, "OpJumpIfFalse") + } + v, ok := val.(rideBoolean) if !ok { return nil, errors.Errorf("not a boolean value '%v' of type '%T'", m.current(), m.current()) } - if !v { - m.ip = pos + if v { + m.ip = posTrue + } else { + m.ip = posFalse } case OpProperty: - obj, err := m.pop() + prop, err := m.pop() if err != nil { - return nil, errors.Wrap(err, "failed to get object") + return nil, err //errors.Wrap(err, "no ref %d", n) } - prop := m.constant() p, ok := prop.(rideString) if !ok { - return nil, errors.Errorf("invalid property name type '%s'", prop.instanceOf()) + return nil, errors.Errorf("invalid property type '%T'", prop) + } + obj, err := m.pop() + if err != nil { + return nil, errors.Wrap(err, "failed to get object") } v, err := obj.get(string(p)) if err != nil { - return nil, err + return nil, errors.Wrap(err, "vm OpProperty") } m.push(v) case OpCall: pos := m.arg16() - cnt := m.arg16() - in := make([]rideType, cnt) - for i := cnt - 1; i >= 0; i-- { - v, err := m.pop() - if err != nil { - return nil, errors.Wrapf(err, "failed to call function at position %d", pos) - } - in[i] = v - } - frame := newFunctionFrame(m.ip, in) // Creating new function frame with return position - m.calls = append(m.calls, frame) - m.ip = pos // Continue to function + m.jmps = append(m.jmps, m.ip) + m.ip = pos + case OpExternalCall: // Before calling external function all parameters must be evaluated and placed on stack id := m.arg16() @@ -110,71 +90,125 @@ func (m *vm) run() (RideResult, error) { for i := cnt - 1; i >= 0; i-- { v, err := m.pop() if err != nil { - return nil, errors.Wrapf(err, "failed to call external function '%s'", m.functionName(id)) + return nil, errors.Wrap(err, "failed to call external function") } in[i] = v } - fn := m.functions(id) + functions, err := selectFunctions(m.libVersion) + if err != nil { + return nil, err + } + provider, err := selectFunctionNameProvider(m.libVersion) + if err != nil { + return nil, err + } + fn := functions(id) if fn == nil { - return nil, errors.Errorf("external function '%s' not implemented", m.functionName(id)) + return nil, errors.Errorf("external function '%s' not implemented", provider(id)) } res, err := fn(m.env, in...) + m.calls = append(m.calls, callLog{ + name: provider(id), + args: in, + result: res, + }) if err != nil { - return nil, err + return nil, errors.Wrapf(err, "iteration %d", m.numOperations) } - m.push(res) - case OpLoad: // Evaluate expression behind a LET declaration - pos := m.arg16() - frame := newExpressionFrame(m.ip) // Creating new function frame with return position - m.calls = append(m.calls, frame) - m.ip = pos // Continue to expression - case OpLoadLocal: - n := m.arg16() - for i := len(m.calls) - 1; i >= 0; i-- { - + if isThrow(res) { + return res, nil } - l := len(m.calls) + m.push(res) + case OpReturn: + l := len(m.jmps) if l == 0 { - return nil, errors.New("failed to load argument on stack") + if len(m.stack) > 0 { + v, err := m.pop() + if err != nil { + return nil, errors.Wrap(err, "failed to get result value") + } + return v, nil + } + return nil, errors.New("no result after script execution") } - frame := m.calls[l-1] - if l := len(frame.args); l < n+1 { - return nil, errors.New("invalid arguments count") + m.ip, m.jmps = m.jmps[l-1], m.jmps[:l-1] + + case OpSetArg: + from := m.uint16() + to := m.uint16() + // for debug purpose + x := m.ref[from] + _ = x + m.ref[to] = m.ref[from] + case OpCache: + refID := m.uint16() + if refID < 200 { + continue } - m.push(frame.args[n]) - case OpReturn: - l := len(m.calls) - var f frame - f, m.calls = m.calls[l-1], m.calls[:l-1] - m.ip = f.back - case OpHalt: - if len(m.stack) > 0 { - v, err := m.pop() + value, err := m.pop() + if err != nil { + return nil, errors.Wrap(err, "no value to cache") + } + m.push(value) + point := m.ref[refID] + point.value = value + m.ref[refID] = point + case OpClearCache: + refID := m.uint16() + point, ok := m.ref[refID] + if !ok { + return nil, errors.Errorf("OpClearCache: no ref with id %d", refID) + } + // Clear cache only if its not constant. + if !point.constant() { + point.value = nil + m.ref[refID] = point + } + + case OpRef: + refID := m.uint16() + switch { + case refID <= 100: + m.push(rideInt(refID)) + continue + case refID == 101: + m.push(rideBoolean(true)) + continue + case refID == 102: + m.push(rideBoolean(false)) + continue + } + point, ok := m.ref[refID] + if !ok { + return nil, errors.Errorf("reference %d not found", refID) + } + if point.value != nil { + m.push(point.value) + } else if point.fn != 0 { + fn := predefined.getn(int(point.fn)) + rs, err := fn(m.env) if err != nil { - return nil, errors.Wrap(err, "failed to get result value") + return nil, err } - switch tv := v.(type) { - case rideBoolean: - return ScriptResult{res: bool(tv)}, nil - default: - return nil, errors.Errorf("unexpected result value '%v' of type '%T'", v, v) + m.push(rs) + } else { + if m.ip == int(point.position)+3 { + return nil, errors.Errorf("infinity loop detected on iteration %d", m.numOperations) } + m.jmps = append(m.jmps, m.ip) + m.ip = int(point.position) } - return nil, errors.New("no result after script execution") - case OpGlobal: - id := m.arg16() - constructor := m.globals(id) - v := constructor(m.env) - m.push(v) + default: - return nil, errors.Errorf("unknown code %#x", op) + return nil, errors.Errorf("unknown code %#x, at iteration %d", op, m.numOperations) } } return nil, errors.New("broken code") } -func (m *vm) push(v rideType) { +func (m *vm) push(v rideType) constid { m.stack = append(m.stack, v) + return uint16(len(m.stack) - 1) } func (m *vm) pop() (rideType, error) { @@ -197,28 +231,9 @@ func (m *vm) arg16() int { return int(res) } -func (m *vm) constant() rideType { +func (m *vm) uint16() uint16 { //TODO: add check - return m.constants[m.arg16()] + res := binary.BigEndian.Uint16(m.code[m.ip : m.ip+2]) + m.ip += 2 + return res } - -//func (m *vm) scope() (*frame, int) { -// n := len(m.calls) - 1 -// if n < 0 { -// return nil, n -// } -// return &m.calls[n], n -//} - -//func (m *vm) resolve(name string) (int, error) { -// _ = name -// //TODO: implement -// return 0, errors.New("not implemented") -//} - -//func (m *vm) returnPosition() int { -// if l := len(m.calls); l > 0 { -// return m.calls[l-1].back -// } -// return len(m.code) -//} diff --git a/pkg/ride/vm_estimator.go b/pkg/ride/vm_estimator.go new file mode 100644 index 000000000..bd42f5b3a --- /dev/null +++ b/pkg/ride/vm_estimator.go @@ -0,0 +1,19 @@ +package ride + +type VmEstimator struct { + builtin map[string]int +} + +func NewVmEstimator(builtin map[string]int) *VmEstimator { + return &VmEstimator{ + builtin: builtin, + } +} + +func (a VmEstimator) Ref() int { + return 1 +} + +func (a VmEstimator) Builtin(n string) int { + return a.builtin[n] +} diff --git a/pkg/ride/vm_test.go b/pkg/ride/vm_test.go index 8ffd6ba27..f0849ce25 100644 --- a/pkg/ride/vm_test.go +++ b/pkg/ride/vm_test.go @@ -1,93 +1,17 @@ package ride import ( - "bytes" - "encoding/base64" "encoding/json" - "testing" "time" "github.com/mr-tron/base58" - "github.com/pkg/errors" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "github.com/wavesplatform/gowaves/pkg/crypto" "github.com/wavesplatform/gowaves/pkg/proto" - "github.com/wavesplatform/gowaves/pkg/types" + "github.com/wavesplatform/gowaves/pkg/util/byte_helpers" ) //go:generate moq -pkg ride -out types_moq_test.go ../types SmartState:MockSmartState -func TestExecution(t *testing.T) { - state := &MockSmartState{NewestTransactionByIDFunc: func(_ []byte) (proto.Transaction, error) { - return testTransferWithProofs(), nil - }} - env := &MockRideEnvironment{ - transactionFunc: testTransferObject, - stateFunc: func() types.SmartState { - return state - }, - schemeFunc: func() byte { - return 'T' - }, - } - for _, test := range []struct { - comment string - source string - env RideEnvironment - res bool - }{ - {`V1: true`, "AQa3b8tH", nil, true}, - {`V3: let x = 1; true`, "AwQAAAABeAAAAAAAAAAAAQbtAkXn", nil, true}, - {`V3: let x = "abc"; true`, "AwQAAAABeAIAAAADYWJjBrpUkE4=", nil, true}, - {`V1: let i = 1; let s = "string"; toString(i) == s`, "AQQAAAABaQAAAAAAAAAAAQQAAAABcwIAAAAGc3RyaW5nCQAAAAAAAAIJAAGkAAAAAQUAAAABaQUAAAABcwIsH74=", nil, false}, - {`V3: let i = 12345; let s = "12345"; toString(i) == s`, "AwQAAAABaQAAAAAAAAAwOQQAAAABcwIAAAAFMTIzNDUJAAAAAAAAAgkAAaQAAAABBQAAAAFpBQAAAAFz1B1iCw==", nil, true}, - {`V3: if (true) then {let r = true; r} else {let r = false; r}`, "AwMGBAAAAAFyBgUAAAABcgQAAAABcgcFAAAAAXJ/ok0E", nil, true}, - {`V3: if (false) then {let r = true; r} else {let r = false; r}`, "AwMHBAAAAAFyBgUAAAABcgQAAAABcgcFAAAAAXI+tfo1", nil, false}, - {`V3: func abs(i:Int) = if (i >= 0) then i else -i; abs(-10) == 10`, "AwoBAAAAA2FicwAAAAEAAAABaQMJAABnAAAAAgUAAAABaQAAAAAAAAAAAAUAAAABaQkBAAAAAS0AAAABBQAAAAFpCQAAAAAAAAIJAQAAAANhYnMAAAABAP/////////2AAAAAAAAAAAKmp8BWw==", nil, true}, - {`V3: let x = 1; func add(i: Int) = i + 1; add(x) == 2`, "AwQAAAABeAAAAAAAAAAAAQoBAAAAA2FkZAAAAAEAAAABaQkAAGQAAAACBQAAAAFpAAAAAAAAAAABCQAAAAAAAAIJAQAAAANhZGQAAAABBQAAAAF4AAAAAAAAAAACfr6U6w==", nil, true}, - {`V3: let b = base16'0000000000000001'; func add(b: ByteVector) = toInt(b) + 1; add(b) == 2`, "AwQAAAABYgEAAAAIAAAAAAAAAAEKAQAAAANhZGQAAAABAAAAAWIJAABkAAAAAgkABLEAAAABBQAAAAFiAAAAAAAAAAABCQAAAAAAAAIJAQAAAANhZGQAAAABBQAAAAFiAAAAAAAAAAACX00biA==", nil, true}, - {`V3: let b = base16'0000000000000001'; func add(v: ByteVector) = toInt(v) + 1; add(b) == 2`, "AwQAAAABYgEAAAAIAAAAAAAAAAEKAQAAAANhZGQAAAABAAAAAXYJAABkAAAAAgkABLEAAAABBQAAAAF2AAAAAAAAAAABCQAAAAAAAAIJAQAAAANhZGQAAAABBQAAAAFiAAAAAAAAAAACI7gYxg==", nil, true}, - {`V3: let b = base16'0000000000000001'; func add(v: ByteVector) = toInt(b) + 1; add(b) == 2`, "AwQAAAABYgEAAAAIAAAAAAAAAAEKAQAAAANhZGQAAAABAAAAAXYJAABkAAAAAgkABLEAAAABBQAAAAFiAAAAAAAAAAABCQAAAAAAAAIJAQAAAANhZGQAAAABBQAAAAFiAAAAAAAAAAAChRvwnQ==", nil, true}, - {`V3: let data = base64'AAAAAAABhqAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWyt9GyysOW84u/u5V5Ah/SzLfef4c28UqXxowxFZS4SLiC6+XBh8D7aJDXyTTjpkPPED06ZPOzUE23V6VYCsLw=='; func getStock(data:ByteVector) = toInt(take(drop(data, 8), 8)); getStock(data) == 1`, `AwQAAAAEZGF0YQEAAABwAAAAAAABhqAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWyt9GyysOW84u/u5V5Ah/SzLfef4c28UqXxowxFZS4SLiC6+XBh8D7aJDXyTTjpkPPED06ZPOzUE23V6VYCsLwoBAAAACGdldFN0b2NrAAAAAQAAAARkYXRhCQAEsQAAAAEJAADJAAAAAgkAAMoAAAACBQAAAARkYXRhAAAAAAAAAAAIAAAAAAAAAAAICQAAAAAAAAIJAQAAAAhnZXRTdG9jawAAAAEFAAAABGRhdGEAAAAAAAAAAAFCtabi`, nil, true}, - {`V3: let ref = 999; func g(a: Int) = ref; func f(ref: Int) = g(ref); f(1) == 999`, "AwQAAAADcmVmAAAAAAAAAAPnCgEAAAABZwAAAAEAAAABYQUAAAADcmVmCgEAAAABZgAAAAEAAAADcmVmCQEAAAABZwAAAAEFAAAAA3JlZgkAAAAAAAACCQEAAAABZgAAAAEAAAAAAAAAAAEAAAAAAAAAA+fjknmW", nil, true}, - {`let x = 5; 6 > 4`, `AQQAAAABeAAAAAAAAAAABQkAAGYAAAACAAAAAAAAAAAGAAAAAAAAAAAEYSW6XA==`, nil, true}, - {`let x = 5; 6 > x`, `AQQAAAABeAAAAAAAAAAABQkAAGYAAAACAAAAAAAAAAAGBQAAAAF4Gh24hw==`, nil, true}, - {`let x = 5; 6 >= x`, `AQQAAAABeAAAAAAAAAAABQkAAGcAAAACAAAAAAAAAAAGBQAAAAF4jlxXHA==`, nil, true}, - {`false`, `AQfeYll6`, nil, false}, - {`let x = throw(); true`, `AQQAAAABeAkBAAAABXRocm93AAAAAAa7bgf4`, nil, true}, - {`let x = throw(); true || x`, `AQQAAAABeAkBAAAABXRocm93AAAAAAMGBgUAAAABeKRnLds=`, nil, true}, - {`tx.id == base58''`, `AQkAAAAAAAACCAUAAAACdHgAAAACaWQBAAAAAJBtD70=`, env, false}, - {`tx.id == base58'H5C8bRzbUTMePSDVVxjiNKDUwk6CKzfZGTP2Rs7aCjsV'`, `BAkAAAAAAAACCAUAAAACdHgAAAACaWQBAAAAIO7N5luRDUgN1SJ4kFmy/Ni8U2H6k7bpszok5tlLlRVgHwSHyg==`, env, true}, - {`let x = tx.id == base58'a';true`, `AQQAAAABeAkAAAAAAAACCAUAAAACdHgAAAACaWQBAAAAASEGjR0kcA==`, env, true}, - {`tx.proofs[0] != base58'' && tx.proofs[1] == base58''`, `BAMJAQAAAAIhPQAAAAIJAAGRAAAAAggFAAAAAnR4AAAABnByb29mcwAAAAAAAAAAAAEAAAAACQAAAAAAAAIJAAGRAAAAAggFAAAAAnR4AAAABnByb29mcwAAAAAAAAAAAQEAAAAAB106gzM=`, env, true}, - {`match tx {case t : TransferTransaction | MassTransferTransaction | ExchangeTransaction => true; case _ => false}`, `AQQAAAAHJG1hdGNoMAUAAAACdHgDAwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAABNFeGNoYW5nZVRyYW5zYWN0aW9uBgMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAXTWFzc1RyYW5zZmVyVHJhbnNhY3Rpb24GCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAE1RyYW5zZmVyVHJhbnNhY3Rpb24EAAAAAXQFAAAAByRtYXRjaDAGB6Ilvok=`, env, true}, - {`V2: match transactionById(tx.id) {case t: Unit => false case _ => true}`, `AgQAAAAHJG1hdGNoMAkAA+gAAAABCAUAAAACdHgAAAACaWQDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAABFVuaXQEAAAAAXQFAAAAByRtYXRjaDAHBp9TFcQ=`, env, true}, - {`Up() == UP`, `AwkAAAAAAAACCQEAAAACVXAAAAAABQAAAAJVUPGUxeg=`, nil, true}, - {`HalfUp() == HALFUP`, `AwkAAAAAAAACCQEAAAAGSGFsZlVwAAAAAAUAAAAGSEFMRlVQbUfpTQ==`, nil, true}, - {`let a0 = NoAlg() == NOALG; let a1 = Md5() == MD5; let a2 = Sha1() == SHA1; let a3 = Sha224() == SHA224; let a4 = Sha256() == SHA256; let a5 = Sha384() == SHA384; let a6 = Sha512() == SHA512; let a7 = Sha3224() == SHA3224; let a8 = Sha3256() == SHA3256; let a9 = Sha3384() == SHA3384; let a10 = Sha3512() == SHA3512; a0 && a1 && a2 && a3 && a4 && a5 && a6 && a7 && a8 && a9 && a10`, `AwQAAAACYTAJAAAAAAAAAgkBAAAABU5vQWxnAAAAAAUAAAAFTk9BTEcEAAAAAmExCQAAAAAAAAIJAQAAAANNZDUAAAAABQAAAANNRDUEAAAAAmEyCQAAAAAAAAIJAQAAAARTaGExAAAAAAUAAAAEU0hBMQQAAAACYTMJAAAAAAAAAgkBAAAABlNoYTIyNAAAAAAFAAAABlNIQTIyNAQAAAACYTQJAAAAAAAAAgkBAAAABlNoYTI1NgAAAAAFAAAABlNIQTI1NgQAAAACYTUJAAAAAAAAAgkBAAAABlNoYTM4NAAAAAAFAAAABlNIQTM4NAQAAAACYTYJAAAAAAAAAgkBAAAABlNoYTUxMgAAAAAFAAAABlNIQTUxMgQAAAACYTcJAAAAAAAAAgkBAAAAB1NoYTMyMjQAAAAABQAAAAdTSEEzMjI0BAAAAAJhOAkAAAAAAAACCQEAAAAHU2hhMzI1NgAAAAAFAAAAB1NIQTMyNTYEAAAAAmE5CQAAAAAAAAIJAQAAAAdTaGEzMzg0AAAAAAUAAAAHU0hBMzM4NAQAAAADYTEwCQAAAAAAAAIJAQAAAAdTaGEzNTEyAAAAAAUAAAAHU0hBMzUxMgMDAwMDAwMDAwMFAAAAAmEwBQAAAAJhMQcFAAAAAmEyBwUAAAACYTMHBQAAAAJhNAcFAAAAAmE1BwUAAAACYTYHBQAAAAJhNwcFAAAAAmE4BwUAAAACYTkHBQAAAANhMTAHRc/wAA==`, nil, true}, - {`Unit() == unit`, `AwkAAAAAAAACCQEAAAAEVW5pdAAAAAAFAAAABHVuaXTstg1G`, nil, true}, - } { - src, err := base64.StdEncoding.DecodeString(test.source) - require.NoError(t, err, test.comment) - - tree, err := Parse(src) - require.NoError(t, err, test.comment) - assert.NotNil(t, tree, test.comment) - - script, err := Compile(tree) - require.NoError(t, err, test.comment) - assert.NotNil(t, script, test.comment) - - res, err := script.Run(test.env) - require.NoError(t, err, test.comment) - assert.NotNil(t, res, test.comment) - r, ok := res.(ScriptResult) - assert.True(t, ok, test.comment) - assert.Equal(t, test.res, r.Result(), test.comment) - } -} - func newTransferTransaction() *proto.TransferWithProofs { js := `{"type":4,"version":2,"id":"CqjGMbrd5bFmLAv2mUSdphEJSgVWkWa6ZtcMkKmgH2ax","proofs":["5W7hjPpgmmhxevCt4A7y9F8oNJ4V9w2g8jhQgx2qGmBTNsP1p1MpQeKF3cvZULwJ7vQthZfSx2BhL6TWkHSVLzvq"],"senderPublicKey":"14ovLL9a6xbBfftyxGNLKMdbnzGgnaFQjmgUJGdho6nY","assetId":null,"feeAssetId":null,"timestamp":1544715621,"amount":15,"fee":10000,"recipient":"3P2USE3iYK5w7jNahAUHTytNbVRccGZwQH3"}` tv2 := &proto.TransferWithProofs{} @@ -126,309 +50,6 @@ func newDataTransaction() *proto.DataWithProofs { return tx } -func TestFunctions(t *testing.T) { - t.SkipNow() - d, err := crypto.NewDigestFromBase58("BXBUNddxTGTQc3G4qHYn5E67SBwMj18zLncUr871iuRD") - transfer := newTransferTransaction() - exchange := newExchangeTransaction() - data := newDataTransaction() - require.NoError(t, err) - env := &MockRideEnvironment{ - checkMessageLengthFunc: v3check, - schemeFunc: func() byte { - return 'W' - }, - heightFunc: func() rideInt { - return 5 - }, - transactionFunc: func() rideObject { - obj, err := transferWithProofsToObject('W', transfer) - if err != nil { - panic(err) - } - return obj - }, - stateFunc: func() types.SmartState { - return &MockSmartState{ - RetrieveNewestIntegerEntryFunc: func(account proto.Recipient, key string) (*proto.IntegerDataEntry, error) { - if key == "integer" { - return &proto.IntegerDataEntry{Key: "integer", Value: 100500}, nil - } - return nil, errors.New("not found") - }, - RetrieveNewestBooleanEntryFunc: func(account proto.Recipient, key string) (*proto.BooleanDataEntry, error) { - if key == "boolean" { - return &proto.BooleanDataEntry{Key: "boolean", Value: true}, nil - } - return nil, errors.New("not found") - }, - RetrieveNewestBinaryEntryFunc: func(account proto.Recipient, key string) (*proto.BinaryDataEntry, error) { - if key == "binary" { - return &proto.BinaryDataEntry{Key: "binary", Value: []byte("hello")}, nil - } - return nil, errors.New("not found") - }, - RetrieveNewestStringEntryFunc: func(account proto.Recipient, key string) (*proto.StringDataEntry, error) { - if key == "string" { - return &proto.StringDataEntry{Key: "string", Value: "world"}, nil - } - return nil, errors.New("not found") - }, - NewestAccountBalanceFunc: func(account proto.Recipient, asset []byte) (uint64, error) { - if len(asset) == 0 { - return 5, nil - } else { - if bytes.Equal(asset, d.Bytes()) { - return 5, nil - } - return 0, nil - } - }, - NewestTransactionByIDFunc: func(id []byte) (proto.Transaction, error) { - return transfer, nil - }, - NewestTransactionHeightByIDFunc: func(_ []byte) (uint64, error) { - return 0, proto.ErrNotFound - }, - IsNotFoundFunc: func(err error) bool { - return true - }, - } - }, - } - _ /*envWithDataTX :*/ = &MockRideEnvironment{ - transactionFunc: func() rideObject { - obj, err := dataWithProofsToObject('W', data) - if err != nil { - panic(err) - } - return obj - }, - } - envWithExchangeTX := &MockRideEnvironment{ - transactionFunc: func() rideObject { - obj, err := exchangeWithProofsToObject('W', exchange) - if err != nil { - panic(err) - } - return obj - }, - } - for _, test := range []struct { - name string - text string - script string - env RideEnvironment - result bool - error bool - }{ - //{`parseIntValue`, `parseInt("12345") == 12345`, `AwkAAAAAAAACCQAEtgAAAAECAAAABTEyMzQ1AAAAAAAAADA57cmovA==`, nil, true, false}, - //{`value`, `let c = if true then 1 else Unit(); value(c) == 1`, `AwQAAAABYwMGAAAAAAAAAAABCQEAAAAEVW5pdAAAAAAJAAAAAAAAAgkBAAAABXZhbHVlAAAAAQUAAAABYwAAAAAAAAAAARfpQ5M=`, nil, true, false}, - //{`valueOrErrorMessage`, `let c = if true then 1 else Unit(); valueOrErrorMessage(c, "ALARM!!!") == 1`, `AwQAAAABYwMGAAAAAAAAAAABCQEAAAAEVW5pdAAAAAAJAAAAAAAAAgkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACBQAAAAFjAgAAAAhBTEFSTSEhIQAAAAAAAAAAAa5tVyw=`, nil, true, false}, - //{`addressFromString`, `addressFromString("12345") == unit`, `AwkAAAAAAAACCQEAAAARYWRkcmVzc0Zyb21TdHJpbmcAAAABAgAAAAUxMjM0NQUAAAAEdW5pdJEPLPE=`, env, true, false}, - //{`addressFromString`, `addressFromString("3P9DEDP5VbyXQyKtXDUt2crRPn5B7gs6ujc") == Address(base58'3P9DEDP5VbyXQyKtXDUt2crRPn5B7gs6ujc')`, `AwkAAAAAAAACCQEAAAARYWRkcmVzc0Zyb21TdHJpbmcAAAABAgAAACMzUDlERURQNVZieVhReUt0WERVdDJjclJQbjVCN2dzNnVqYwkBAAAAB0FkZHJlc3MAAAABAQAAABoBV0/fzRv7GRFL0qw2njIBPHDG0DpGJ4ecv6EI6ng=`, env, true, false}, - //{`addressFromStringValue`, `addressFromStringValue("3P9DEDP5VbyXQyKtXDUt2crRPn5B7gs6ujc") == Address(base58'3P9DEDP5VbyXQyKtXDUt2crRPn5B7gs6ujc')`, `AwkAAAAAAAACCQEAAAAcQGV4dHJVc2VyKGFkZHJlc3NGcm9tU3RyaW5nKQAAAAECAAAAIzNQOURFRFA1VmJ5WFF5S3RYRFV0MmNyUlBuNUI3Z3M2dWpjCQEAAAAHQWRkcmVzcwAAAAEBAAAAGgFXT9/NG/sZEUvSrDaeMgE8cMbQOkYnh5y/56rYHQ==`, env, true, false}, - //{`getIntegerFromState`, `let a = addressFromStringValue("3P2USE3iYK5w7jNahAUHTytNbVRccGZwQH3"); getInteger(a, "integer") == 100500`, `AwQAAAABYQkBAAAAHEBleHRyVXNlcihhZGRyZXNzRnJvbVN0cmluZykAAAABAgAAACMzUDJVU0UzaVlLNXc3ak5haEFVSFR5dE5iVlJjY0dad1FIMwkAAAAAAAACCQAEGgAAAAIFAAAAAWECAAAAB2ludGVnZXIAAAAAAAABiJTtgrwb`, env, true, false}, - //{`getIntegerValueFromState`, `let a = addressFromStringValue("3P2USE3iYK5w7jNahAUHTytNbVRccGZwQH3"); getIntegerValue(a, "integer") == 100500`, `AwQAAAABYQkBAAAAHEBleHRyVXNlcihhZGRyZXNzRnJvbVN0cmluZykAAAABAgAAACMzUDJVU0UzaVlLNXc3ak5haEFVSFR5dE5iVlJjY0dad1FIMwkAAAAAAAACCQEAAAARQGV4dHJOYXRpdmUoMTA1MCkAAAACBQAAAAFhAgAAAAdpbnRlZ2VyAAAAAAAAAYiUEnGoww==`, env, true, false}, - //{`getBooleanFromState`, `let a = addressFromStringValue("3P2USE3iYK5w7jNahAUHTytNbVRccGZwQH3"); getBoolean(a, "boolean") == true`, `AwQAAAABYQkBAAAAHEBleHRyVXNlcihhZGRyZXNzRnJvbVN0cmluZykAAAABAgAAACMzUDJVU0UzaVlLNXc3ak5haEFVSFR5dE5iVlJjY0dad1FIMwkAAAAAAAACCQAEGwAAAAIFAAAAAWECAAAAB2Jvb2xlYW4GQ1SwZw==`, env, true, false}, - //{`getBooleanValueFromState`, `let a = addressFromStringValue("3P2USE3iYK5w7jNahAUHTytNbVRccGZwQH3"); getBooleanValue(a, "boolean") == true`, `AwQAAAABYQkBAAAAHEBleHRyVXNlcihhZGRyZXNzRnJvbVN0cmluZykAAAABAgAAACMzUDJVU0UzaVlLNXc3ak5haEFVSFR5dE5iVlJjY0dad1FIMwkAAAAAAAACCQEAAAARQGV4dHJOYXRpdmUoMTA1MSkAAAACBQAAAAFhAgAAAAdib29sZWFuBiG4UlQ=`, env, true, false}, - //{`getBinaryFromState`, `let a = addressFromStringValue("3P2USE3iYK5w7jNahAUHTytNbVRccGZwQH3"); getBinary(a, "binary") == base16'68656c6c6f'`, `AwQAAAABYQkBAAAAHEBleHRyVXNlcihhZGRyZXNzRnJvbVN0cmluZykAAAABAgAAACMzUDJVU0UzaVlLNXc3ak5haEFVSFR5dE5iVlJjY0dad1FIMwkAAAAAAAACCQAEHAAAAAIFAAAAAWECAAAABmJpbmFyeQEAAAAFaGVsbG8AbKgo`, env, true, false}, - //{`getBinaryValueFromState`, `let a = addressFromStringValue("3P2USE3iYK5w7jNahAUHTytNbVRccGZwQH3"); getBinaryValue(a, "binary") == base16'68656c6c6f'`, `AwQAAAABYQkBAAAAHEBleHRyVXNlcihhZGRyZXNzRnJvbVN0cmluZykAAAABAgAAACMzUDJVU0UzaVlLNXc3ak5haEFVSFR5dE5iVlJjY0dad1FIMwkAAAAAAAACCQEAAAARQGV4dHJOYXRpdmUoMTA1MikAAAACBQAAAAFhAgAAAAZiaW5hcnkBAAAABWhlbGxvJ1b3yw==`, env, true, false}, - //{`getStringFromState`, `let a = addressFromStringValue("3P2USE3iYK5w7jNahAUHTytNbVRccGZwQH3"); getString(a, "string") == "world"`, `AwQAAAABYQkBAAAAHEBleHRyVXNlcihhZGRyZXNzRnJvbVN0cmluZykAAAABAgAAACMzUDJVU0UzaVlLNXc3ak5haEFVSFR5dE5iVlJjY0dad1FIMwkAAAAAAAACCQEAAAARQGV4dHJOYXRpdmUoMTA1MikAAAACBQAAAAFhAgAAAAZiaW5hcnkBAAAABWhlbGxvJ1b3yw==`, env, true, false}, - //{`getStringValueFromState`, `let a = addressFromStringValue("3P2USE3iYK5w7jNahAUHTytNbVRccGZwQH3"); getStringValue(a, "string") == "world"`, `AwQAAAABYQkBAAAAHEBleHRyVXNlcihhZGRyZXNzRnJvbVN0cmluZykAAAABAgAAACMzUDJVU0UzaVlLNXc3ak5haEFVSFR5dE5iVlJjY0dad1FIMwkAAAAAAAACCQAEHQAAAAIFAAAAAWECAAAABnN0cmluZwIAAAAFd29ybGSFdQnb`, env, true, false}, - //{`getIntegerFromArrayByKey`, `let d = [DataEntry("integer", 100500), DataEntry("boolean", true), DataEntry("binary", base16'68656c6c6f'), DataEntry("string", "world")]; getInteger(d, "integer") == 100500`, `AwQAAAABZAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHaW50ZWdlcgAAAAAAAAGIlAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHYm9vbGVhbgYJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABmJpbmFyeQEAAAAFaGVsbG8JAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABnN0cmluZwIAAAAFd29ybGQFAAAAA25pbAkAAAAAAAACCQAEEAAAAAIFAAAAAWQCAAAAB2ludGVnZXIAAAAAAAABiJSeStXa`, env, true, false}, - //{`getIntegerValueFromArrayByKey`, `let d = [DataEntry("integer",100500), DataEntry("boolean", true), DataEntry("binary", base16'68656c6c6f'), DataEntry("string", "world")]; getIntegerValue(d, "integer") == 100500`, `AwQAAAABZAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHaW50ZWdlcgAAAAAAAAGIlAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHYm9vbGVhbgYJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABmJpbmFyeQEAAAAFaGVsbG8JAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABnN0cmluZwIAAAAFd29ybGQFAAAAA25pbAkAAAAAAAACCQEAAAARQGV4dHJOYXRpdmUoMTA0MCkAAAACBQAAAAFkAgAAAAdpbnRlZ2VyAAAAAAAAAYiUmn7ujg==`, env, true, false}, - //{`getBooleanFromArrayByKey`, `let d = [DataEntry("integer",100500), DataEntry("boolean", true), DataEntry("binary", base16'68656c6c6f'), DataEntry("string", "world")]; getBoolean(d, "boolean") == true`, `AwQAAAABZAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHaW50ZWdlcgAAAAAAAAGIlAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHYm9vbGVhbgYJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABmJpbmFyeQEAAAAFaGVsbG8JAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABnN0cmluZwIAAAAFd29ybGQFAAAAA25pbAkAAAAAAAACCQAEEQAAAAIFAAAAAWQCAAAAB2Jvb2xlYW4GaWuehg==`, env, true, false}, - //{`getBooleanValueFromArrayByKey`, `let d = [DataEntry("integer",100500), DataEntry("boolean", true), DataEntry("binary", base16'68656c6c6f'), DataEntry("string", "world")]; getBooleanValue(d, "boolean") == true`, `AwQAAAABZAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHaW50ZWdlcgAAAAAAAAGIlAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHYm9vbGVhbgYJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABmJpbmFyeQEAAAAFaGVsbG8JAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABnN0cmluZwIAAAAFd29ybGQFAAAAA25pbAkAAAAAAAACCQEAAAARQGV4dHJOYXRpdmUoMTA0MSkAAAACBQAAAAFkAgAAAAdib29sZWFuBt3vwJY=`, env, true, false}, - //{`getBinaryFromArrayByKey`, `let d = [DataEntry("integer",100500), DataEntry("boolean", true), DataEntry("binary", base16'68656c6c6f'), DataEntry("string", "world")]; getBinary(d, "binary") == base16'68656c6c6f'`, `AwQAAAABZAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHaW50ZWdlcgAAAAAAAAGIlAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHYm9vbGVhbgYJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABmJpbmFyeQEAAAAFaGVsbG8JAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABnN0cmluZwIAAAAFd29ybGQFAAAAA25pbAkAAAAAAAACCQAEEgAAAAIFAAAAAWQCAAAABmJpbmFyeQEAAAAFaGVsbG+so7oZ`, env, true, false}, - //{`getBinaryValueFromArrayByKey`, `let d = [DataEntry("integer",100500), DataEntry("boolean", true), DataEntry("binary", base16'68656c6c6f'), DataEntry("string", "world")]; getBinaryValue(d, "binary") == base16'68656c6c6f'`, `AwQAAAABZAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHaW50ZWdlcgAAAAAAAAGIlAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHYm9vbGVhbgYJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABmJpbmFyeQEAAAAFaGVsbG8JAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABnN0cmluZwIAAAAFd29ybGQFAAAAA25pbAkAAAAAAAACCQEAAAARQGV4dHJOYXRpdmUoMTA0MikAAAACBQAAAAFkAgAAAAZiaW5hcnkBAAAABWhlbGxvpcldYg==`, env, true, false}, - //{`getStringFromArrayByKey`, `let d = [DataEntry("integer",100500), DataEntry("boolean", true), DataEntry("binary", base16'68656c6c6f'), DataEntry("string", "world")]; getString(d, "string") == "world"`, `AwQAAAABZAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHaW50ZWdlcgAAAAAAAAGIlAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHYm9vbGVhbgYJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABmJpbmFyeQEAAAAFaGVsbG8JAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABnN0cmluZwIAAAAFd29ybGQFAAAAA25pbAkAAAAAAAACCQAEEwAAAAIFAAAAAWQCAAAABnN0cmluZwIAAAAFd29ybGRFTMLs`, env, true, false}, - //{`getStringValueFromArrayByKey`, `let d = [DataEntry("integer",100500), DataEntry("boolean", true), DataEntry("binary", base16'68656c6c6f'), DataEntry("string", "world")]; getStringValue(d, "string") == "world"`, `AwQAAAABZAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHaW50ZWdlcgAAAAAAAAGIlAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHYm9vbGVhbgYJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABmJpbmFyeQEAAAAFaGVsbG8JAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABnN0cmluZwIAAAAFd29ybGQFAAAAA25pbAkAAAAAAAACCQEAAAARQGV4dHJOYXRpdmUoMTA0MykAAAACBQAAAAFkAgAAAAZzdHJpbmcCAAAABXdvcmxkCbSDLQ==`, env, true, false}, - //{`getIntegerFromArrayByIndex`, `let d = [DataEntry("integer", 100500), DataEntry("boolean", true), DataEntry("binary", base16'68656c6c6f'), DataEntry("string", "world")]; getInteger(d, 0) == 100500`, `AwQAAAABZAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHaW50ZWdlcgAAAAAAAAGIlAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHYm9vbGVhbgYJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABmJpbmFyeQEAAAAFaGVsbG8JAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABnN0cmluZwIAAAAFd29ybGQFAAAAA25pbAkAAAAAAAACCQEAAAAKZ2V0SW50ZWdlcgAAAAIFAAAAAWQAAAAAAAAAAAAAAAAAAAABiJTdCjRc`, env, true, false}, - //{`getIntegerValueFromArrayByIndex`, `let d = [DataEntry("integer", 100500), DataEntry("boolean", true), DataEntry("binary", base16'68656c6c6f'), DataEntry("string", "world")]; getIntegerValue(d, 0) == 100500`, `AwQAAAABZAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHaW50ZWdlcgAAAAAAAAGIlAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHYm9vbGVhbgYJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABmJpbmFyeQEAAAAFaGVsbG8JAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABnN0cmluZwIAAAAFd29ybGQFAAAAA25pbAkAAAAAAAACCQEAAAAVQGV4dHJVc2VyKGdldEludGVnZXIpAAAAAgUAAAABZAAAAAAAAAAAAAAAAAAAAAGIlOyDHCY=`, env, true, false}, - //{`getBooleanFromArrayByIndex`, `let d = [DataEntry("integer",100500), DataEntry("boolean", true), DataEntry("binary", base16'68656c6c6f'), DataEntry("string", "world")]; getBoolean(d, 1) == true`, `AwQAAAABZAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHaW50ZWdlcgAAAAAAAAGIlAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHYm9vbGVhbgYJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABmJpbmFyeQEAAAAFaGVsbG8JAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABnN0cmluZwIAAAAFd29ybGQFAAAAA25pbAkAAAAAAAACCQEAAAAKZ2V0Qm9vbGVhbgAAAAIFAAAAAWQAAAAAAAAAAAEGlS0yug==`, env, true, false}, - //{`getBooleanValueFromArrayByIndex`, `let d = [DataEntry("integer",100500), DataEntry("boolean", true), DataEntry("binary", base16'68656c6c6f'), DataEntry("string", "world")]; getBooleanValue(d, 1) == true`, `AwQAAAABZAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHaW50ZWdlcgAAAAAAAAGIlAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHYm9vbGVhbgYJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABmJpbmFyeQEAAAAFaGVsbG8JAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABnN0cmluZwIAAAAFd29ybGQFAAAAA25pbAkAAAAAAAACCQEAAAAVQGV4dHJVc2VyKGdldEJvb2xlYW4pAAAAAgUAAAABZAAAAAAAAAAAAQY8zZ6Y`, env, true, false}, - //{`getBinaryFromArrayByIndex`, `let d = [DataEntry("integer",100500), DataEntry("boolean", true), DataEntry("binary", base16'68656c6c6f'), DataEntry("string", "world")]; getBinary(d, 2) == base16'68656c6c6f'`, `AwQAAAABZAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHaW50ZWdlcgAAAAAAAAGIlAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHYm9vbGVhbgYJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABmJpbmFyeQEAAAAFaGVsbG8JAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABnN0cmluZwIAAAAFd29ybGQFAAAAA25pbAkAAAAAAAACCQEAAAAJZ2V0QmluYXJ5AAAAAgUAAAABZAAAAAAAAAAAAgEAAAAFaGVsbG/jc7GJ`, env, true, false}, - //{`getBinaryValueFromArrayByIndex`, `let d = [DataEntry("integer",100500), DataEntry("boolean", true), DataEntry("binary", base16'68656c6c6f'), DataEntry("string", "world")]; getBinaryValue(d, 2) == base16'68656c6c6f'`, `AwQAAAABZAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHaW50ZWdlcgAAAAAAAAGIlAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHYm9vbGVhbgYJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABmJpbmFyeQEAAAAFaGVsbG8JAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABnN0cmluZwIAAAAFd29ybGQFAAAAA25pbAkAAAAAAAACCQEAAAAUQGV4dHJVc2VyKGdldEJpbmFyeSkAAAACBQAAAAFkAAAAAAAAAAACAQAAAAVoZWxsbwxEPw4=`, env, true, false}, - //{`getStringFromArrayByIndex`, `let d = [DataEntry("integer",100500), DataEntry("boolean", true), DataEntry("binary", base16'68656c6c6f'), DataEntry("string", "world")]; getString(d, 3) == "world"`, `AwQAAAABZAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHaW50ZWdlcgAAAAAAAAGIlAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHYm9vbGVhbgYJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABmJpbmFyeQEAAAAFaGVsbG8JAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABnN0cmluZwIAAAAFd29ybGQFAAAAA25pbAkAAAAAAAACCQEAAAAJZ2V0U3RyaW5nAAAAAgUAAAABZAAAAAAAAAAAAwIAAAAFd29ybGTcG8rI`, env, true, false}, - //{`getStringValueFromArrayByIndex`, `let d = [DataEntry("integer",100500), DataEntry("boolean", true), DataEntry("binary", base16'68656c6c6f'), DataEntry("string", "world")]; getStringValue(d, 3) == "world"`, `AwQAAAABZAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHaW50ZWdlcgAAAAAAAAGIlAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgIAAAAHYm9vbGVhbgYJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABmJpbmFyeQEAAAAFaGVsbG8JAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAICAAAABnN0cmluZwIAAAAFd29ybGQFAAAAA25pbAkAAAAAAAACCQEAAAAUQGV4dHJVc2VyKGdldFN0cmluZykAAAACBQAAAAFkAAAAAAAAAAADAgAAAAV3b3JsZOGBO8c=`, env, true, false}, - //{`compare Recipient with Address`, `let a = Address(base58'3PKpKgcwArHQVmYWUg6Ljxx31VueBStUKBR'); match tx {case tt: TransferTransaction => tt.recipient == a case _ => false}`, `AwQAAAABYQkBAAAAB0FkZHJlc3MAAAABAQAAABoBV8Q0LvvkEO83LtpdRUhgK760itMpcq1W7AQAAAAHJG1hdGNoMAUAAAACdHgDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAE1RyYW5zZmVyVHJhbnNhY3Rpb24EAAAAAnR0BQAAAAckbWF0Y2gwCQAAAAAAAAIIBQAAAAJ0dAAAAAlyZWNpcGllbnQFAAAAAWEHQOLkRA==`, env, false, false}, - //{`compare Recipient with Address`, `let a = Address(base58'3P2USE3iYK5w7jNahAUHTytNbVRccGZwQH3'); match tx {case tt: TransferTransaction => tt.recipient == a case _ => false}`, `AwQAAAABYQkBAAAAB0FkZHJlc3MAAAABAQAAABoBVwX3L9Q7Ao0/8ZNhoE70/41bHPBwqbd27gQAAAAHJG1hdGNoMAUAAAACdHgDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAE1RyYW5zZmVyVHJhbnNhY3Rpb24EAAAAAnR0BQAAAAckbWF0Y2gwCQAAAAAAAAIIBQAAAAJ0dAAAAAlyZWNpcGllbnQFAAAAAWEHd9vYmA==`, env, true, false}, - //{`compare Address with Recipient`, `let a = Address(base58'3PKpKgcwArHQVmYWUg6Ljxx31VueBStUKBR'); match tx {case tt: TransferTransaction => a == tt.recipient case _ => false}`, `AwQAAAABYQkBAAAAB0FkZHJlc3MAAAABAQAAABoBV8Q0LvvkEO83LtpdRUhgK760itMpcq1W7AQAAAAHJG1hdGNoMAUAAAACdHgDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAE1RyYW5zZmVyVHJhbnNhY3Rpb24EAAAAAnR0BQAAAAckbWF0Y2gwCQAAAAAAAAIFAAAAAWEIBQAAAAJ0dAAAAAlyZWNpcGllbnQHG1tX4w==`, env, false, false}, - //{`compare Address with Recipient`, `let a = Address(base58'3P2USE3iYK5w7jNahAUHTytNbVRccGZwQH3'); match tx {case tt: TransferTransaction => a == tt.recipient case _ => false}`, `AwQAAAABYQkBAAAAB0FkZHJlc3MAAAABAQAAABoBVwX3L9Q7Ao0/8ZNhoE70/41bHPBwqbd27gQAAAAHJG1hdGNoMAUAAAACdHgDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAE1RyYW5zZmVyVHJhbnNhY3Rpb24EAAAAAnR0BQAAAAckbWF0Y2gwCQAAAAAAAAIFAAAAAWEIBQAAAAJ0dAAAAAlyZWNpcGllbnQHw8RWfw==`, env, true, false}, - // - //{`getIntegerFromDataTransactionByKey`, `match tx {case d: DataTransaction => extract(getInteger(d.data, "integer")) == 100500 case _ => false}`, `AQQAAAAHJG1hdGNoMAUAAAACdHgDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAD0RhdGFUcmFuc2FjdGlvbgQAAAABZAUAAAAHJG1hdGNoMAkAAAAAAAACCQEAAAAHZXh0cmFjdAAAAAEJAAQQAAAAAggFAAAAAWQAAAAEZGF0YQIAAAAHaW50ZWdlcgAAAAAAAAGIlAfN4Sfl`, envWithDataTX, true, false}, - //{`getIntegerFromDataTransactionByKey`, `match tx {case dt: DataTransaction => let a = match getInteger(dt.data, "someKey") {case v: Int => v case _ => -1}; a >= 0 case _ => false}`, `AQQAAAAHJG1hdGNoMAUAAAACdHgDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAD0RhdGFUcmFuc2FjdGlvbgQAAAACZHQFAAAAByRtYXRjaDAEAAAAAWEEAAAAByRtYXRjaDEJAAQQAAAAAggFAAAAAmR0AAAABGRhdGECAAAAB3NvbWVLZXkDCQAAAQAAAAIFAAAAByRtYXRjaDECAAAAA0ludAQAAAABdgUAAAAHJG1hdGNoMQUAAAABdgD//////////wkAAGcAAAACBQAAAAFhAAAAAAAAAAAAB1mStww=`, envWithDataTX, true, false}, - //{`getIntegerFromDataTransactionByKey`, `match tx {case dt: DataTransaction => let x = match getInteger(dt.data, "someKey") {case i: Int => true case _ => false};let y = match getInteger(dt.data, "someKey") {case v: Int => v case _ => -1}; x && y >= 0 case _ => false}`, `AQQAAAAHJG1hdGNoMAUAAAACdHgDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAD0RhdGFUcmFuc2FjdGlvbgQAAAACZHQFAAAAByRtYXRjaDAEAAAAAXgEAAAAByRtYXRjaDEJAAQQAAAAAggFAAAAAmR0AAAABGRhdGECAAAAB3NvbWVLZXkDCQAAAQAAAAIFAAAAByRtYXRjaDECAAAAA0ludAQAAAABaQUAAAAHJG1hdGNoMQYHBAAAAAF5BAAAAAckbWF0Y2gxCQAEEAAAAAIIBQAAAAJkdAAAAARkYXRhAgAAAAdzb21lS2V5AwkAAAEAAAACBQAAAAckbWF0Y2gxAgAAAANJbnQEAAAAAXYFAAAAByRtYXRjaDEFAAAAAXYA//////////8DBQAAAAF4CQAAZwAAAAIFAAAAAXkAAAAAAAAAAAAHB5sznFY=`, envWithDataTX, true, false}, - //{`matchIntegerFromDataTransactionByKey`, `let x = match tx {case d: DataTransaction => match getInteger(d.data, "integer") {case i: Int => i case _ => 0}case _ => 0}; x == 100500`, `AQQAAAABeAQAAAAHJG1hdGNoMAUAAAACdHgDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAD0RhdGFUcmFuc2FjdGlvbgQAAAABZAUAAAAHJG1hdGNoMAQAAAAHJG1hdGNoMQkABBAAAAACCAUAAAABZAAAAARkYXRhAgAAAAdpbnRlZ2VyAwkAAAEAAAACBQAAAAckbWF0Y2gxAgAAAANJbnQEAAAAAWkFAAAAByRtYXRjaDEFAAAAAWkAAAAAAAAAAAAAAAAAAAAAAAAJAAAAAAAAAgUAAAABeAAAAAAAAAGIlApOoB4=`, envWithDataTX, true, false}, - //{`matchIntegerFromState`, `let a = addressFromStringValue("3P2USE3iYK5w7jNahAUHTytNbVRccGZwQH3"); let i = getInteger(a, "integer"); let x = match i {case i: Int => i case _ => 0}; x == 100500`, `AwQAAAABYQkBAAAAHEBleHRyVXNlcihhZGRyZXNzRnJvbVN0cmluZykAAAABAgAAACMzUDJVU0UzaVlLNXc3ak5haEFVSFR5dE5iVlJjY0dad1FIMwQAAAABaQkABBoAAAACBQAAAAFhAgAAAAdpbnRlZ2VyBAAAAAF4BAAAAAckbWF0Y2gwBQAAAAFpAwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAANJbnQEAAAAAWkFAAAAByRtYXRjaDAFAAAAAWkAAAAAAAAAAAAJAAAAAAAAAgUAAAABeAAAAAAAAAGIlKWtlDk=`, env, true, false}, - //{`ifIntegerFromState`, `let a = addressFromStringValue("3P2USE3iYK5w7jNahAUHTytNbVRccGZwQH3"); let i = getInteger(a, "integer"); let x = if i != 0 then i else 0; x == 100500`, `AwQAAAABYQkBAAAAHEBleHRyVXNlcihhZGRyZXNzRnJvbVN0cmluZykAAAABAgAAACMzUDJVU0UzaVlLNXc3ak5haEFVSFR5dE5iVlJjY0dad1FIMwQAAAABaQkABBoAAAACBQAAAAFhAgAAAAdpbnRlZ2VyBAAAAAF4AwkBAAAAAiE9AAAAAgUAAAABaQAAAAAAAAAAAAUAAAABaQAAAAAAAAAAAAkAAAAAAAACBQAAAAF4AAAAAAAAAYiU1cZgMA==`, env, true, false}, - // - //{`string concatenation`, `let a = base16'cafe'; let b = base16'bebe'; toBase58String(a) + "/" + toBase58String(b) == "GSy/FWu"`, `AwQAAAABYQEAAAACyv4EAAAAAWIBAAAAAr6+CQAAAAAAAAIJAAEsAAAAAgkAASwAAAACCQACWAAAAAEFAAAAAWECAAAAAS8JAAJYAAAAAQUAAAABYgIAAAAHR1N5L0ZXdc2NqKQ=`, env, true, false}, - //{`match on ByteVector`, `match tx {case etx: ExchangeTransaction => match etx.sellOrder.assetPair.amountAsset {case ByteVector => true case _ => false} case _ => false}`, `AwQAAAAHJG1hdGNoMAUAAAACdHgDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAE0V4Y2hhbmdlVHJhbnNhY3Rpb24EAAAAA2V0eAUAAAAHJG1hdGNoMAQAAAAHJG1hdGNoMQgICAUAAAADZXR4AAAACXNlbGxPcmRlcgAAAAlhc3NldFBhaXIAAAALYW1vdW50QXNzZXQEAAAACkJ5dGVWZWN0b3IFAAAAByRtYXRjaDEGB76y+jI=`, envWithExchangeTX, true, false}, - // - {`3P8M8XGF2uzDazV5fzdKNxrbC3YqCWScKxw`, ``, `AwoBAAAAGVJlbW92ZVVuZGVyc2NvcmVJZlByZXNlbnQAAAABAAAACXJlbWFpbmluZwMJAABmAAAAAgkAATEAAAABBQAAAAlyZW1haW5pbmcAAAAAAAAAAAAJAAEwAAAAAgUAAAAJcmVtYWluaW5nAAAAAAAAAAABBQAAAAlyZW1haW5pbmcKAQAAABJQYXJzZU5leHRBdHRyaWJ1dGUAAAABAAAACXJlbWFpbmluZwQAAAABcwkAATEAAAABBQAAAAlyZW1haW5pbmcDCQAAZgAAAAIFAAAAAXMAAAAAAAAAAAAEAAAAAm5uCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAEvAAAAAgUAAAAJcmVtYWluaW5nAAAAAAAAAAACBAAAAAF2CQABLwAAAAIJAAEwAAAAAgUAAAAJcmVtYWluaW5nAAAAAAAAAAACBQAAAAJubgQAAAAMdG1wUmVtYWluaW5nCQABMAAAAAIFAAAACXJlbWFpbmluZwkAAGQAAAACBQAAAAJubgAAAAAAAAAAAgQAAAAOcmVtYWluaW5nU3RhdGUJAQAAABlSZW1vdmVVbmRlcnNjb3JlSWZQcmVzZW50AAAAAQUAAAAMdG1wUmVtYWluaW5nCQAETAAAAAIFAAAAAXYJAARMAAAAAgUAAAAOcmVtYWluaW5nU3RhdGUFAAAAA25pbAkAAAIAAAABAgAAADRFbXB0eSBzdHJpbmcgd2FzIHBhc3NlZCBpbnRvIHBhcnNlTmV4dEF0dHJpYnV0ZSBmdW5jCgEAAAATUGFyc2VHYW1lUmF3RGF0YVN0cgAAAAEAAAALcmF3U3RhdGVTdHIEAAAACWdhbWVTdGF0ZQkBAAAAElBhcnNlTmV4dEF0dHJpYnV0ZQAAAAEFAAAAC3Jhd1N0YXRlU3RyBAAAAAxwbGF5ZXJDaG9pY2UJAQAAABJQYXJzZU5leHRBdHRyaWJ1dGUAAAABCQABkQAAAAIFAAAACWdhbWVTdGF0ZQAAAAAAAAAAAQQAAAAOcGxheWVyUHViS2V5NTgJAQAAABJQYXJzZU5leHRBdHRyaWJ1dGUAAAABCQABkQAAAAIFAAAADHBsYXllckNob2ljZQAAAAAAAAAAAQQAAAANc3RhcnRlZEhlaWdodAkBAAAAElBhcnNlTmV4dEF0dHJpYnV0ZQAAAAEJAAGRAAAAAgUAAAAOcGxheWVyUHViS2V5NTgAAAAAAAAAAAEEAAAABndpbkFtdAkBAAAAElBhcnNlTmV4dEF0dHJpYnV0ZQAAAAEJAAGRAAAAAgUAAAANc3RhcnRlZEhlaWdodAAAAAAAAAAAAQkABEwAAAACCQABkQAAAAIFAAAACWdhbWVTdGF0ZQAAAAAAAAAAAAkABEwAAAACCQABkQAAAAIFAAAADHBsYXllckNob2ljZQAAAAAAAAAAAAkABEwAAAACCQABkQAAAAIFAAAADnBsYXllclB1YktleTU4AAAAAAAAAAAACQAETAAAAAIJAAGRAAAAAgUAAAANc3RhcnRlZEhlaWdodAAAAAAAAAAAAAkABEwAAAACCQABkQAAAAIFAAAABndpbkFtdAAAAAAAAAAAAAUAAAADbmlsCQAAAAAAAAIJAQAAABNQYXJzZUdhbWVSYXdEYXRhU3RyAAAAAQIAAABWMDNXT05fMDUzNTY0Ml80NDM4OXBhNmlOaHgxaEZEcU5abVNBVEp1ZldaMUVMbUtkOUh4eXpQUUtIdWMzXzA3MTYxMDU1N18wOTExNDAwMDAwMF8wMTYJAARMAAAAAgIAAAADV09OCQAETAAAAAICAAAABTM1NjQyCQAETAAAAAICAAAALDM4OXBhNmlOaHgxaEZEcU5abVNBVEp1ZldaMUVMbUtkOUh4eXpQUUtIdWMzCQAETAAAAAICAAAABzE2MTA1NTcJAARMAAAAAgIAAAAJMTE0MDAwMDAwBQAAAANuaWyuDQ4Y`, envWithExchangeTX, true, false}, - - //{"EQ", `5 == 5`, `AQkAAAAAAAACAAAAAAAAAAAFAAAAAAAAAAAFqWG0Fw==`, env, true, false}, - //{"ISINSTANCEOF", `match tx {case t : TransferTransaction => true case _ => false}`, `AQQAAAAHJG1hdGNoMAUAAAACdHgDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAE1RyYW5zZmVyVHJhbnNhY3Rpb24EAAAAAXQFAAAAByRtYXRjaDAGB5yQ/+k=`, env, true, false}, - //{`THROW`, `true && throw("mess")`, `AQMGCQAAAgAAAAECAAAABG1lc3MH7PDwAQ==`, env, false, true}, - //{`SUM_LONG`, `1 + 1 > 0`, `AQkAAGYAAAACCQAAZAAAAAIAAAAAAAAAAAEAAAAAAAAAAAEAAAAAAAAAAABiJjSk`, env, true, false}, - //{`SUB_LONG`, `2 - 1 > 0`, `AQkAAGYAAAACCQAAZQAAAAIAAAAAAAAAAAIAAAAAAAAAAAEAAAAAAAAAAABqsps1`, env, true, false}, - //{`GT_LONG`, `1 > 0`, `AQkAAGYAAAACAAAAAAAAAAABAAAAAAAAAAAAyAIM4w==`, env, true, false}, - //{`GE_LONG`, `1 >= 0`, `AQkAAGcAAAACAAAAAAAAAAABAAAAAAAAAAAAm30DnQ==`, env, true, false}, - //{`MUL_LONG`, `2 * 2>0`, `AQkAAGYAAAACCQAAaAAAAAIAAAAAAAAAAAIAAAAAAAAAAAIAAAAAAAAAAABCMM5o`, env, true, false}, - //{`DIV_LONG`, `4 / 2>0`, `AQkAAGYAAAACCQAAaQAAAAIAAAAAAAAAAAQAAAAAAAAAAAIAAAAAAAAAAAAadVma`, env, true, false}, - //{`DIV_LONG`, `10000 / (27+121) == 67`, `AwkAAAAAAAACCQAAaQAAAAIAAAAAAAAAJxAJAABkAAAAAgAAAAAAAAAAGwAAAAAAAAAAeQAAAAAAAAAAQ1vSVaQ=`, env, true, false}, - //{`DIV_LONG`, `((98750005 * (100 - 4)) / 100) == 94800004`, `AwkAAAAAAAACCQAAaQAAAAIJAABoAAAAAgAAAAAABeLONQkAAGUAAAACAAAAAAAAAABkAAAAAAAAAAAEAAAAAAAAAABkAAAAAAAFpoiEGMUZcA==`, env, true, false}, - //{`MOD_LONG`, `-10 % 6>0`, `AQkAAGYAAAACCQAAagAAAAIA//////////YAAAAAAAAAAAYAAAAAAAAAAAB5rBSH`, env, true, false}, - //{`MOD_LONG`, `10000 % 100 == 0`, `AwkAAAAAAAACCQAAagAAAAIAAAAAAAAAJxAAAAAAAAAAAGQAAAAAAAAAAAAmFt9K`, env, true, false}, - //{`FRACTION`, `fraction(10, 5, 2)>0`, `AQkAAGYAAAACCQAAawAAAAMAAAAAAAAAAAoAAAAAAAAAAAUAAAAAAAAAAAIAAAAAAAAAAACRyFu2`, env, true, false}, - //{`POW`, `pow(12, 1, 3456, 3, 2, Down()) == 187`, `AwkAAAAAAAACCQAAbAAAAAYAAAAAAAAAAAwAAAAAAAAAAAEAAAAAAAAADYAAAAAAAAAAAAMAAAAAAAAAAAIJAQAAAAREb3duAAAAAAAAAAAAAAAAu9llw2M=`, env, true, false}, - //{`POW`, `pow(12, 1, 3456, 3, 2, UP) == 188`, `AwkAAAAAAAACCQAAbAAAAAYAAAAAAAAAAAwAAAAAAAAAAAEAAAAAAAAADYAAAAAAAAAAAAMAAAAAAAAAAAIFAAAAAlVQAAAAAAAAAAC8evjDQQ==`, env, true, false}, - //{`POW`, `pow(12, 1, 3456, 3, 2, UP) == 187`, `AwkAAAAAAAACCQAAbAAAAAYAAAAAAAAAAAwAAAAAAAAAAAEAAAAAAAAADYAAAAAAAAAAAAMAAAAAAAAAAAIFAAAAAlVQAAAAAAAAAAC7FUMwCQ==`, env, false, false}, - //{`LOG`, `log(16, 0, 2, 0, 0, CEILING) == 4`, `AwkAAAAAAAACCQAAbQAAAAYAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAFAAAAB0NFSUxJTkcAAAAAAAAAAARh6Dy6`, env, true, false}, - //{`LOG`, `log(100, 0, 10, 0, 0, CEILING) == 2`, `AwkAAAAAAAACCQAAbQAAAAYAAAAAAAAAAGQAAAAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAFAAAAB0NFSUxJTkcAAAAAAAAAAAJ7Op42`, env, true, false}, - // - //{`SIZE_BYTES`, `size(base58'abcd') > 0`, `AQkAAGYAAAACCQAAyAAAAAEBAAAAA2QGAgAAAAAAAAAAACMcdM4=`, env, true, false}, - //{`TAKE_BYTES`, `size(take(base58'abcd', 2)) == 2`, `AQkAAAAAAAACCQAAyAAAAAEJAADJAAAAAgEAAAADZAYCAAAAAAAAAAACAAAAAAAAAAACccrCZg==`, env, true, false}, - //{`DROP_BYTES`, `size(drop(base58'abcd', 2)) > 0`, `AQkAAGYAAAACCQAAyAAAAAEJAADKAAAAAgEAAAADZAYCAAAAAAAAAAACAAAAAAAAAAAA+srbUQ==`, env, true, false}, - {`DROP_BYTES`, `let data = base64'AAAAAAABhqAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWyt9GyysOW84u/u5V5Ah/SzLfef4c28UqXxowxFZS4SLiC6+XBh8D7aJDXyTTjpkPPED06ZPOzUE23V6VYCsLw=='; func getStock(data:ByteVector) = toInt(take(drop(data, 8), 8)); getStock(data) == 1`, `AwQAAAAEZGF0YQEAAABwAAAAAAABhqAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWyt9GyysOW84u/u5V5Ah/SzLfef4c28UqXxowxFZS4SLiC6+XBh8D7aJDXyTTjpkPPED06ZPOzUE23V6VYCsLwoBAAAACGdldFN0b2NrAAAAAQAAAARkYXRhCQAEsQAAAAEJAADJAAAAAgkAAMoAAAACBQAAAARkYXRhAAAAAAAAAAAIAAAAAAAAAAAICQAAAAAAAAIJAQAAAAhnZXRTdG9jawAAAAEFAAAABGRhdGEAAAAAAAAAAAFCtabi`, env, true, false}, - //{`SUM_BYTES`, `size(base58'ab' + base58'cd') > 0`, `AQkAAGYAAAACCQAAyAAAAAEJAADLAAAAAgEAAAACB5wBAAAAAggSAAAAAAAAAAAAo+LRIA==`, env, true, false}, - // - //{`SUM_STRING`, `"ab"+"cd" == "abcd"`, `AQkAAAAAAAACCQABLAAAAAICAAAAAmFiAgAAAAJjZAIAAAAEYWJjZMBJvls=`, env, true, false}, - //{`TAKE_STRING`, `take("abcd", 2) == "ab"`, `AQkAAAAAAAACCQABLwAAAAICAAAABGFiY2QAAAAAAAAAAAICAAAAAmFiiXc+oQ==`, env, true, false}, - //{`TAKE_STRING`, `take("", 1) == ""`, `AwkAAAAAAAACCQABLwAAAAICAAAAAAAAAAAAAAAAAQIAAAAAmz5yjQ==`, env, true, false}, - //{`DROP_STRING`, `drop("abcd", 2) == "cd"`, `AQkAAAAAAAACCQABMAAAAAICAAAABGFiY2QAAAAAAAAAAAICAAAAAmNkZQdjWQ==`, env, true, false}, - //{`SIZE_STRING`, `size("abcd") == 4`, `AQkAAAAAAAACCQABMQAAAAECAAAABGFiY2QAAAAAAAAAAAScZzsq`, env, true, false}, - // - //{`SIZE_LIST`, `size(tx.proofs) == 8`, `AwkAAAAAAAACCQABkAAAAAEIBQAAAAJ0eAAAAAZwcm9vZnMAAAAAAAAAAAgEd23x`, env, true, false}, - //{`GET_LIST`, `size(tx.proofs[0]) > 0`, `AQkAAGYAAAACCQAAyAAAAAEJAAGRAAAAAggFAAAAAnR4AAAABnByb29mcwAAAAAAAAAAAAAAAAAAAAAAAFF6iVo=`, env, true, false}, - //{`LONG_TO_BYTES`, `toBytes(1) == base58'11111112'`, `AQkAAAAAAAACCQABmgAAAAEAAAAAAAAAAAEBAAAACAAAAAAAAAABm8cc1g==`, env, true, false}, - //{`STRING_TO_BYTES`, `toBytes("привет") == base58'4wUjatAwfVDjaHQVX'`, `AQkAAAAAAAACCQABmwAAAAECAAAADNC/0YDQuNCy0LXRggEAAAAM0L/RgNC40LLQtdGCuUGFxw==`, env, true, false}, - //{`BOOLEAN_TO_BYTES`, `toBytes(true) == base58'2'`, `AQkAAAAAAAACCQABnAAAAAEGAQAAAAEBJRrQbw==`, env, true, false}, - //{`LONG_TO_STRING`, `toString(5) == "5"`, `AQkAAAAAAAACCQABpAAAAAEAAAAAAAAAAAUCAAAAATXPb5tR`, env, true, false}, - //{`BOOLEAN_TO_STRING`, `toString(true) == "true"`, `AQkAAAAAAAACCQABpQAAAAEGAgAAAAR0cnVlL6ZrWg==`, env, true, false}, - // - //{`SIGVERIFY`, `sigVerify(tx.bodyBytes, tx.proofs[0], base58'14ovLL9a6xbBfftyxGNLKMdbnzGgnaFQjmgUJGdho6nY')`, `AQkAAfQAAAADCAUAAAACdHgAAAAJYm9keUJ5dGVzCQABkQAAAAIIBQAAAAJ0eAAAAAZwcm9vZnMAAAAAAAAAAAABAAAAIAD5y2Wf7zxfv7l+9tcWxyLAbktd9nCbdvFMnxmREqV1igWi3A==`, env, true, false}, - //{`KECCAK256`, `keccak256(base58'a') != base58'a'`, `AQkBAAAAAiE9AAAAAgkAAfUAAAABAQAAAAEhAQAAAAEhKeR77g==`, env, true, false}, - //{`BLAKE256`, `blake2b256(base58'a') != base58'a'`, `AQkBAAAAAiE9AAAAAgkAAfYAAAABAQAAAAEhAQAAAAEh50D2WA==`, env, true, false}, - //{`SHA256`, `sha256(base58'a') != base58'a'`, `AQkBAAAAAiE9AAAAAgkAAfcAAAABAQAAAAEhAQAAAAEhVojmeg==`, env, true, false}, - //{`RSAVERIFY`, `let pk = fromBase64String("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkDg8m0bCDX7fTbBlHZm+BZIHVOfC2I4klRbjSqwFi/eCdfhGjYRYvu/frpSO0LIm0beKOUvwat6DY4dEhNt2PW3UeQvT2udRQ9VBcpwaJlLreCr837sn4fa9UG9FQFaGofSww1O9eBBjwMXeZr1jOzR9RBIwoL1TQkIkZGaDXRltEaMxtNnzotPfF3vGIZZuZX4CjiitHaSC0zlmQrEL3BDqqoLwo3jq8U3Zz8XUMyQElwufGRbZqdFCeiIs/EoHiJm8q8CVExRoxB0H/vE2uDFK/OXLGTgfwnDlrCa/qGt9Zsb8raUSz9IIHx72XB+kOXTt/GOuW7x2dJvTJIqKTwIDAQAB"); let msg = fromBase64String("REIiN2hDQUxIJVQzdk1zQSpXclRRelExVWd+YGQoOyx0KHduPzFmcU8zUWosWiA7aFloOWplclAxPCU="); let sig = fromBase64String("OXVKJwtSoenRmwizPtpjh3sCNmOpU1tnXUnyzl+PEI1P9Rx20GkxkIXlysFT2WdbPn/HsfGMwGJW7YhrVkDXy4uAQxUxSgQouvfZoqGSPp1NtM8iVJOGyKiepgB3GxRzQsev2G8Ik47eNkEDVQa47ct9j198Wvnkf88yjSkK0KxR057MWAi20ipNLirW4ZHDAf1giv68mniKfKxsPWahOA/7JYkv18sxcsISQqRXM8nGI1UuSLt9ER7kIzyAk2mgPCiVlj0hoPGUytmbiUqvEM4QaJfCpR0wVO4f/fob6jwKkGT6wbtia+5xCD7bESIHH8ISDrdexZ01QyNP2r4enw=="); rsaVerify(SHA3256, msg, sig, pk)`, `AwQAAAACcGsJAAJbAAAAAQIAAAGITUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUFrRGc4bTBiQ0RYN2ZUYkJsSFptK0JaSUhWT2ZDMkk0a2xSYmpTcXdGaS9lQ2RmaEdqWVJZdnUvZnJwU08wTEltMGJlS09VdndhdDZEWTRkRWhOdDJQVzNVZVF2VDJ1ZFJROVZCY3B3YUpsTHJlQ3I4MzdzbjRmYTlVRzlGUUZhR29mU3d3MU85ZUJCandNWGVacjFqT3pSOVJCSXdvTDFUUWtJa1pHYURYUmx0RWFNeHRObnpvdFBmRjN2R0laWnVaWDRDamlpdEhhU0MwemxtUXJFTDNCRHFxb0x3bzNqcThVM1p6OFhVTXlRRWx3dWZHUmJacWRGQ2VpSXMvRW9IaUptOHE4Q1ZFeFJveEIwSC92RTJ1REZLL09YTEdUZ2Z3bkRsckNhL3FHdDlac2I4cmFVU3o5SUlIeDcyWEIra09YVHQvR091Vzd4MmRKdlRKSXFLVHdJREFRQUIEAAAAA21zZwkAAlsAAAABAgAAAFBSRUlpTjJoRFFVeElKVlF6ZGsxelFTcFhjbFJSZWxFeFZXZCtZR1FvT3l4MEtIZHVQekZtY1U4elVXb3NXaUE3YUZsb09XcGxjbEF4UENVPQQAAAADc2lnCQACWwAAAAECAAABWE9YVktKd3RTb2VuUm13aXpQdHBqaDNzQ05tT3BVMXRuWFVueXpsK1BFSTFQOVJ4MjBHa3hrSVhseXNGVDJXZGJQbi9Ic2ZHTXdHSlc3WWhyVmtEWHk0dUFReFV4U2dRb3V2ZlpvcUdTUHAxTnRNOGlWSk9HeUtpZXBnQjNHeFJ6UXNldjJHOElrNDdlTmtFRFZRYTQ3Y3Q5ajE5OFd2bmtmODh5alNrSzBLeFIwNTdNV0FpMjBpcE5MaXJXNFpIREFmMWdpdjY4bW5pS2ZLeHNQV2FoT0EvN0pZa3YxOHN4Y3NJU1FxUlhNOG5HSTFVdVNMdDlFUjdrSXp5QWsybWdQQ2lWbGowaG9QR1V5dG1iaVVxdkVNNFFhSmZDcFIwd1ZPNGYvZm9iNmp3S2tHVDZ3YnRpYSs1eENEN2JFU0lISDhJU0RyZGV4WjAxUXlOUDJyNGVudz09CQAB+AAAAAQFAAAAB1NIQTMyNTYFAAAAA21zZwUAAAADc2lnBQAAAAJwa8wcz28=`, env, true, false}, - // - //{`TOBASE58`, `toBase58String(base58'a') == "a"`, `AQkAAAAAAAACCQACWAAAAAEBAAAAASECAAAAAWFcT4nY`, env, true, false}, - //{`FROMBASE58`, `fromBase58String("a") == base58'a'`, `AQkAAAAAAAACCQACWQAAAAECAAAAAWEBAAAAASEB1Qmd`, env, true, false}, - //{`FROMBASE58`, `fromBase58String(extract("")) == base58''`, `AwkAAAAAAAACCQACWQAAAAEJAQAAAAdleHRyYWN0AAAAAQIAAAAAAQAAAAAt2xTN`, env, true, false}, - //{`TOBASE64`, `toBase64String(base16'544553547465737454455354') == "VEVTVHRlc3RURVNU"`, `AwkAAAAAAAACCQACWgAAAAEBAAAADFRFU1R0ZXN0VEVTVAIAAAAQVkVWVFZIUmxjM1JVUlZOVd6DVfc=`, env, true, false}, - //{`FROMBASE64`, `base16'544553547465737454455354' == fromBase64String("VEVTVHRlc3RURVNU")`, `AwkAAAAAAAACAQAAAAxURVNUdGVzdFRFU1QJAAJbAAAAAQIAAAAQVkVWVFZIUmxjM1JVUlZOVV+c29Q=`, env, true, false}, - //{`TOBASE16`, `toBase16String(base64'VEVTVHRlc3RURVNU') == "544553547465737454455354"`, `AwkAAAAAAAACCQACXAAAAAEBAAAADFRFU1R0ZXN0VEVTVAIAAAAYNTQ0NTUzNTQ3NDY1NzM3NDU0NDU1MzU07NMrMQ==`, env, true, false}, - //{`FROMBASE16`, `fromBase16String("544553547465737454455354") == base64'VEVTVHRlc3RURVNU'`, `AwkAAAAAAAACCQACXQAAAAECAAAAGDU0NDU1MzU0NzQ2NTczNzQ1NDQ1NTM1NAEAAAAMVEVTVHRlc3RURVNUFBEa5A==`, env, true, false}, - // - //{`CHECKMERKLEPROOF`, `let rootHash = base64'eh9fm3HeHZ3XA/UfMpC9HSwLVMyBLgkAJL0MIVBIoYk='; let leafData = base64'AAAm+w=='; let merkleProof = base64'ACBSs2di6rY+9N3mrpQVRNZLGAdRX2WBD6XkrOXuhh42XwEgKhB3Aiij6jqLRuQhrwqv6e05kr89tyxkuFYwUuMCQB8AIKLhp/AFQkokTe/NMQnKFL5eTMvDlFejApmJxPY6Rp8XACAWrdgB8DwvPA8D04E9HgUjhKghAn5aqtZnuKcmpLHztQAgd2OG15WYz90r1WipgXwjdq9WhvMIAtvGlm6E3WYY12oAIJXPPVIdbwOTdUJvCgMI4iape2gvR55vsrO2OmJJtZUNASAya23YyBl+EpKytL9+7cPdkeMMWSjk0Bc0GNnqIisofQ=='; checkMerkleProof(rootHash, merkleProof, leafData)`, `AwQAAAAIcm9vdEhhc2gBAAAAIHofX5tx3h2d1wP1HzKQvR0sC1TMgS4JACS9DCFQSKGJBAAAAAhsZWFmRGF0YQEAAAAEAAAm+wQAAAALbWVya2xlUHJvb2YBAAAA7gAgUrNnYuq2PvTd5q6UFUTWSxgHUV9lgQ+l5Kzl7oYeNl8BICoQdwIoo+o6i0bkIa8Kr+ntOZK/PbcsZLhWMFLjAkAfACCi4afwBUJKJE3vzTEJyhS+XkzLw5RXowKZicT2OkafFwAgFq3YAfA8LzwPA9OBPR4FI4SoIQJ+WqrWZ7inJqSx87UAIHdjhteVmM/dK9VoqYF8I3avVobzCALbxpZuhN1mGNdqACCVzz1SHW8Dk3VCbwoDCOImqXtoL0eeb7KztjpiSbWVDQEgMmtt2MgZfhKSsrS/fu3D3ZHjDFko5NAXNBjZ6iIrKH0JAAK8AAAAAwUAAAAIcm9vdEhhc2gFAAAAC21lcmtsZVByb29mBQAAAAhsZWFmRGF0YXe8Icg=`, env, true, false}, - // - //{`GETTRANSACTIONBYID`, `V2: match transactionById(tx.id) {case _: TransferTransaction => true; case _ => false}`, `AgQAAAAHJG1hdGNoMAkAA+gAAAABCAUAAAACdHgAAAACaWQDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAE1RyYW5zZmVyVHJhbnNhY3Rpb24GB9Sc8FA=`, env, true, false}, - //{`TRANSACTIONHEIGHTBYID`, `transactionHeightById(base58'aaaa') == 5`, `AQkAAAAAAAACCQAD6QAAAAEBAAAAA2P4ZwAAAAAAAAAABSLhRM4=`, env, false, false}, - //{`ACCOUNTASSETBALANCE`, `assetBalance(tx.sender, base58'BXBUNddxTGTQc3G4qHYn5E67SBwMj18zLncUr871iuRD') == 5`, `AQkAAAAAAAACCQAD6wAAAAIIBQAAAAJ0eAAAAAZzZW5kZXIBAAAAIJxQIls8iGUc1935JolBz6bYc37eoPDtScOAM0lTNhY0AAAAAAAAAAAFjp6PBg==`, env, true, false}, - //{`ADDRESSTOSTRING`, `toString(Address(base58'3P3336rNSSU8bDAqDb6S5jNs8DJb2bfNmpg')) == "3P3336rNSSU8bDAqDb6S5jNs8DJb2bfNmpg"`, `AwkAAAAAAAACCQAEJQAAAAEJAQAAAAdBZGRyZXNzAAAAAQEAAAAaAVcMIZxOsk2Gw5Avd0ztqi+phtb1Bb83MiUCAAAAIzNQMzMzNnJOU1NVOGJEQXFEYjZTNWpOczhESmIyYmZObXBnkXj7Cg==`, env, true, false}, - //{`ADDRESSTOSTRING`, `toString(Address(base58'3P3336rNSSU8bDAqDb6S5jNs8DJb2bfNmpg')) == "3P3336rNSSU8bDAqDb6S5jNs8DJb2bfNmpf"`, `AwkAAAAAAAACCQAEJQAAAAEJAQAAAAdBZGRyZXNzAAAAAQEAAAAaAVcMIZxOsk2Gw5Avd0ztqi+phtb1Bb83MiUCAAAAIzNQMzMzNnJOU1NVOGJEQXFEYjZTNWpOczhESmIyYmZObXBmb/6mcg==`, env, false, false}, - //{`CONS`, `size([1, "2"]) == 2`, `AwkAAAAAAAACCQABkAAAAAEJAARMAAAAAgAAAAAAAAAAAQkABEwAAAACAgAAAAEyBQAAAANuaWwAAAAAAAAAAAKuUcc0`, env, true, false}, - //{`CONS`, `size(cons(1, nil)) == 1`, `AwkAAAAAAAACCQABkAAAAAEJAARMAAAAAgAAAAAAAAAAAQUAAAADbmlsAAAAAAAAAAABX96esw==`, env, true, false}, - //{`CONS`, `[1, 2, 3, 4, 5][4] == 5`, `AwkAAAAAAAACCQABkQAAAAIJAARMAAAAAgAAAAAAAAAAAQkABEwAAAACAAAAAAAAAAACCQAETAAAAAIAAAAAAAAAAAMJAARMAAAAAgAAAAAAAAAABAkABEwAAAACAAAAAAAAAAAFBQAAAANuaWwAAAAAAAAAAAQAAAAAAAAAAAVrPjYC`, env, true, false}, - //{`CONS`, `[1, 2, 3, 4, 5][4] == 4`, `AwkAAAAAAAACCQABkQAAAAIJAARMAAAAAgAAAAAAAAAAAQkABEwAAAACAAAAAAAAAAACCQAETAAAAAIAAAAAAAAAAAMJAARMAAAAAgAAAAAAAAAABAkABEwAAAACAAAAAAAAAAAFBQAAAANuaWwAAAAAAAAAAAQAAAAAAAAAAASbi8eN`, env, false, false}, - //{`UTF8STR`, `toUtf8String(base16'536f6d65207465737420737472696e67') == "Some test string"`, `AwkAAAAAAAACCQAEsAAAAAEBAAAAEFNvbWUgdGVzdCBzdHJpbmcCAAAAEFNvbWUgdGVzdCBzdHJpbme0Wj5y`, env, true, false}, - //{`UTF8STR`, `toUtf8String(base16'536f6d65207465737420737472696e67') == "blah-blah-blah"`, `AwkAAAAAAAACCQAEsAAAAAEBAAAAEFNvbWUgdGVzdCBzdHJpbmcCAAAADmJsYWgtYmxhaC1ibGFojpjG3g==`, env, false, false}, - //{`TOINT`, `toInt(base16'0000000000003039') == 12345`, `AwkAAAAAAAACCQAEsQAAAAEBAAAACAAAAAAAADA5AAAAAAAAADA5WVzTeQ==`, env, true, false}, - //{`TOINT`, `toInt(base16'3930000000000000') == 12345`, `AwkAAAAAAAACCQAEsQAAAAEBAAAACDkwAAAAAAAAAAAAAAAAADA5Vq02Hg==`, env, false, false}, - //{`TOINT_OFF`, `toInt(base16'ffffff0000000000003039', 3) == 12345`, `AwkAAAAAAAACCQAEsgAAAAIBAAAAC////wAAAAAAADA5AAAAAAAAAAADAAAAAAAAADA5pGJt2g==`, env, true, false}, - //{`TOINT_OFF`, `toInt(base16'ffffff0000000000003039', 2) == 12345`, `AwkAAAAAAAACCQAEsgAAAAIBAAAAC////wAAAAAAADA5AAAAAAAAAAACAAAAAAAAADA57UQA4Q==`, env, false, false}, - //{`INDEXOF`, `indexOf("cafe bebe dead beef cafe bebe", "bebe") == 5`, `AwkAAAAAAAACCQAEswAAAAICAAAAHWNhZmUgYmViZSBkZWFkIGJlZWYgY2FmZSBiZWJlAgAAAARiZWJlAAAAAAAAAAAFyqpjwQ==`, env, true, false}, - //{`INDEXOF`, `indexOf("cafe bebe dead beef cafe bebe", "fox") == unit`, `AwkAAAAAAAACCQAEswAAAAICAAAAHWNhZmUgYmViZSBkZWFkIGJlZWYgY2FmZSBiZWJlAgAAAANmb3gFAAAABHVuaXS7twzl`, env, true, false}, - //{`INDEXOF`, `indexOf("世界}}世界", "}}") == 2`, `AwkAAAAAAAACCQAEswAAAAICAAAADuS4lueVjH195LiW55WMAgAAAAJ9fQAAAAAAAAAAAjCgf3g=`, env, true, false}, - //{`INDEXOFN`, `indexOf("cafe bebe dead beef cafe bebe", "bebe", 0) == 5`, `AwkAAAAAAAACCQAEtAAAAAMCAAAAHWNhZmUgYmViZSBkZWFkIGJlZWYgY2FmZSBiZWJlAgAAAARiZWJlAAAAAAAAAAAAAAAAAAAAAAAFFBPTAA==`, env, true, false}, - //{`INDEXOFN`, `indexOf("cafe bebe dead beef cafe bebe", "bebe", 10) == 25`, `AwkAAAAAAAACCQAEtAAAAAMCAAAAHWNhZmUgYmViZSBkZWFkIGJlZWYgY2FmZSBiZWJlAgAAAARiZWJlAAAAAAAAAAAKAAAAAAAAAAAZVBpWMw==`, env, true, false}, - //{`INDEXOFN`, `indexOf("cafe bebe dead beef cafe bebe", "dead", 10) == 10`, `AwkAAAAAAAACCQAEtAAAAAMCAAAAHWNhZmUgYmViZSBkZWFkIGJlZWYgY2FmZSBiZWJlAgAAAARkZWFkAAAAAAAAAAAKAAAAAAAAAAAKstuWEQ==`, env, true, false}, - //{`INDEXOFN`, `indexOf("cafe bebe dead beef cafe bebe", "dead", 11) == unit`, `AwkAAAAAAAACCQAEtAAAAAMCAAAAHWNhZmUgYmViZSBkZWFkIGJlZWYgY2FmZSBiZWJlAgAAAARkZWFkAAAAAAAAAAALBQAAAAR1bml0f2q2UQ==`, env, true, false}, - //{`SPLIT`, `split("abcd", "") == ["a", "b", "c", "d"]`, `AwkAAAAAAAACCQAEtQAAAAICAAAABGFiY2QCAAAAAAkABEwAAAACAgAAAAFhCQAETAAAAAICAAAAAWIJAARMAAAAAgIAAAABYwkABEwAAAACAgAAAAFkBQAAAANuaWwrnSMu`, env, true, false}, - //{`SPLIT`, `split("one two three", " ") == ["one", "two", "three"]`, `AwkAAAAAAAACCQAEtQAAAAICAAAADW9uZSB0d28gdGhyZWUCAAAAASAJAARMAAAAAgIAAAADb25lCQAETAAAAAICAAAAA3R3bwkABEwAAAACAgAAAAV0aHJlZQUAAAADbmlsdBcUog==`, env, true, false}, - //{`PARSEINT`, `parseInt("12345") == 12345`, `AwkAAAAAAAACCQAEtgAAAAECAAAABTEyMzQ1AAAAAAAAADA57cmovA==`, env, true, false}, - //{`PARSEINT`, `parseInt("0x12345") == unit`, `AwkAAAAAAAACCQAEtgAAAAECAAAABzB4MTIzNDUFAAAABHVuaXQvncQM`, env, true, false}, - //{`LASTINDEXOF`, `lastIndexOf("cafe bebe dead beef cafe bebe", "bebe") == 25`, `AwkAAAAAAAACCQAEtwAAAAICAAAAHWNhZmUgYmViZSBkZWFkIGJlZWYgY2FmZSBiZWJlAgAAAARiZWJlAAAAAAAAAAAZDUvNng==`, env, true, false}, - //{`LASTINDEXOF`, `lastIndexOf("cafe bebe dead beef cafe bebe", "fox") == unit`, `AwkAAAAAAAACCQAEtwAAAAICAAAAHWNhZmUgYmViZSBkZWFkIGJlZWYgY2FmZSBiZWJlAgAAAANmb3gFAAAABHVuaXSK8YYp`, env, true, false}, - //{`LASTINDEXOFN`, `lastIndexOf("cafe bebe dead beef cafe bebe", "bebe", 30) == 25`, `AwkAAAAAAAACCQAEuAAAAAMCAAAAHWNhZmUgYmViZSBkZWFkIGJlZWYgY2FmZSBiZWJlAgAAAARiZWJlAAAAAAAAAAAeAAAAAAAAAAAZus4/9A==`, env, true, false}, - //{`LASTINDEXOFN`, `lastIndexOf("cafe bebe dead beef cafe bebe", "bebe", 10) == 5`, `AwkAAAAAAAACCQAEuAAAAAMCAAAAHWNhZmUgYmViZSBkZWFkIGJlZWYgY2FmZSBiZWJlAgAAAARiZWJlAAAAAAAAAAAKAAAAAAAAAAAFrGUCxA==`, env, true, false}, - //{`LASTINDEXOFN`, `lastIndexOf("cafe bebe dead beef cafe bebe", "dead", 13) == 10`, `AwkAAAAAAAACCQAEuAAAAAMCAAAAHWNhZmUgYmViZSBkZWFkIGJlZWYgY2FmZSBiZWJlAgAAAARkZWFkAAAAAAAAAAANAAAAAAAAAAAKepNV2A==`, env, true, false}, - //{`LASTINDEXOFN`, `lastIndexOf("cafe bebe dead beef cafe bebe", "dead", 11) == 10`, `AwkAAAAAAAACCQAEuAAAAAMCAAAAHWNhZmUgYmViZSBkZWFkIGJlZWYgY2FmZSBiZWJlAgAAAARkZWFkAAAAAAAAAAALAAAAAAAAAAAKcxKwfA==`, env, true, false}, - } { - src, err := base64.StdEncoding.DecodeString(test.script) - require.NoError(t, err, test.name) - - tree, err := Parse(src) - require.NoError(t, err, test.name) - assert.NotNil(t, tree, test.name) - - script, err := Compile(tree) - require.NoError(t, err, test.name) - assert.NotNil(t, script, test.name) - - res, err := script.Run(test.env) - if test.error { - assert.Error(t, err, "No error in "+test.name) - } else { - require.NoError(t, err, "Unexpected error in: "+test.name) - assert.NotNil(t, res, test.name) - r, ok := res.(ScriptResult) - assert.True(t, ok, test.name) - assert.Equal(t, test.result, r.Result(), test.name) - } - } -} - -func BenchmarkSimplestScript(b *testing.B) { - b.ReportAllocs() - for i := 0; i < b.N; i++ { - src, err := base64.StdEncoding.DecodeString("AwZd0cYf") // V3: true - require.NoError(b, err) - tree, err := Parse(src) - require.NoError(b, err) - prg, err := Compile(tree) - require.NoError(b, err) - assert.NotNil(b, prg) - res, err := prg.Run(nil) - require.NoError(b, err) - r := res.(ScriptResult) - assert.True(b, r.Result()) - } -} - -func BenchmarkEval(b *testing.B) { - //let x = addressFromString("3PJaDyprvekvPXPuAtxrapacuDJopgJRaU3") - // - //let a = x - //let b = a - //let c = b - //let d = c - //let e = d - //let f = e - // - //f == e - - code := "AQQAAAABeAkBAAAAEWFkZHJlc3NGcm9tU3RyaW5nAAAAAQIAAAAjM1BKYUR5cHJ2ZWt2UFhQdUF0eHJhcGFjdURKb3BnSlJhVTMEAAAAAWEFAAAAAXgEAAAAAWIFAAAAAWEEAAAAAWMFAAAAAWIEAAAAAWQFAAAAAWMEAAAAAWUFAAAAAWQEAAAAAWYFAAAAAWUJAAAAAAAAAgUAAAABZgUAAAABZS5FHzs=" - b.ReportAllocs() - src, err := base64.StdEncoding.DecodeString(code) - require.NoError(b, err) - tree, err := Parse(src) - require.NoError(b, err) - prg, err := Compile(tree) - require.NoError(b, err) - assert.NotNil(b, prg) - b.ResetTimer() - for i := 0; i < b.N; i++ { - res, err := prg.Run(nil) //TODO: pass real value - require.NoError(b, err) - r := res.(ScriptResult) - assert.True(b, r.Result()) - } -} - func testTransferWithProofs() *proto.TransferWithProofs { var scheme byte = 'T' seed, err := base58.Decode("3TUPTbbpiM5UmZDhMmzdsKKNgMvyHwZQncKWfJrxk3bc") @@ -463,9 +84,17 @@ func testTransferWithProofs() *proto.TransferWithProofs { } func testTransferObject() rideObject { - obj, err := transferWithProofsToObject('T', testTransferWithProofs()) + obj, err := transferWithProofsToObject('T', byte_helpers.TransferWithProofs.Transaction) if err != nil { panic(err) } return obj } + +func testExchangeWithProofsToObject() rideObject { + obj, err := exchangeWithProofsToObject('T', byte_helpers.ExchangeWithProofs.Transaction) + if err != nil { + panic(err.Error()) + } + return obj +} diff --git a/pkg/state/api.go b/pkg/state/api.go index 3cf065327..7c9305034 100644 --- a/pkg/state/api.go +++ b/pkg/state/api.go @@ -127,6 +127,9 @@ type StateInfo interface { // ShouldPersisAddressTransactions checks if PersisAddressTransactions // should be called. ShouldPersistAddressTransactions() (bool, error) + + // Method should be used only in tests. + SmartState() types.SmartState } // StateModifier contains all the methods needed to modify node's state. diff --git a/pkg/state/common_test.go b/pkg/state/common_test.go index c23877b06..99c0b4d6d 100644 --- a/pkg/state/common_test.go +++ b/pkg/state/common_test.go @@ -377,7 +377,7 @@ func (s *testStorageObjects) createAsset(t *testing.T, assetID crypto.Digest) *a func (s *testStorageObjects) createSmartAsset(t *testing.T, assetID crypto.Digest) { s.addBlock(t, blockID0) - err := s.entities.scriptsStorage.setAssetScript(assetID, testGlobal.scriptBytes, testGlobal.senderInfo.pk, blockID0) + err := s.entities.scriptsStorage.setAssetScript(assetID, testGlobal.scriptBytes, testGlobal.senderInfo.pk, blockID0, "") assert.NoError(t, err, "setAssetScript failed") s.flush(t) } diff --git a/pkg/state/fee_validation_test.go b/pkg/state/fee_validation_test.go index f8d0c1dc7..23c537b35 100644 --- a/pkg/state/fee_validation_test.go +++ b/pkg/state/fee_validation_test.go @@ -25,7 +25,7 @@ func TestAssetScriptExtraFee(t *testing.T) { // Set script. to.stor.addBlock(t, blockID0) addr := testGlobal.senderInfo.addr - err = to.stor.entities.scriptsStorage.setAccountScript(addr, testGlobal.scriptBytes, testGlobal.senderInfo.pk, blockID0) + err = to.stor.entities.scriptsStorage.setAccountScript(addr, testGlobal.scriptBytes, testGlobal.senderInfo.pk, blockID0, "") assert.NoError(t, err) // Burn. @@ -63,7 +63,7 @@ func TestAccountScriptExtraFee(t *testing.T) { // Set script. to.stor.addBlock(t, blockID0) addr := testGlobal.senderInfo.addr - err = to.stor.entities.scriptsStorage.setAccountScript(addr, testGlobal.scriptBytes, testGlobal.senderInfo.pk, blockID0) + err = to.stor.entities.scriptsStorage.setAccountScript(addr, testGlobal.scriptBytes, testGlobal.senderInfo.pk, blockID0, "") assert.NoError(t, err) // Burn. diff --git a/pkg/state/invoke_applier.go b/pkg/state/invoke_applier.go index 7690c75c9..3dff1a430 100644 --- a/pkg/state/invoke_applier.go +++ b/pkg/state/invoke_applier.go @@ -522,6 +522,10 @@ func (ia *invokeApplier) applyInvokeScript(tx *proto.InvokeScriptWithProofs, inf if err != nil { return nil, errors.Wrap(err, "recipientToAddress() failed") } + exe, err := ia.stor.scriptsStorage.newestBytecodeByAddr(*scriptAddr, !info.initialisation) + if err != nil { + return nil, errors.Wrapf(err, "failed to instantiate script on address '%s'", scriptAddr.String()) + } tree, err := ia.stor.scriptsStorage.newestScriptByAddr(*scriptAddr, !info.initialisation) if err != nil { return nil, errors.Wrapf(err, "failed to instantiate script on address '%s'", scriptAddr.String()) @@ -532,11 +536,11 @@ func (ia *invokeApplier) applyInvokeScript(tx *proto.InvokeScriptWithProofs, inf } // Check that the script's library supports multiple payments. // We don't have to check feature activation because we done it before. - if len(tx.Payments) == 2 && tree.LibVersion < 4 { - return nil, errors.Errorf("multiple payments is not allowed for RIDE library version %d", tree.LibVersion) + if len(tx.Payments) == 2 && exe.LibVersion < 4 { + return nil, errors.Errorf("multiple payments is not allowed for RIDE library version %d", exe.LibVersion) } // Refuse payments to DApp itself since activation of BlockV5 (acceptFailed) and for DApps with StdLib V4. - disableSelfTransfers := info.acceptFailed && tree.LibVersion >= 4 + disableSelfTransfers := info.acceptFailed && exe.LibVersion >= 4 if disableSelfTransfers && len(tx.Payments) > 0 { sender, err := proto.NewAddressFromPublicKey(ia.settings.AddressSchemeCharacter, tx.SenderPK) if err != nil { @@ -554,7 +558,7 @@ func (ia *invokeApplier) applyInvokeScript(tx *proto.InvokeScriptWithProofs, inf return nil, err } // Call script function. - ok, scriptActions, err := ia.sc.invokeFunction(tree, tx, info.blockInfo, *scriptAddr, info.initialisation) + ok, scriptActions, err := ia.sc.invokeFunction(exe, tx, info.blockInfo, *scriptAddr, info.initialisation, tree) if !ok { // When ok is false, it means that we could not even start invocation. // We just return error in such case. @@ -583,7 +587,7 @@ func (ia *invokeApplier) applyInvokeScript(tx *proto.InvokeScriptWithProofs, inf actions: scriptActions, paymentSmartAssets: paymentSmartAssets, disableSelfTransfers: disableSelfTransfers, - libVersion: byte(tree.LibVersion), + libVersion: byte(exe.LibVersion), }) if err != nil { // If fallibleValidation fails, we should save transaction to blockchain when acceptFailed is true. diff --git a/pkg/state/invoke_applier_test.go b/pkg/state/invoke_applier_test.go index 2ac712466..5ee9ce776 100644 --- a/pkg/state/invoke_applier_test.go +++ b/pkg/state/invoke_applier_test.go @@ -75,7 +75,7 @@ func (to *invokeApplierTestObjects) setScript(t *testing.T, addr proto.Address, require.NoError(t, err) err = to.state.stor.scriptsComplexity.saveComplexitiesForAddr(addr, map[int]ride.TreeEstimation{1: estimation}, blockID0) assert.NoError(t, err, "failed to save complexity for address") - err = to.state.stor.scriptsStorage.setAccountScript(addr, script, pk, blockID0) + err = to.state.stor.scriptsStorage.setAccountScript(addr, script, pk, blockID0, "") assert.NoError(t, err, "failed to set account script") } diff --git a/pkg/state/script_caller.go b/pkg/state/script_caller.go index 96f44e7df..a1f2ee0ae 100644 --- a/pkg/state/script_caller.go +++ b/pkg/state/script_caller.go @@ -46,18 +46,22 @@ func (a *scriptCaller) callAccountScriptWithOrder(order proto.Order, lastBlockIn if err != nil { return errors.Wrap(err, "failed to retrieve account script") } + exe, err := a.stor.scriptsStorage.newestBytecodeByAddr(sender, !initialisation) + if err != nil { + return errors.Wrap(err, "failed to retrieve account script") + } env, err := ride.NewEnvironment(a.settings.AddressSchemeCharacter, a.state) if err != nil { return errors.Wrap(err, "failed to create RIDE environment") } env.SetThisFromAddress(sender) env.SetLastBlock(lastBlockInfo) - env.ChooseSizeCheck(tree.LibVersion) + env.ChooseSizeCheck(exe.LibVersion) err = env.SetTransactionFromOrder(order) if err != nil { return errors.Wrap(err, "failed to convert order") } - r, err := ride.CallVerifier(env, tree) + r, err := ride.CallVerifier("scriptCaller callAccountScriptWithOrder", env, tree, exe) if err != nil { return errors.Wrapf(err, "failed to call account script on order '%s'", base58.Encode(id)) } @@ -81,6 +85,11 @@ func (a *scriptCaller) callAccountScriptWithOrder(order proto.Order, lastBlockIn } func (a *scriptCaller) callAccountScriptWithTx(tx proto.Transaction, lastBlockInfo *proto.BlockInfo, initialisation bool) error { + id, err := tx.GetID(a.settings.AddressSchemeCharacter) + if err != nil { + return err + } + txID := base58.Encode(id) senderAddr, err := proto.NewAddressFromPublicKey(a.settings.AddressSchemeCharacter, tx.GetSenderPK()) if err != nil { return err @@ -89,10 +98,11 @@ func (a *scriptCaller) callAccountScriptWithTx(tx proto.Transaction, lastBlockIn if err != nil { return err } - id, err := tx.GetID(a.settings.AddressSchemeCharacter) + exe, err := a.stor.scriptsStorage.newestBytecodeByAddr(senderAddr, !initialisation) if err != nil { return err } + env, err := ride.NewEnvironment(a.settings.AddressSchemeCharacter, a.state) if err != nil { return errors.Wrapf(err, "failed to call account script on transaction '%s'", base58.Encode(id)) @@ -103,15 +113,25 @@ func (a *scriptCaller) callAccountScriptWithTx(tx proto.Transaction, lastBlockIn if err != nil { return errors.Wrapf(err, "failed to call account script on transaction '%s'", base58.Encode(id)) } - r, err := ride.CallVerifier(env, tree) + //zap.S().Debug(tx.GetID(a.settings.AddressSchemeCharacter)) + r, err := ride.CallVerifier(txID, env, tree, exe) if err != nil { return errors.Wrapf(err, "failed to call account script on transaction '%s'", base58.Encode(id)) } + + //r2, err := ride.CallVerifier2(env, tree) + //if err != nil { + // return errors.Wrapf(err, "R2: failed to call account script on transaction '%s'", base58.Encode(id)) + //} + //if !r.Eq(r2) { + // return errors.Wrapf(err, "R1 != R2: failed to call account script on transaction '%s'", base58.Encode(id)) + //} + if !r.Result() { if r.UserError() != "" { - return errors.Errorf("account script on transaction '%s' failed with error: %v", base58.Encode(id), r.UserError()) + return errors.Errorf("account script on transaction '%s' failed with error: %v", txID, r.UserError()) } - return errs.NewTransactionNotAllowedByScript("script failed", id) + return errors.Wrap(errs.NewTransactionNotAllowedByScript("script failed", id), txID) } // Increase complexity. ev, err := a.state.EstimatorVersion() @@ -131,8 +151,12 @@ func (a *scriptCaller) callAssetScriptCommon(env *ride.Environment, assetID cryp if err != nil { return nil, err } - env.ChooseSizeCheck(tree.LibVersion) - switch tree.LibVersion { + exe, err := a.stor.scriptsStorage.newestBytecodeByAsset(assetID, !initialisation) + if err != nil { + return nil, err + } + env.ChooseSizeCheck(exe.LibVersion) + switch exe.LibVersion { case 4: assetInfo, err := a.state.NewestFullAssetInfo(assetID) if err != nil { @@ -147,7 +171,7 @@ func (a *scriptCaller) callAssetScriptCommon(env *ride.Environment, assetID cryp env.SetThisFromAssetInfo(assetInfo) } env.SetLastBlock(lastBlockInfo) - r, err := ride.CallVerifier(env, tree) + r, err := ride.CallVerifier("scriptCaller callAssetScriptCommon", env, tree, exe) if err != nil { return nil, errors.Wrapf(err, "failed to call script on asset '%s'", assetID.String()) } @@ -188,7 +212,9 @@ func (a *scriptCaller) callAssetScript(tx proto.Transaction, assetID crypto.Dige return a.callAssetScriptCommon(env, assetID, lastBlockInfo, initialisation, acceptFailed) } -func (a *scriptCaller) invokeFunction(tree *ride.Tree, tx *proto.InvokeScriptWithProofs, lastBlockInfo *proto.BlockInfo, scriptAddress proto.Address, initialisation bool) (bool, []proto.ScriptAction, error) { +func (a *scriptCaller) invokeFunction(exe *ride.Executable, tx *proto.InvokeScriptWithProofs, lastBlockInfo *proto.BlockInfo, scriptAddress proto.Address, initialisation bool, tree *ride.Tree) (bool, []proto.ScriptAction, error) { + txID := tx.ID.String() + _ = txID env, err := ride.NewEnvironment(a.settings.AddressSchemeCharacter, a.state) if err != nil { return false, nil, errors.Wrap(err, "failed to create RIDE environment") @@ -199,12 +225,28 @@ func (a *scriptCaller) invokeFunction(tree *ride.Tree, tx *proto.InvokeScriptWit if err != nil { return false, nil, errors.Wrapf(err, "invocation of transaction '%s' failed", tx.ID.String()) } - err = env.SetInvoke(tx, tree.LibVersion) + err = env.SetInvoke(tx, exe.LibVersion) if err != nil { return false, nil, errors.Wrapf(err, "invocation of transaction '%s' failed", tx.ID.String()) } - env.ChooseSizeCheck(tree.LibVersion) - r, err := ride.CallFunction(env, tree, tx.FunctionCall.Name, tx.FunctionCall.Arguments) + env.ChooseSizeCheck(exe.LibVersion) + + //for i, f := range tree.Declarations { + // rs := ride.Decompiler(f) + // zap.S().Error(i, " == ", rs) + // + //} + //for i, f := range tree.Functions { + // rs := ride.Decompiler(f) + // zap.S().Error(i, " == ", rs) + //} + // + //zap.S().Error("verifier: == ", tree.Verifier) + //for i, v := range tx.FunctionCall.Arguments { + // zap.S().Errorf("%d argument %+v, %T", i, v, v) + //} + + r, err := ride.CallFunction(txID, env, exe, tree, tx.FunctionCall.Name, tx.FunctionCall.Arguments) if err != nil { return false, nil, errors.Wrapf(err, "invocation of transaction '%s' failed", tx.ID.String()) } diff --git a/pkg/state/scripts_cache.go b/pkg/state/scripts_cache.go index 2219b517f..0275fc91d 100644 --- a/pkg/state/scripts_cache.go +++ b/pkg/state/scripts_cache.go @@ -7,13 +7,11 @@ import ( type element struct { key string - value ride.Tree + value *ride.Executable prev, next *element bytes uint64 } -var defaultValue ride.Tree - type lru struct { maxSize, maxBytes, size, bytesUsed uint64 @@ -72,7 +70,7 @@ func (l *lru) del(e *element) { l.cut(e) l.size -= 1 l.bytesUsed -= e.bytes - e.value = defaultValue + e.value = nil l.removed = e } @@ -82,7 +80,7 @@ func (l *lru) makeFreeSpace(bytes uint64) { } } -func (l *lru) get(key []byte) (value ride.Tree, has bool) { +func (l *lru) get(key []byte) (value *ride.Executable, has bool) { var e *element e, has = l.m[string(key)] if !has { @@ -93,7 +91,7 @@ func (l *lru) get(key []byte) (value ride.Tree, has bool) { return e.value, true } -func (l *lru) set(key []byte, value ride.Tree, bytes uint64) (existed bool) { +func (l *lru) set(key []byte, value *ride.Executable, bytes uint64) (existed bool) { keyStr := string(key) e, has := l.m[keyStr] if has { diff --git a/pkg/state/scripts_storage.go b/pkg/state/scripts_storage.go index 49b382208..0672ad016 100644 --- a/pkg/state/scripts_storage.go +++ b/pkg/state/scripts_storage.go @@ -2,10 +2,11 @@ package state import ( "bytes" - "errors" + "encoding/binary" "io" "github.com/wavesplatform/gowaves/pkg/crypto" + "github.com/wavesplatform/gowaves/pkg/libs/deserializer" "github.com/wavesplatform/gowaves/pkg/proto" "github.com/wavesplatform/gowaves/pkg/ride" ) @@ -18,11 +19,14 @@ const ( ) func scriptBytesToTree(script proto.Script) (*ride.Tree, error) { - tree, err := ride.Parse(script) - if err != nil { - return nil, err + if len(script) == 0 { + panic("scriptBytesToTree") } - return tree, nil + return ride.Parse(script) +} + +func scriptBytesToExecutable(script proto.Script) (*ride.Executable, error) { + return ride.DeserializeExecutable(script) } type accountScripRecordForHashes struct { @@ -75,8 +79,9 @@ func scriptExists(recordBytes []byte) bool { } type scriptRecord struct { - pk crypto.PublicKey - script proto.Script + pk crypto.PublicKey + script proto.Script + bytecode []byte } func (r *scriptRecord) scriptIsEmpty() bool { @@ -84,25 +89,43 @@ func (r *scriptRecord) scriptIsEmpty() bool { } func (r *scriptRecord) marshalBinary() ([]byte, error) { - res := make([]byte, crypto.KeySize+len(r.script)) - copy(res, r.pk[:]) - copy(res[crypto.KeySize:], r.script) - return res, nil + if len(r.script) > 0 { + res := make([]byte, crypto.KeySize+len(r.script)+len(r.bytecode)+4) + copy(res, r.pk[:]) + binary.BigEndian.PutUint32(res[crypto.KeySize:], uint32(len(r.script))) + copy(res[crypto.KeySize+4:], append(r.script, r.bytecode...)) + return res, nil + } else { + return r.pk.Bytes(), nil + } } func (r *scriptRecord) unmarshalBinary(data []byte) error { - if len(data) < crypto.KeySize { - return errors.New("insufficient data for scriptRecord") + var err error + d := deserializer.NewDeserializer(data) + r.pk, err = d.PublicKey() + if err != nil { + return err + } + if d.Len() == 0 { + return nil } - pk, err := crypto.NewPublicKeyFromBytes(data[:crypto.KeySize]) + size, err := d.Uint32() if err != nil { return err } - r.pk = pk - scriptBytes := make([]byte, len(data)-crypto.KeySize) - copy(scriptBytes, data[crypto.KeySize:]) - r.script = proto.Script(scriptBytes) - return nil + r.script, err = d.Bytes(uint(size)) + if err != nil { + return err + } + r.bytecode, err = d.Bytes(uint(d.Len())) + return err + //scriptBytes := make([]byte, size) + //copy(scriptBytes, data[crypto.KeySize:]) + //r.script = scriptBytes + //data = data[size:] + //r.bytecode = common.Dup(data) + //return nil } // TODO: LRU cache for script ASTs here only makes sense at the import stage. @@ -135,7 +158,30 @@ func newScriptsStorage(hs *historyStorage, calcHashes bool) (*scriptsStorage, er }, nil } -func (ss *scriptsStorage) setScript(scriptType blockchainEntity, key []byte, record scriptRecord, blockID proto.BlockID) error { +func (ss *scriptsStorage) setScript(scriptType blockchainEntity, key []byte, record scriptRecord, blockID proto.BlockID, txID string) error { + var exe *ride.Executable + if len(record.script) > 0 { + if len(record.bytecode) == 0 { + p, err := scriptBytesToTree(record.script) + if err != nil { + return err + } + //expandedTree, err := ride.Expand(p) + //if err != nil { + // return err + //} + exe, err = ride.CompileTree("scriptsStorage setScript "+txID, p) + if err != nil { + return err + } + s := ride.NewSerializer() + err = exe.Serialize(s) + if err != nil { + return err + } + record.bytecode = s.Source() + } + } recordBytes, err := record.marshalBinary() if err != nil { return err @@ -148,11 +194,15 @@ func (ss *scriptsStorage) setScript(scriptType blockchainEntity, key []byte, rec ss.cache.deleteIfExists(key) return nil } - tree, err := scriptBytesToTree(record.script) - if err != nil { - return err + if exe == nil { + exe, err := scriptBytesToExecutable(record.script) + if err != nil { + return err + } + ss.cache.set(key, exe, scriptSize) + } else { + ss.cache.set(key, exe, scriptSize) } - ss.cache.set(key, *tree, scriptSize) return nil } @@ -193,6 +243,19 @@ func (ss *scriptsStorage) scriptAstFromRecordBytes(recordBytes []byte) (*ride.Tr return tree, record.pk, err } +func (ss *scriptsStorage) scriptExecutableFromRecordBytes(recordBytes []byte) (*ride.Executable, crypto.PublicKey, error) { + var record scriptRecord + if err := record.unmarshalBinary(recordBytes); err != nil { + return nil, crypto.PublicKey{}, err + } + if record.scriptIsEmpty() { + // Empty script = no script. + return nil, crypto.PublicKey{}, proto.ErrNotFound + } + tree, err := scriptBytesToExecutable(record.bytecode) + return tree, record.pk, err +} + func (ss *scriptsStorage) newestScriptAstByKey(key []byte, filter bool) (*ride.Tree, error) { recordBytes, err := ss.hs.newestTopEntryData(key, filter) if err != nil { @@ -202,6 +265,15 @@ func (ss *scriptsStorage) newestScriptAstByKey(key []byte, filter bool) (*ride.T return tree, err } +func (ss *scriptsStorage) newestBytecodeByKey(key []byte, filter bool) (*ride.Executable, error) { + recordBytes, err := ss.hs.newestTopEntryData(key, filter) + if err != nil { + return nil, err + } + tree, _, err := ss.scriptExecutableFromRecordBytes(recordBytes) + return tree, err +} + func (ss *scriptsStorage) scriptTreeByKey(key []byte, filter bool) (*ride.Tree, error) { recordBytes, err := ss.hs.topEntryData(key, filter) if err != nil { @@ -213,7 +285,7 @@ func (ss *scriptsStorage) scriptTreeByKey(key []byte, filter bool) (*ride.Tree, func (ss *scriptsStorage) commitUncertain(blockID proto.BlockID) error { for assetID, r := range ss.uncertainAssetScripts { - if err := ss.setAssetScript(assetID, r.script, r.pk, blockID); err != nil { + if err := ss.setAssetScript(assetID, r.script, r.pk, blockID, "commitUncertain"); err != nil { return err } } @@ -228,7 +300,7 @@ func (ss *scriptsStorage) setAssetScriptUncertain(assetID crypto.Digest, script ss.uncertainAssetScripts[assetID] = scriptRecord{pk: pk, script: script} } -func (ss *scriptsStorage) setAssetScript(assetID crypto.Digest, script proto.Script, pk crypto.PublicKey, blockID proto.BlockID) error { +func (ss *scriptsStorage) setAssetScript(assetID crypto.Digest, script proto.Script, pk crypto.PublicKey, blockID proto.BlockID, txID string) error { key := assetScriptKey{assetID} keyBytes := key.bytes() keyStr := string(keyBytes) @@ -242,7 +314,7 @@ func (ss *scriptsStorage) setAssetScript(assetID crypto.Digest, script proto.Scr return err } } - return ss.setScript(assetScript, keyBytes, record, blockID) + return ss.setScript(assetScript, keyBytes, record, blockID, txID) } func (ss *scriptsStorage) newestIsSmartAsset(assetID crypto.Digest, filter bool) bool { @@ -279,17 +351,37 @@ func (ss *scriptsStorage) newestScriptByAsset(assetID crypto.Digest, filter bool } key := assetScriptKey{assetID} keyBytes := key.bytes() - if script, has := ss.cache.get(keyBytes); has { - return &script, nil - } + //if script, has := ss.cache.get(keyBytes); has { + // return &script, nil + //} tree, err := ss.newestScriptAstByKey(keyBytes, filter) if err != nil { return nil, err } - ss.cache.set(keyBytes, *tree, scriptSize) + //ss.cache.set(keyBytes, *tree, scriptSize) return tree, nil } +func (ss *scriptsStorage) newestBytecodeByAsset(assetID crypto.Digest, filter bool) (*ride.Executable, error) { + if r, ok := ss.uncertainAssetScripts[assetID]; ok { + if r.scriptIsEmpty() { + return nil, proto.ErrNotFound + } + return scriptBytesToExecutable(r.script) + } + key := assetScriptKey{assetID} + keyBytes := key.bytes() + if script, has := ss.cache.get(keyBytes); has { + return script, nil + } + exe, err := ss.newestBytecodeByKey(keyBytes, filter) + if err != nil { + return nil, err + } + ss.cache.set(keyBytes, exe, scriptSize) + return exe, nil +} + func (ss *scriptsStorage) scriptByAsset(assetID crypto.Digest, filter bool) (*ride.Tree, error) { key := assetScriptKey{assetID} return ss.scriptTreeByKey(key.bytes(), filter) @@ -305,7 +397,7 @@ func (ss *scriptsStorage) newestScriptBytesByAsset(assetID crypto.Digest, filter return ss.newestScriptBytesByKey(key.bytes(), filter) } -func (ss *scriptsStorage) setAccountScript(addr proto.Address, script proto.Script, pk crypto.PublicKey, blockID proto.BlockID) error { +func (ss *scriptsStorage) setAccountScript(addr proto.Address, script proto.Script, pk crypto.PublicKey, blockID proto.BlockID, txID string) error { key := accountScriptKey{addr} keyBytes := key.bytes() keyStr := string(keyBytes) @@ -319,7 +411,7 @@ func (ss *scriptsStorage) setAccountScript(addr proto.Address, script proto.Scri return err } } - return ss.setScript(accountScript, keyBytes, record, blockID) + return ss.setScript(accountScript, keyBytes, record, blockID, txID) } func (ss *scriptsStorage) newestAccountHasVerifier(addr proto.Address, filter bool) (bool, error) { @@ -370,14 +462,20 @@ func (ss *scriptsStorage) accountHasScript(addr proto.Address, filter bool) (boo func (ss *scriptsStorage) newestScriptByAddr(addr proto.Address, filter bool) (*ride.Tree, error) { key := accountScriptKey{addr} keyBytes := key.bytes() - if tree, has := ss.cache.get(keyBytes); has { - return &tree, nil - } tree, err := ss.newestScriptAstByKey(keyBytes, filter) if err != nil { return nil, err } - ss.cache.set(keyBytes, *tree, scriptSize) + return tree, nil +} + +func (ss *scriptsStorage) newestBytecodeByAddr(addr proto.Address, filter bool) (*ride.Executable, error) { + key := accountScriptKey{addr} + keyBytes := key.bytes() + tree, err := ss.newestBytecodeByKey(keyBytes, filter) + if err != nil { + return nil, err + } return tree, nil } diff --git a/pkg/state/scripts_storage_test.go b/pkg/state/scripts_storage_test.go index 184ad072a..e8e67f7e4 100644 --- a/pkg/state/scripts_storage_test.go +++ b/pkg/state/scripts_storage_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/wavesplatform/gowaves/pkg/proto" "github.com/wavesplatform/gowaves/pkg/util/common" ) @@ -38,7 +39,7 @@ func TestSetAccountScript(t *testing.T) { to.stor.addBlock(t, blockID0) addr := testGlobal.senderInfo.addr - err = to.scriptsStorage.setAccountScript(addr, testGlobal.scriptBytes, testGlobal.senderInfo.pk, blockID0) + err = to.scriptsStorage.setAccountScript(addr, testGlobal.scriptBytes, testGlobal.senderInfo.pk, blockID0, "") assert.NoError(t, err, "setAccountScript() failed") // Test newest before flushing. @@ -82,12 +83,12 @@ func TestSetAccountScript(t *testing.T) { accountHasVerifier, err = to.scriptsStorage.accountHasVerifier(addr, true) assert.NoError(t, err, "accountHasVerifier() failed") assert.Equal(t, true, accountHasVerifier) - scriptAst, err = to.scriptsStorage.scriptByAddr(addr, true) + scriptAst2, err := to.scriptsStorage.scriptByAddr(addr, true) assert.NoError(t, err, "scriptByAddr() failed after flushing") - assert.Equal(t, testGlobal.scriptAst, scriptAst) + assert.Equal(t, testGlobal.scriptAst, scriptAst2) // Test discarding script. - err = to.scriptsStorage.setAccountScript(addr, proto.Script{}, testGlobal.senderInfo.pk, blockID0) + err = to.scriptsStorage.setAccountScript(addr, proto.Script{}, testGlobal.senderInfo.pk, blockID0, "") assert.NoError(t, err, "setAccountScript() failed") // Test newest before flushing. @@ -107,9 +108,9 @@ func TestSetAccountScript(t *testing.T) { accountHasVerifier, err = to.scriptsStorage.accountHasVerifier(addr, true) assert.NoError(t, err, "accountHasVerifier() failed") assert.Equal(t, true, accountHasVerifier) - scriptAst, err = to.scriptsStorage.scriptByAddr(addr, true) + scriptAst3, err := to.scriptsStorage.scriptByAddr(addr, true) assert.NoError(t, err) - assert.Equal(t, testGlobal.scriptAst, scriptAst) + assert.Equal(t, testGlobal.scriptAst, scriptAst3) to.stor.flush(t) @@ -147,7 +148,7 @@ func TestSetAssetScript(t *testing.T) { to.stor.addBlock(t, blockID0) assetID := testGlobal.asset0.asset.ID - err = to.scriptsStorage.setAssetScript(assetID, testGlobal.scriptBytes, testGlobal.senderInfo.pk, blockID0) + err = to.scriptsStorage.setAssetScript(assetID, testGlobal.scriptBytes, testGlobal.senderInfo.pk, blockID0, "") assert.NoError(t, err, "setAssetScript() failed") // Test newest before flushing. @@ -177,12 +178,12 @@ func TestSetAssetScript(t *testing.T) { isSmartAsset, err = to.scriptsStorage.isSmartAsset(assetID, true) assert.NoError(t, err, "isSmartAsset() failed") assert.Equal(t, true, isSmartAsset) - scriptAst, err = to.scriptsStorage.scriptByAsset(assetID, true) + scriptAst2, err := to.scriptsStorage.scriptByAsset(assetID, true) assert.NoError(t, err, "scriptByAsset() failed after flushing") - assert.Equal(t, testGlobal.scriptAst, scriptAst) + assert.Equal(t, testGlobal.scriptAst, scriptAst2) // Test discarding script. - err = to.scriptsStorage.setAssetScript(assetID, proto.Script{}, testGlobal.senderInfo.pk, blockID0) + err = to.scriptsStorage.setAssetScript(assetID, proto.Script{}, testGlobal.senderInfo.pk, blockID0, "") assert.NoError(t, err, "setAssetScript() failed") // Test newest before flushing. @@ -195,9 +196,9 @@ func TestSetAssetScript(t *testing.T) { isSmartAsset, err = to.scriptsStorage.isSmartAsset(assetID, true) assert.NoError(t, err, "isSmartAsset() failed") assert.Equal(t, true, isSmartAsset) - scriptAst, err = to.scriptsStorage.scriptByAsset(assetID, true) + scriptAst2, err = to.scriptsStorage.scriptByAsset(assetID, true) assert.NoError(t, err) - assert.Equal(t, testGlobal.scriptAst, scriptAst) + assert.Equal(t, testGlobal.scriptAst, scriptAst2) to.stor.flush(t) @@ -245,3 +246,18 @@ func TestSetAssetScript(t *testing.T) { assert.NoError(t, err) assert.Equal(t, testGlobal.scriptAst, scriptAst) } + +func TestScriptRecord(t *testing.T) { + kp, _ := proto.NewKeyPair([]byte("test")) + r := scriptRecord{ + pk: kp.Public, + script: []byte{1, 2, 3}, + bytecode: []byte{4, 5, 6}, + } + bytes, _ := r.marshalBinary() + + r2 := scriptRecord{} + _ = r2.unmarshalBinary(bytes) + + require.Equal(t, r, r2) +} diff --git a/pkg/state/state.go b/pkg/state/state.go index e9ca0a9e5..6bf1fa2ac 100644 --- a/pkg/state/state.go +++ b/pkg/state/state.go @@ -4,6 +4,7 @@ import ( "context" "encoding/base64" "fmt" + "github.com/wavesplatform/gowaves/pkg/types" "math/big" "os" "path/filepath" @@ -354,6 +355,10 @@ type stateManager struct { newBlocks *newBlocks } +func (s *stateManager) SmartState() types.SmartState { + return s +} + func newStateManager(dataDir string, params StateParams, settings *settings.BlockchainSettings) (*stateManager, error) { err := validateSettings(settings) if err != nil { diff --git a/pkg/state/threadsafe_wrapper.go b/pkg/state/threadsafe_wrapper.go index 0fd4cffd1..cf22386b9 100644 --- a/pkg/state/threadsafe_wrapper.go +++ b/pkg/state/threadsafe_wrapper.go @@ -1,6 +1,7 @@ package state import ( + "github.com/wavesplatform/gowaves/pkg/types" "math/big" "sync" "sync/atomic" @@ -21,6 +22,10 @@ func (a *ThreadSafeReadWrapper) HitSourceAtHeight(height proto.Height) ([]byte, return a.s.HitSourceAtHeight(height) } +func (a *ThreadSafeReadWrapper) SmartState() types.SmartState { + return a.s.SmartState() +} + func (a *ThreadSafeReadWrapper) MapR(f func(StateInfo) (interface{}, error)) (interface{}, error) { a.mu.RLock() defer a.mu.RUnlock() diff --git a/pkg/state/transaction_checker.go b/pkg/state/transaction_checker.go index 5ee0c51b4..7de8552e9 100644 --- a/pkg/state/transaction_checker.go +++ b/pkg/state/transaction_checker.go @@ -99,7 +99,7 @@ func (tc *transactionChecker) checkScriptComplexity(tree *ride.Tree, estimation } func (tc *transactionChecker) checkScript(script proto.Script, estimatorVersion int) (map[int]ride.TreeEstimation, error) { - tree, err := ride.Parse(script) + tree, err := scriptBytesToTree(script) if err != nil { return nil, errs.Extend(err, "failed to build AST") } @@ -979,7 +979,7 @@ func (tc *transactionChecker) checkSetScriptWithProofs(transaction proto.Transac return nil, err } if len(tx.Script) == 0 { - // No script checks / actions are needed. + // No script checks/actions are needed. if err := tc.stor.scriptsComplexity.saveComplexitiesForAddr(addr, nil, info.blockID); err != nil { return nil, err } diff --git a/pkg/state/transaction_checker_test.go b/pkg/state/transaction_checker_test.go index 52f3aec90..64e7518fd 100644 --- a/pkg/state/transaction_checker_test.go +++ b/pkg/state/transaction_checker_test.go @@ -458,7 +458,7 @@ func TestCheckExchangeWithSig(t *testing.T) { // Set script. to.stor.addBlock(t, blockID0) addr := testGlobal.recipientInfo.addr - err = to.stor.entities.scriptsStorage.setAccountScript(addr, testGlobal.scriptBytes, testGlobal.recipientInfo.pk, blockID0) + err = to.stor.entities.scriptsStorage.setAccountScript(addr, testGlobal.scriptBytes, testGlobal.recipientInfo.pk, blockID0, "") assert.NoError(t, err) _, err = to.tc.checkExchangeWithSig(tx, info) @@ -1052,7 +1052,7 @@ func TestCheckSetAssetScriptWithProofs(t *testing.T) { assert.Error(t, err, "checkSetAssetScriptWithProofs did not fail with non-smart asset") // Make it smart. - err = to.stor.entities.scriptsStorage.setAssetScript(tx.AssetID, tx.Script, tx.SenderPK, blockID0) + err = to.stor.entities.scriptsStorage.setAssetScript(tx.AssetID, tx.Script, tx.SenderPK, blockID0, "") assert.NoError(t, err, "setAssetScript failed") // Now should pass. diff --git a/pkg/state/transaction_performer.go b/pkg/state/transaction_performer.go index d4e9216f2..a7f46c0d9 100644 --- a/pkg/state/transaction_performer.go +++ b/pkg/state/transaction_performer.go @@ -3,6 +3,7 @@ package state import ( "math/big" + "github.com/mr-tron/base58/base58" "github.com/pkg/errors" "github.com/wavesplatform/gowaves/pkg/crypto" "github.com/wavesplatform/gowaves/pkg/proto" @@ -59,7 +60,7 @@ func (tp *transactionPerformer) performIssueWithSig(transaction proto.Transactio if err != nil { return err } - if err := tp.stor.scriptsStorage.setAssetScript(assetID, proto.Script{}, tx.SenderPK, info.blockID); err != nil { + if err := tp.stor.scriptsStorage.setAssetScript(assetID, proto.Script{}, tx.SenderPK, info.blockID, "performIssueWithSig"); err != nil { return err } return tp.performIssue(&tx.Issue, assetID, info) @@ -78,7 +79,7 @@ func (tp *transactionPerformer) performIssueWithProofs(transaction proto.Transac if err != nil { return err } - if err := tp.stor.scriptsStorage.setAssetScript(assetID, tx.Script, tx.SenderPK, info.blockID); err != nil { + if err := tp.stor.scriptsStorage.setAssetScript(assetID, tx.Script, tx.SenderPK, info.blockID, "performIssueWithProofs"); err != nil { return err } return tp.performIssue(&tx.Issue, assetID, info) @@ -305,11 +306,16 @@ func (tp *transactionPerformer) performSetScriptWithProofs(transaction proto.Tra if !ok { return errors.New("failed to convert interface to SetScriptWithProofs transaction") } + txIDbytes, err := tx.GetID(tp.settings.AddressSchemeCharacter) + if err != nil { + return err + } + txID := base58.Encode(txIDbytes) senderAddr, err := proto.NewAddressFromPublicKey(tp.settings.AddressSchemeCharacter, tx.SenderPK) if err != nil { return err } - if err := tp.stor.scriptsStorage.setAccountScript(senderAddr, tx.Script, tx.SenderPK, info.blockID); err != nil { + if err := tp.stor.scriptsStorage.setAccountScript(senderAddr, tx.Script, tx.SenderPK, info.blockID, txID); err != nil { return errors.Wrap(err, "failed to set account script") } return nil @@ -320,7 +326,7 @@ func (tp *transactionPerformer) performSetAssetScriptWithProofs(transaction prot if !ok { return errors.New("failed to convert interface to SetAssetScriptWithProofs transaction") } - if err := tp.stor.scriptsStorage.setAssetScript(tx.AssetID, tx.Script, tx.SenderPK, info.blockID); err != nil { + if err := tp.stor.scriptsStorage.setAssetScript(tx.AssetID, tx.Script, tx.SenderPK, info.blockID, "performSetAssetScriptWithProofs"); err != nil { return errors.Wrap(err, "failed to set asset script") } return nil diff --git a/pkg/state/transaction_performer_test.go b/pkg/state/transaction_performer_test.go index 3966be521..39be2dc32 100644 --- a/pkg/state/transaction_performer_test.go +++ b/pkg/state/transaction_performer_test.go @@ -608,7 +608,7 @@ func TestPerformSetAssetScriptWithProofs(t *testing.T) { assert.Equal(t, testGlobal.scriptAst, scriptAst) // Test discarding script. - err = to.stor.entities.scriptsStorage.setAssetScript(assetID, proto.Script{}, crypto.PublicKey{}, blockID0) + err = to.stor.entities.scriptsStorage.setAssetScript(assetID, proto.Script{}, crypto.PublicKey{}, blockID0, "") assert.NoError(t, err, "setAssetScript() failed") // Test newest before flushing.