diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index dffc9e42d..390c52c5a 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -41,6 +41,13 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 + - name: Set up Go 1.21 + uses: actions/setup-go@v5.0.0 + with: + go-version: 1.21.x + check-latest: true + cache: true + # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL uses: github/codeql-action/init@v3 diff --git a/cmd/snapshotsreader/snapshots_reader.go b/cmd/snapshotsreader/snapshots_reader.go new file mode 100644 index 000000000..cda21b62c --- /dev/null +++ b/cmd/snapshotsreader/snapshots_reader.go @@ -0,0 +1,126 @@ +package main + +import ( + "bufio" + "encoding/binary" + "encoding/json" + "errors" + "flag" + "fmt" + "io" + "os" + + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + + "github.com/wavesplatform/gowaves/pkg/logging" + "github.com/wavesplatform/gowaves/pkg/proto" + "github.com/wavesplatform/gowaves/pkg/settings" +) + +const ( + snapshotsByteSize = 4 +) + +type SnapshotAtHeight struct { + Height proto.Height `json:"height"` + BlockSnapshot proto.BlockSnapshot `json:"blockSnapshot"` +} + +func parseSnapshots(start, end uint64, snapshotsBody io.Reader, scheme proto.Scheme) []SnapshotAtHeight { + var buf []byte + snapshotsSizeBytes := make([]byte, snapshotsByteSize) + var blocksSnapshots []SnapshotAtHeight + for height := uint64(2); height < end; height++ { + if _, readBerr := io.ReadFull(snapshotsBody, snapshotsSizeBytes); readBerr != nil { + zap.S().Fatalf("failed to read the snapshots size in block: %v", readBerr) + } + snapshotsSize := binary.BigEndian.Uint32(snapshotsSizeBytes) + if snapshotsSize == 0 { // add empty block snapshot + if height >= start { + blocksSnapshots = append(blocksSnapshots, SnapshotAtHeight{ + Height: height, + BlockSnapshot: proto.BlockSnapshot{}, + }) + } + continue + } + + if cap(buf) < int(snapshotsSize) { + buf = make([]byte, snapshotsSize) + } + buf = buf[:snapshotsSize] + + if _, readRrr := io.ReadFull(snapshotsBody, buf); readRrr != nil { + zap.S().Fatalf("failed to read the snapshots in block: %v", readRrr) + } + if height < start { + continue + } + + snapshotsInBlock := proto.BlockSnapshot{} + unmrshlErr := snapshotsInBlock.UnmarshalBinaryImport(buf, scheme) + if unmrshlErr != nil { + zap.S().Fatalf("failed to unmarshal snapshots in block: %v", unmrshlErr) + } + blocksSnapshots = append(blocksSnapshots, SnapshotAtHeight{ + Height: height, + BlockSnapshot: snapshotsInBlock, + }) + } + return blocksSnapshots +} + +func main() { + var ( + logLevel = zap.LevelFlag("log-level", zapcore.InfoLevel, + "Logging level. Supported levels: DEBUG, INFO, WARN, ERROR, FATAL. Default logging level INFO.") + blockchainType = flag.String("blockchain-type", "mainnet", + "Blockchain type. Allowed values: mainnet/testnet/stagenet. Default is 'mainnet'.") + snapshotsPath = flag.String("snapshots-path", "", "Path to binary blockchain file.") + blocksStart = flag.Uint64("blocks-start", 0, + "Start block number. Should be greater than 1, because the snapshots file doesn't include genesis.") + nBlocks = flag.Uint64("blocks-number", 1, "Number of blocks to read since 'blocks-start'.") + ) + flag.Parse() + + logger := logging.SetupSimpleLogger(*logLevel) + defer func() { + err := logger.Sync() + if err != nil && errors.Is(err, os.ErrInvalid) { + panic(fmt.Sprintf("failed to close logging subsystem: %v\n", err)) + } + }() + if *snapshotsPath == "" { + zap.S().Fatalf("You must specify snapshots-path option.") + } + if *blocksStart < 2 { + zap.S().Fatalf("'blocks-start' must be greater than 1.") + } + + ss, err := settings.BlockchainSettingsByTypeName(*blockchainType) + if err != nil { + zap.S().Fatalf("failed to load blockchain settings: %v", err) + } + + snapshotsBody, err := os.Open(*snapshotsPath) + if err != nil { + zap.S().Fatalf("failed to open snapshots file, %v", err) + } + defer func(snapshotsBody *os.File) { + if clErr := snapshotsBody.Close(); clErr != nil { + zap.S().Fatalf("failed to close snapshots file, %v", clErr) + } + }(snapshotsBody) + const mb = 1 << 20 + var ( + start = *blocksStart + end = start + *nBlocks + ) + blocksSnapshots := parseSnapshots(start, end, bufio.NewReaderSize(snapshotsBody, mb), ss.AddressSchemeCharacter) + data, err := json.Marshal(blocksSnapshots) + if err != nil { + zap.S().Fatalf("failed to marshal blocksSnapshots: %v", err) + } + fmt.Println(string(data)) //nolint:forbidigo // it's a command-line tool +} diff --git a/go.mod b/go.mod index ce338d3a6..bd4a7cfbe 100644 --- a/go.mod +++ b/go.mod @@ -26,7 +26,7 @@ require ( github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.18.0 - github.com/qmuntal/stateless v1.6.8 + github.com/qmuntal/stateless v1.6.9 github.com/seiflotfy/cuckoofilter v0.0.0-20201222105146-bc6005554a0c github.com/semrush/zenrpc/v2 v2.1.1 github.com/spf13/afero v1.11.0 @@ -43,12 +43,12 @@ require ( github.com/valyala/bytebufferpool v1.0.0 github.com/xenolf/lego v2.7.2+incompatible go.uber.org/atomic v1.11.0 - go.uber.org/zap v1.26.0 - golang.org/x/crypto v0.19.0 + go.uber.org/zap v1.27.0 + golang.org/x/crypto v0.20.0 golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 golang.org/x/sync v0.6.0 golang.org/x/sys v0.17.0 - google.golang.org/grpc v1.61.1 + google.golang.org/grpc v1.62.0 google.golang.org/protobuf v1.32.0 gopkg.in/natefinch/lumberjack.v2 v2.2.1 moul.io/zapfilter v1.7.0 @@ -105,11 +105,11 @@ require ( github.com/xeipuuv/gojsonschema v1.2.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.19.0 // indirect + golang.org/x/net v0.21.0 // indirect golang.org/x/term v0.17.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect rsc.io/tmplfunc v0.0.3 // indirect diff --git a/go.sum b/go.sum index 668b7c87b..a8faa05bf 100644 --- a/go.sum +++ b/go.sum @@ -232,8 +232,8 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= -github.com/qmuntal/stateless v1.6.8 h1:FFtK4eVFg59hupskooMg2MxDvW325KtHjiuXiaFHeRQ= -github.com/qmuntal/stateless v1.6.8/go.mod h1:n1HjRBM/cq4uCr3rfUjaMkgeGcd+ykAZwkjLje6jGBM= +github.com/qmuntal/stateless v1.6.9 h1:o2QDpwq8bF6n1DN8rKe8c4HZoVaUoF0rmQgihL/dMwA= +github.com/qmuntal/stateless v1.6.9/go.mod h1:n1HjRBM/cq4uCr3rfUjaMkgeGcd+ykAZwkjLje6jGBM= github.com/redis/go-redis/v9 v9.0.5/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= @@ -320,22 +320,22 @@ go.uber.org/atomic v1.8.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.20.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg= +golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ= golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -361,8 +361,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -434,10 +434,10 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f h1:ultW7fxlIvee4HYrtnaRPon9HpEgFk5zYpmfMgtKB5I= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc= -google.golang.org/grpc v1.61.1 h1:kLAiWrZs7YeDM6MumDe7m3y4aM6wacLzM1Y/wiLP9XY= -google.golang.org/grpc v1.61.1/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 h1:AjyfHzEPEFp/NpvfN5g+KDla3EMojjhRVZc1i7cj+oM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s= +google.golang.org/grpc v1.62.0 h1:HQKZ/fa1bXkX1oFOvSjmZEUL8wLSaZTjCcLAlmZRtdk= +google.golang.org/grpc v1.62.0/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/pkg/miner/utxpool/pool_test.go b/pkg/miner/utxpool/pool_test.go index 0c8336b92..f112d2423 100644 --- a/pkg/miner/utxpool/pool_test.go +++ b/pkg/miner/utxpool/pool_test.go @@ -95,6 +95,10 @@ func (a transaction) GetFee() uint64 { return a.fee } +func (a transaction) GetFeeAsset() proto.OptionalAsset { + return proto.NewOptionalAssetWaves() +} + func (a transaction) GetSenderPK() crypto.PublicKey { panic("not implemented") } diff --git a/pkg/proto/block_snapshot.go b/pkg/proto/block_snapshot.go index 174d0fd44..03ce2a229 100644 --- a/pkg/proto/block_snapshot.go +++ b/pkg/proto/block_snapshot.go @@ -68,6 +68,38 @@ func (bs *BlockSnapshot) UnmarshalBinary(data []byte, scheme Scheme) error { return nil } +func (bs *BlockSnapshot) UnmarshalBinaryImport(data []byte, scheme Scheme) error { + snapshotsBytesSize := len(data) + var txSnapshots [][]AtomicSnapshot + for i := uint32(0); snapshotsBytesSize > 0; i++ { + if len(data) < uint32Size { + return errors.Errorf("BlockSnapshot UnmarshallBinary: invalid data size") + } + oneSnapshotSize := binary.BigEndian.Uint32(data[0:uint32Size]) + var tsProto g.TransactionStateSnapshot + data = data[uint32Size:] // skip size + if uint32(len(data)) < oneSnapshotSize { + return errors.Errorf("BlockSnapshot UnmarshallBinary: invalid snapshot size") + } + err := tsProto.UnmarshalVT(data[0:oneSnapshotSize]) + if err != nil { + return err + } + atomicTS, err := TxSnapshotsFromProtobuf(scheme, &tsProto) + if err != nil { + return err + } + txSnapshots = append(txSnapshots, atomicTS) + data = data[oneSnapshotSize:] + snapshotsBytesSize = snapshotsBytesSize - int(oneSnapshotSize) - uint32Size + } + if snapshotsBytesSize != 0 { // check that all bytes were read + return errors.Errorf("BlockSnapshot UnmarshallBinary: invalid snapshots size") + } + bs.TxSnapshots = txSnapshots + return nil +} + func (bs BlockSnapshot) MarshalJSON() ([]byte, error) { if len(bs.TxSnapshots) == 0 { return []byte("[]"), nil diff --git a/pkg/proto/eth_transaction.go b/pkg/proto/eth_transaction.go index ab956592e..79e2eb348 100644 --- a/pkg/proto/eth_transaction.go +++ b/pkg/proto/eth_transaction.go @@ -280,6 +280,10 @@ func (tx *EthereumTransaction) GetFee() uint64 { return tx.Gas() } +func (tx *EthereumTransaction) GetFeeAsset() OptionalAsset { + return NewOptionalAssetWaves() +} + func (tx *EthereumTransaction) GetTimestamp() uint64 { return tx.Nonce() } diff --git a/pkg/proto/microblock.go b/pkg/proto/microblock.go index af006610a..b969c6051 100644 --- a/pkg/proto/microblock.go +++ b/pkg/proto/microblock.go @@ -219,6 +219,12 @@ func (a *MicroBlock) WriteWithoutSignature(scheme Scheme, w io.Writer) (int64, e // Write transactions bytes s.Bytes(txsBuf.Bytes()) s.Bytes(a.SenderPK.Bytes()) + // Write state hash if it's present + var stateHash []byte + if sh, present := a.GetStateHash(); present { + stateHash = sh.Bytes() + } + s.Bytes(stateHash) return s.N(), nil } diff --git a/pkg/proto/microblock_test.go b/pkg/proto/microblock_test.go index 4ef469444..8ef91cac7 100644 --- a/pkg/proto/microblock_test.go +++ b/pkg/proto/microblock_test.go @@ -7,6 +7,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/wavesplatform/gowaves/pkg/crypto" ) @@ -155,3 +156,16 @@ func TestMicroBlockV5VerifySignature(t *testing.T) { require.NoError(t, err) assert.True(t, ok) } + +func TestMicroBlockV5VerifySignatureWithFilledStateHash(t *testing.T) { + b, err := base64.StdEncoding.DecodeString("CqIDCAUSIOk/LLkzAI1fKhFkEpSLKSTpQbL0mbZ0MfqD+fPosnzqGkBicWtO7M/qZMDCefUpa/cFwtFaLzjGA7umJ0A/C+op5PlTM0fHl6TNzNGKPHTBUWRBda3KdTzfs1crhf3MMCkHIiBwUsMLcs1y9+uFb8o4smXf5Z8IgXE9nDOO7wjJvVYfJCr1ARJA54FMEFCehlwooxG7oai66tSarbLABgVpg1/6vvnjuatF/5Hw2b6xImQ8AkEHPRlQfaG7lnWiJhxKCz2DEQXLCQqwAQhTEiDccMcuB9sSU7lrzTHdWHMPLXzY0fjRIqS5pnIg6y/7NxoEEKDCHiCIiKTH3jEoAqIHegoWChSdehPEUYH4VAnEEKfxeXrM8DevhhJgAQkBAAAAC2FwcGVuZEJsb2NrAAAAAgEAAAAgLfHmO80M5E9Zxq9HifKAmTsoWJBaNklsTc+J5hKQiz0BAAAAIB7q/lbnRFXHsf8Cz6or7P6nhNFxwwq/K5rWrgtxxH9LMiD3SCw4ghE0v3CGnerhAqfzxjpIECncD+QPE22N77bjMhJAcWZaiEE9TS/8NzaMTPvEalv5sp3aMdqo2XlZs+xbGHb+4RmRdTGjU1jgAqt+ZDmz3ZjSYfrXsNy9LUowzEjQDBogvnp/dU93K1XLzUmjnQMTz4Jcz1bXWSnH/bsbLJNe3HY=") //nolint:lll + require.NoError(t, err) + micro := new(MicroBlock) + err = micro.UnmarshalFromProtobuf(b) + require.NoError(t, err) + _, present := micro.GetStateHash() + require.True(t, present) + ok, err := micro.VerifySignature(StageNetScheme) + require.NoError(t, err) + assert.True(t, ok) +} diff --git a/pkg/proto/transactions.go b/pkg/proto/transactions.go index f5cdbac73..56f8a7a4f 100644 --- a/pkg/proto/transactions.go +++ b/pkg/proto/transactions.go @@ -10,6 +10,7 @@ import ( "strings" "github.com/pkg/errors" + "github.com/wavesplatform/gowaves/pkg/crypto" "github.com/wavesplatform/gowaves/pkg/errs" g "github.com/wavesplatform/gowaves/pkg/grpc/generated/waves" @@ -194,6 +195,7 @@ type Transaction interface { GetID(scheme Scheme) ([]byte, error) GetSender(scheme Scheme) (Address, error) GetFee() uint64 + GetFeeAsset() OptionalAsset GetTimestamp() uint64 // Validate checks that all transaction fields are valid. @@ -516,6 +518,10 @@ func (tx Genesis) GetFee() uint64 { return 0 } +func (tx Genesis) GetFeeAsset() OptionalAsset { + return NewOptionalAssetWaves() +} + func (tx Genesis) GetTimestamp() uint64 { return tx.Timestamp } @@ -766,6 +772,10 @@ func (tx Payment) GetFee() uint64 { return tx.Fee } +func (tx Payment) GetFeeAsset() OptionalAsset { + return NewOptionalAssetWaves() +} + func (tx Payment) GetTimestamp() uint64 { return tx.Timestamp } @@ -1026,6 +1036,10 @@ func (i Issue) GetFee() uint64 { return i.Fee } +func (i Issue) GetFeeAsset() OptionalAsset { + return NewOptionalAssetWaves() +} + func (i Issue) GetTimestamp() uint64 { return i.Timestamp } @@ -1153,6 +1167,10 @@ func (tr Transfer) GetFee() uint64 { return tr.Fee } +func (tr Transfer) GetFeeAsset() OptionalAsset { + return tr.FeeAsset +} + func (tr Transfer) GetTimestamp() uint64 { return tr.Timestamp } @@ -1354,6 +1372,10 @@ func (r Reissue) GetFee() uint64 { return r.Fee } +func (r Reissue) GetFeeAsset() OptionalAsset { + return NewOptionalAssetWaves() +} + func (r Reissue) GetTimestamp() uint64 { return r.Timestamp } @@ -1443,6 +1465,10 @@ func (b Burn) GetFee() uint64 { return b.Fee } +func (b Burn) GetFeeAsset() OptionalAsset { + return NewOptionalAssetWaves() +} + func (b Burn) GetTimestamp() uint64 { return b.Timestamp } @@ -1541,6 +1567,10 @@ func (l Lease) GetFee() uint64 { return l.Fee } +func (l Lease) GetFeeAsset() OptionalAsset { + return NewOptionalAssetWaves() +} + func (l Lease) GetTimestamp() uint64 { return l.Timestamp } @@ -1646,6 +1676,10 @@ func (lc LeaseCancel) GetFee() uint64 { return lc.Fee } +func (lc LeaseCancel) GetFeeAsset() OptionalAsset { + return NewOptionalAssetWaves() +} + func (lc LeaseCancel) GetTimestamp() uint64 { return lc.Timestamp } @@ -1716,6 +1750,10 @@ func (ca CreateAlias) GetFee() uint64 { return ca.Fee } +func (ca CreateAlias) GetFeeAsset() OptionalAsset { + return NewOptionalAssetWaves() +} + func (ca CreateAlias) GetTimestamp() uint64 { return ca.Timestamp } diff --git a/pkg/proto/transactions_with_proofs.go b/pkg/proto/transactions_with_proofs.go index adafd947f..24c50c14d 100644 --- a/pkg/proto/transactions_with_proofs.go +++ b/pkg/proto/transactions_with_proofs.go @@ -1395,10 +1395,15 @@ func (tx ExchangeWithProofs) GetBuyMatcherFee() uint64 { func (tx ExchangeWithProofs) GetSellMatcherFee() uint64 { return tx.SellMatcherFee } + func (tx ExchangeWithProofs) GetFee() uint64 { return tx.Fee } +func (tx ExchangeWithProofs) GetFeeAsset() OptionalAsset { + return NewOptionalAssetWaves() +} + func (tx ExchangeWithProofs) GetTimestamp() uint64 { return tx.Timestamp } @@ -2748,6 +2753,10 @@ func (tx MassTransferWithProofs) GetFee() uint64 { return tx.Fee } +func (tx MassTransferWithProofs) GetFeeAsset() OptionalAsset { + return NewOptionalAssetWaves() +} + func (tx MassTransferWithProofs) GetTimestamp() uint64 { return tx.Timestamp } @@ -3132,6 +3141,10 @@ func (tx DataWithProofs) GetFee() uint64 { return tx.Fee } +func (tx DataWithProofs) GetFeeAsset() OptionalAsset { + return NewOptionalAssetWaves() +} + func (tx DataWithProofs) GetTimestamp() uint64 { return tx.Timestamp } @@ -3514,6 +3527,10 @@ func (tx SetScriptWithProofs) GetFee() uint64 { return tx.Fee } +func (tx SetScriptWithProofs) GetFeeAsset() OptionalAsset { + return NewOptionalAssetWaves() +} + func (tx SetScriptWithProofs) GetTimestamp() uint64 { return tx.Timestamp } @@ -3808,6 +3825,10 @@ func (tx SponsorshipWithProofs) GetFee() uint64 { return tx.Fee } +func (tx SponsorshipWithProofs) GetFeeAsset() OptionalAsset { + return NewOptionalAssetWaves() +} + func (tx SponsorshipWithProofs) GetTimestamp() uint64 { return tx.Timestamp } @@ -4095,6 +4116,10 @@ func (tx SetAssetScriptWithProofs) GetFee() uint64 { return tx.Fee } +func (tx SetAssetScriptWithProofs) GetFeeAsset() OptionalAsset { + return NewOptionalAssetWaves() +} + func (tx SetAssetScriptWithProofs) GetTimestamp() uint64 { return tx.Timestamp } @@ -4403,6 +4428,10 @@ func (tx InvokeScriptWithProofs) GetFee() uint64 { return tx.Fee } +func (tx InvokeScriptWithProofs) GetFeeAsset() OptionalAsset { + return tx.FeeAsset +} + func (tx InvokeScriptWithProofs) GetTimestamp() uint64 { return tx.Timestamp } @@ -4780,6 +4809,10 @@ func (tx UpdateAssetInfoWithProofs) GetFee() uint64 { return tx.Fee } +func (tx UpdateAssetInfoWithProofs) GetFeeAsset() OptionalAsset { + return tx.FeeAsset +} + func (tx UpdateAssetInfoWithProofs) GetTimestamp() uint64 { return tx.Timestamp } @@ -4994,6 +5027,10 @@ func (tx InvokeExpressionTransactionWithProofs) GetFee() uint64 { return tx.Fee } +func (tx InvokeExpressionTransactionWithProofs) GetFeeAsset() OptionalAsset { + return tx.FeeAsset +} + func (tx InvokeExpressionTransactionWithProofs) GetTimestamp() uint64 { return tx.Timestamp } diff --git a/pkg/proto/transactions_with_sig.go b/pkg/proto/transactions_with_sig.go index 68f9a3179..037b2965e 100644 --- a/pkg/proto/transactions_with_sig.go +++ b/pkg/proto/transactions_with_sig.go @@ -8,6 +8,7 @@ import ( "github.com/jinzhu/copier" "github.com/pkg/errors" "github.com/valyala/bytebufferpool" + "github.com/wavesplatform/gowaves/pkg/crypto" g "github.com/wavesplatform/gowaves/pkg/grpc/generated/waves" "github.com/wavesplatform/gowaves/pkg/libs/serializer" @@ -1127,10 +1128,15 @@ func (tx ExchangeWithSig) GetBuyMatcherFee() uint64 { func (tx ExchangeWithSig) GetSellMatcherFee() uint64 { return tx.SellMatcherFee } + func (tx ExchangeWithSig) GetFee() uint64 { return tx.Fee } +func (tx ExchangeWithSig) GetFeeAsset() OptionalAsset { + return NewOptionalAssetWaves() +} + func (tx ExchangeWithSig) GetTimestamp() uint64 { return tx.Timestamp } diff --git a/pkg/state/appender.go b/pkg/state/appender.go index f62f9f848..18aa14cb9 100644 --- a/pkg/state/appender.go +++ b/pkg/state/appender.go @@ -692,9 +692,9 @@ func (a *txAppender) appendBlock(params *appendBlockParams) error { snapshotApplierInfo := newBlockSnapshotsApplierInfo(checkerInfo, a.settings.AddressSchemeCharacter) a.txHandler.sa.SetApplierInfo(snapshotApplierInfo) // Create miner balance diff. - // This adds 60% of prev block fees as very first balance diff of the current block - // in case NG is activated, or empty diff otherwise. - minerAndRewardDiff, err := a.blockDiffer.createMinerAndRewardDiff(params.block, hasParent) + // This adds 60% of prev block fees as very first balance diff of the current block in case NG is activated. + // Before NG activation it adds all transactions fees to the miner's balance. + minerAndRewardDiff, err := a.blockDiffer.createMinerAndRewardDiff(params.block, hasParent, params.transactions) if err != nil { return err } diff --git a/pkg/state/balances.go b/pkg/state/balances.go index 5dfe13eed..ab3405575 100644 --- a/pkg/state/balances.go +++ b/pkg/state/balances.go @@ -277,7 +277,7 @@ func (s *balances) generateZeroLeaseBalanceSnapshotsForAllLeases() ([]proto.Leas return zeroLeaseBalanceSnapshots, nil } -func (s *balances) generateLeaseBalanceSnapthosForLeaseOverflows() ( +func (s *balances) generateLeaseBalanceSnapshotsForLeaseOverflows() ( []proto.LeaseBalanceSnapshot, map[proto.WavesAddress]struct{}, error, ) { iter, err := s.hs.newNewestTopEntryIterator(wavesBalance) diff --git a/pkg/state/balances_test.go b/pkg/state/balances_test.go index e1d666ff8..45b104008 100644 --- a/pkg/state/balances_test.go +++ b/pkg/state/balances_test.go @@ -118,8 +118,8 @@ func TestCancelLeaseOverflows(t *testing.T) { err = to.balances.setWavesBalance(addr.ID(), newWavesValueFromProfile(tc.profile), tc.blockID) assert.NoError(t, err, "setWavesBalance() failed") } - leaseBalanceSnapshots, overflows, err := to.balances.generateLeaseBalanceSnapthosForLeaseOverflows() - assert.NoError(t, err, "generateLeaseBalanceSnapthosForLeaseOverflows() failed") + leaseBalanceSnapshots, overflows, err := to.balances.generateLeaseBalanceSnapshotsForLeaseOverflows() + assert.NoError(t, err, "generateLeaseBalanceSnapshotsForLeaseOverflows() failed") to.stor.flush(t) expected := make(map[proto.WavesAddress]proto.LeaseBalanceSnapshot, len(leaseBalanceSnapshots)) diff --git a/pkg/state/block_differ.go b/pkg/state/block_differ.go index 6b57c2bf1..9bfc95754 100644 --- a/pkg/state/block_differ.go +++ b/pkg/state/block_differ.go @@ -158,6 +158,38 @@ func (d *blockDiffer) countMinerFee(tx proto.Transaction) error { return nil } +func (d *blockDiffer) doMinerPayoutBeforeNG( + diff txDiff, + blockTimestamp uint64, + minerAddr proto.WavesAddress, + transactions []proto.Transaction, +) error { + ngActivated, fErr := d.stor.features.newestIsActivatedForNBlocks(int16(settings.NG), 1) + if fErr != nil { + return fErr + } + if ngActivated { // no-op after NG activation + return nil + } + updateMinIntermediateBalance := false + if blockTimestamp >= d.settings.CheckTempNegativeAfterTime { + updateMinIntermediateBalance = true + } + for i, tx := range transactions { + var ( + fee = tx.GetFee() + feeAsset = tx.GetFeeAsset() + ) + minerKey := byteKey(minerAddr.ID(), feeAsset) + minerBalanceDiff := calculateCurrentBlockTxFee(fee, ngActivated) + nd := newBalanceDiff(int64(minerBalanceDiff), 0, 0, updateMinIntermediateBalance) + if err := diff.appendBalanceDiff(minerKey, nd); err != nil { + return errors.Wrapf(err, "failed to append balance diff for miner on %d-th transaction", i+1) + } + } + return nil +} + func (d *blockDiffer) saveCurFeeDistr(block *proto.BlockHeader) error { // Save fee distribution to DB. if err := d.stor.blocksInfo.saveFeeDistribution(block.BlockID(), &d.curDistr); err != nil { @@ -170,18 +202,25 @@ func (d *blockDiffer) saveCurFeeDistr(block *proto.BlockHeader) error { return nil } -func (d *blockDiffer) createMinerAndRewardDiff(block *proto.BlockHeader, hasParent bool) (txDiff, error) { +func (d *blockDiffer) createMinerAndRewardDiff( + blockHeader *proto.BlockHeader, + hasParent bool, + transactions []proto.Transaction, +) (txDiff, error) { var err error var minerDiff txDiff var minerAddr proto.WavesAddress if hasParent { - minerDiff, minerAddr, err = d.createPrevBlockMinerFeeDiff(block.Parent, block.GeneratorPublicKey) + minerDiff, minerAddr, err = d.createPrevBlockMinerFeeDiff(blockHeader.Parent, blockHeader.GeneratorPublicKey) if err != nil { return txDiff{}, err } - d.appendBlockInfoToTxDiff(minerDiff, block) + if mpErr := d.doMinerPayoutBeforeNG(minerDiff, blockHeader.Timestamp, minerAddr, transactions); mpErr != nil { + return txDiff{}, errors.Wrap(err, "failed to count miner payout") + } + d.appendBlockInfoToTxDiff(minerDiff, blockHeader) } - err = d.addBlockReward(minerDiff, minerAddr.ID(), block) + err = d.addBlockReward(minerDiff, minerAddr.ID(), blockHeader) if err != nil { return txDiff{}, err } diff --git a/pkg/state/block_differ_test.go b/pkg/state/block_differ_test.go index b8132e745..0450edcbc 100644 --- a/pkg/state/block_differ_test.go +++ b/pkg/state/block_differ_test.go @@ -58,10 +58,29 @@ func TestCreateBlockDiffWithoutNg(t *testing.T) { to := createBlockDiffer(t) block, _ := genBlocks(t, to) - minerDiff, err := to.blockDiffer.createMinerAndRewardDiff(&block.BlockHeader, true) + minerAddr, err := proto.NewAddressFromPublicKey(to.stor.settings.AddressSchemeCharacter, block.GeneratorPublicKey) + require.NoError(t, err) + expected := txDiff{} + updateMinIntermediateBalance := false + if block.Timestamp >= to.stor.settings.CheckTempNegativeAfterTime { + updateMinIntermediateBalance = true + } + for _, tx := range block.Transactions { + var ( + fee = tx.GetFee() + txFeeAsset = tx.GetFeeAsset() + ) + minerKey := byteKey(minerAddr.ID(), txFeeAsset) + minerBalanceDiff := fee // ng is not activated, so miner gets all the fee + bd := newBalanceDiff(int64(minerBalanceDiff), 0, 0, updateMinIntermediateBalance) + bd.blockID = block.BlockID() // set blockID for balance diff + bdErr := expected.appendBalanceDiff(minerKey, bd) + require.NoError(t, bdErr) + } + minerDiff, err := to.blockDiffer.createMinerAndRewardDiff(&block.BlockHeader, true, block.Transactions) require.NoError(t, err, "createMinerAndRewardDiff() failed") // Empty miner diff before NG activation. - assert.Equal(t, txDiff{}, minerDiff) + assert.Equal(t, expected, minerDiff) } func TestCreateBlockDiffNg(t *testing.T) { @@ -86,7 +105,7 @@ func TestCreateBlockDiffNg(t *testing.T) { parentFeeNextBlock := parentFeeTotal - parentFeePrevBlock // Create diff from child block. - minerDiff, err := to.blockDiffer.createMinerAndRewardDiff(&child.BlockHeader, true) + minerDiff, err := to.blockDiffer.createMinerAndRewardDiff(&child.BlockHeader, true, child.Transactions) require.NoError(t, err, "createMinerAndRewardDiff() failed") // Verify child block miner's diff. correctMinerAssetBalanceDiff := newBalanceDiff(parentFeeNextBlock, 0, 0, false) @@ -124,14 +143,14 @@ func TestCreateBlockDiffSponsorship(t *testing.T) { } err = to.blockDiffer.saveCurFeeDistr(&parent.BlockHeader) require.NoError(t, err, "saveCurFeeDistr() failed") - _, err = to.blockDiffer.createMinerAndRewardDiff(&parent.BlockHeader, false) + _, err = to.blockDiffer.createMinerAndRewardDiff(&parent.BlockHeader, false, parent.Transactions) require.NoError(t, err, "createMinerAndRewardDiff() failed") parentFeeTotal := int64(txs[0].GetFee() * FeeUnit / assetCost) parentFeePrevBlock := parentFeeTotal / 5 * 2 parentFeeNextBlock := parentFeeTotal - parentFeePrevBlock // Create diff from child block. - minerDiff, err := to.blockDiffer.createMinerAndRewardDiff(&child.BlockHeader, true) + minerDiff, err := to.blockDiffer.createMinerAndRewardDiff(&child.BlockHeader, true, child.Transactions) require.NoError(t, err, "createMinerAndRewardDiff() failed") // Verify child block miner's diff. correctMinerWavesBalanceDiff := newBalanceDiff(parentFeeNextBlock, 0, 0, false) @@ -187,7 +206,7 @@ func TestCreateBlockDiffWithReward(t *testing.T) { // Second block block2 := genBlockWithSingleTransaction(t, block1.BlockID(), block1.GenSignature, to) to.stor.addBlock(t, block2.BlockID()) - minerDiff, err := to.blockDiffer.createMinerAndRewardDiff(&block2.BlockHeader, true) + minerDiff, err := to.blockDiffer.createMinerAndRewardDiff(&block2.BlockHeader, true, block2.Transactions) require.NoError(t, err) fee := defaultFee - defaultFee/5*2 @@ -226,7 +245,7 @@ func TestBlockRewardDistributionWithTwoAddresses(t *testing.T) { // Second block block2 := genBlockWithSingleTransaction(t, block1.BlockID(), block1.GenSignature, to) to.stor.addBlock(t, block2.BlockID()) - minerDiff, err := to.blockDiffer.createMinerAndRewardDiff(&block2.BlockHeader, true) + minerDiff, err := to.blockDiffer.createMinerAndRewardDiff(&block2.BlockHeader, true, block2.Transactions) require.NoError(t, err) fee := int64(defaultFee - defaultFee/5*2) @@ -274,7 +293,7 @@ func TestBlockRewardDistributionWithOneAddress(t *testing.T) { // Second block block2 := genBlockWithSingleTransaction(t, block1.BlockID(), block1.GenSignature, to) to.stor.addBlock(t, block2.BlockID()) - minerDiff, err := to.blockDiffer.createMinerAndRewardDiff(&block2.BlockHeader, true) + minerDiff, err := to.blockDiffer.createMinerAndRewardDiff(&block2.BlockHeader, true, block2.Transactions) require.NoError(t, err) fee := defaultFee - defaultFee/5*2 diff --git a/pkg/state/invoke_applier_test.go b/pkg/state/invoke_applier_test.go index 730e6e7eb..1c9b6400a 100644 --- a/pkg/state/invoke_applier_test.go +++ b/pkg/state/invoke_applier_test.go @@ -37,9 +37,13 @@ type invokeApplierTestObjects struct { func createInvokeApplierTestObjects(t *testing.T) *invokeApplierTestObjects { state, err := newStateManager(t.TempDir(), true, DefaultTestingStateParams(), settings.MainNetSettings) assert.NoError(t, err, "newStateManager() failed") - err = state.stateDB.addBlock(blockID0) - assert.NoError(t, err) to := &invokeApplierTestObjects{state} + randGenesisBlockID := genRandBlockId(t) + to.addBlock(t, randGenesisBlockID) + + to.prepareBlock(t, blockID0) // height here is 2 + + to.activateFeature(t, int16(settings.NG)) to.activateFeature(t, int16(settings.SmartAccounts)) to.activateFeature(t, int16(settings.Ride4DApps)) t.Cleanup(func() { @@ -49,6 +53,22 @@ func createInvokeApplierTestObjects(t *testing.T) *invokeApplierTestObjects { return to } +// prepareBlock makes test block officially valid (but only after batch is flushed). +func (to *invokeApplierTestObjects) prepareBlock(t *testing.T, blockID proto.BlockID) { + // Assign unique block number for this block ID, add this number to the list of valid blocks. + err := to.state.stateDB.addBlock(blockID) + assert.NoError(t, err, "stateDB.addBlock() failed") +} + +// addBlock prepares, starts and finishes fake block. +func (to *invokeApplierTestObjects) addBlock(t *testing.T, blockID proto.BlockID) { + to.prepareBlock(t, blockID) + err := to.state.rw.startBlock(blockID) + assert.NoError(t, err, "startBlock() failed") + err = to.state.rw.finishBlock(blockID) + assert.NoError(t, err, "finishBlock() failed") +} + func (to *invokeApplierTestObjects) cleanup() { to.state.stor.dropUncertain() to.state.appender.ia.sc.resetComplexity() diff --git a/pkg/state/snapshot_generator.go b/pkg/state/snapshot_generator.go index cde1ea66e..0cb39828a 100644 --- a/pkg/state/snapshot_generator.go +++ b/pkg/state/snapshot_generator.go @@ -8,6 +8,7 @@ import ( "github.com/wavesplatform/gowaves/pkg/crypto" "github.com/wavesplatform/gowaves/pkg/proto" + "github.com/wavesplatform/gowaves/pkg/util/common" ) type snapshotGenerator struct { @@ -1201,13 +1202,25 @@ func (sg *snapshotGenerator) wavesBalanceSnapshotFromBalanceDiff( return nil, nil, errors.Wrap(err, "failed to receive sender's waves balance") } if diffAmount.balance != 0 { - newBalance := proto.WavesBalanceSnapshot{ + newBalance, bErr := common.AddInt(int64(fullBalance.balance), diffAmount.balance) // sum & sanity check + if bErr != nil { + return nil, nil, errors.Wrapf(bErr, + "failed to calculate waves balance for addr %q: failed to add %d to %d", + wavesAddress.String(), diffAmount.balance, fullBalance.balance, + ) + } + if newBalance < 0 { // sanity check + return nil, nil, errors.Errorf("negative waves balance for addr %q", wavesAddress.String()) + } + newBalanceSnapshot := proto.WavesBalanceSnapshot{ Address: wavesAddress, - Balance: uint64(int64(fullBalance.balance) + diffAmount.balance), + Balance: uint64(newBalance), } - wavesBalances = append(wavesBalances, newBalance) + wavesBalances = append(wavesBalances, newBalanceSnapshot) } if diffAmount.leaseIn != 0 || diffAmount.leaseOut != 0 { + // Don't check for overflow & negative leaseIn/leaseOut because overflowed addresses + // See `balances.generateLeaseBalanceSnapshotsForLeaseOverflows` for details newLeaseBalance := proto.LeaseBalanceSnapshot{ Address: wavesAddress, LeaseIn: uint64(fullBalance.leaseIn + diffAmount.leaseIn), @@ -1241,12 +1254,22 @@ func (sg *snapshotGenerator) assetBalanceSnapshotFromBalanceDiff( } assetIDTail = constInfo.Tail } - newBalance := proto.AssetBalanceSnapshot{ + fullAssetID := key.asset.Digest(assetIDTail) + newBalance, err := common.AddInt(int64(balance), diffAmount) // sum & sanity check + if err != nil { + return nil, errors.Wrapf(err, "failed to calculate asset %q balance: failed to add %d to %d", + fullAssetID.String(), diffAmount, balance, + ) + } + if newBalance < 0 { // sanity check + return nil, errors.Errorf("negative asset %q balance %d", fullAssetID.String(), newBalance) + } + newBalanceSnapshot := proto.AssetBalanceSnapshot{ Address: key.address, - AssetID: key.asset.Digest(assetIDTail), - Balance: uint64(int64(balance) + diffAmount), + AssetID: fullAssetID, + Balance: uint64(newBalance), } - assetBalances = append(assetBalances, newBalance) + assetBalances = append(assetBalances, newBalanceSnapshot) } return assetBalances, nil } diff --git a/pkg/state/snapshot_generator_internal_test.go b/pkg/state/snapshot_generator_internal_test.go index 647f6eaa2..3bcc64e0a 100644 --- a/pkg/state/snapshot_generator_internal_test.go +++ b/pkg/state/snapshot_generator_internal_test.go @@ -977,11 +977,11 @@ func TestDefaultInvokeScriptSnapshot(t *testing.T) { info := to.fallibleValidationParams(t) to.setDApp(t, "default_dapp_snapshots.base64", testGlobal.recipientInfo) amount := uint64(1000) - startBalance := amount + invokeFee + 1 + startBalance := amount + 1 wavesBalSender := wavesValue{ profile: balanceProfile{ - balance: startBalance, + balance: startBalance + invokeFee, }, leaseChange: false, balanceChange: false, @@ -1045,7 +1045,7 @@ func TestDefaultInvokeScriptSnapshot(t *testing.T) { regular: []proto.AtomicSnapshot{ &proto.WavesBalanceSnapshot{ Address: testGlobal.minerInfo.addr, - Balance: 1001001, + Balance: startBalance + calculateCurrentBlockTxFee(invokeFee, true), // because ng is activated }, &proto.WavesBalanceSnapshot{ Address: testGlobal.senderInfo.addr, @@ -1099,11 +1099,11 @@ func TestNoExtraStaticAssetInfoSnapshot(t *testing.T) { info := to.fallibleValidationParams(t) to.setDApp(t, "issue_reissue_dapp_snapshots.base64", testGlobal.recipientInfo) amount := uint64(1000) - startBalance := amount + invokeFee + 1 + startBalance := amount + 1 wavesBalSender := wavesValue{ profile: balanceProfile{ - balance: startBalance, + balance: startBalance + invokeFee, }, leaseChange: false, balanceChange: false, @@ -1170,7 +1170,7 @@ func TestNoExtraStaticAssetInfoSnapshot(t *testing.T) { regular: []proto.AtomicSnapshot{ &proto.WavesBalanceSnapshot{ Address: testGlobal.minerInfo.addr, - Balance: 1001001, + Balance: startBalance + calculateCurrentBlockTxFee(invokeFee, true), // because ng is activated }, &proto.WavesBalanceSnapshot{ Address: testGlobal.senderInfo.addr, @@ -1223,11 +1223,11 @@ func TestLeaseAndLeaseCancelInTheSameInvokeTx(t *testing.T) { to.setScript(t, testGlobal.recipientInfo.addr, dAppInfo.pk, scriptBytes) amount := uint64(1000) - startBalance := amount + invokeFee + 1 + startBalance := amount + 1 wavesBalSender := wavesValue{ profile: balanceProfile{ - balance: startBalance, + balance: startBalance + invokeFee, }, leaseChange: false, balanceChange: false, @@ -1270,7 +1270,7 @@ func TestLeaseAndLeaseCancelInTheSameInvokeTx(t *testing.T) { regular: []proto.AtomicSnapshot{ &proto.WavesBalanceSnapshot{ Address: testGlobal.minerInfo.addr, - Balance: 1001001, + Balance: startBalance + calculateCurrentBlockTxFee(invokeFee, true), // because ng is activated }, &proto.WavesBalanceSnapshot{ Address: testGlobal.senderInfo.addr, diff --git a/pkg/state/state.go b/pkg/state/state.go index f6e4e6b00..0d02f5a04 100644 --- a/pkg/state/state.go +++ b/pkg/state/state.go @@ -1435,7 +1435,7 @@ func (s *stateManager) generateLeasesCancellationWithNewBalancesSnapshots( } return joinCancelledLeasesAndLeaseBalances(cancelledLeasesSnapshots, zeroLeaseBalancesSnapshots), nil case s.settings.BlockVersion3AfterHeight: - leaseBalanceSnapshots, overflowAddresses, err := s.stor.balances.generateLeaseBalanceSnapthosForLeaseOverflows() + leaseBalanceSnapshots, overflowAddresses, err := s.stor.balances.generateLeaseBalanceSnapshotsForLeaseOverflows() if err != nil { return nil, err } diff --git a/pkg/state/transaction_differ.go b/pkg/state/transaction_differ.go index 50684b2f6..6599df10f 100644 --- a/pkg/state/transaction_differ.go +++ b/pkg/state/transaction_differ.go @@ -273,26 +273,31 @@ func newTransactionDiffer(stor *blockchainEntitiesStorage, settings *settings.Bl return &transactionDiffer{stor, settings}, nil } -func (td *transactionDiffer) calculateTxFee(txFee uint64) (uint64, error) { +func (td *transactionDiffer) minerPayoutInWaves(diff txDiff, fee uint64, info *differInfo) error { + return td.doMinerPayoutAfterNG(diff, fee, info, proto.NewOptionalAssetWaves()) +} + +// doMinerPayoutAfterNG adds current fee part of given tx to txDiff. +// It is used to add miner's payout to txDiff. Before NG activation it does nothing. +func (td *transactionDiffer) doMinerPayoutAfterNG( + diff txDiff, + fee uint64, + info *differInfo, + feeAsset proto.OptionalAsset, +) error { + if !info.hasMiner() { // no nothing if there's no miner + return nil + } ngActivated, err := td.stor.features.newestIsActivatedForNBlocks(int16(settings.NG), 1) if err != nil { - return 0, err + return err + } + if !ngActivated { // no-op before NG activation + return nil } - return calculateCurrentBlockTxFee(txFee, ngActivated), nil -} - -func (td *transactionDiffer) minerPayoutInWaves(diff txDiff, fee uint64, info *differInfo) error { - return td.minerPayout(diff, fee, info, proto.NewOptionalAssetWaves()) -} - -// minerPayout adds current fee part of given tx to txDiff. -func (td *transactionDiffer) minerPayout(diff txDiff, fee uint64, info *differInfo, feeAsset proto.OptionalAsset) error { minerAddr := info.blockInfo.Generator minerKey := byteKey(minerAddr.ID(), feeAsset) - minerBalanceDiff, err := td.calculateTxFee(fee) - if err != nil { - return err - } + minerBalanceDiff := calculateCurrentBlockTxFee(fee, ngActivated) if err := diff.appendBalanceDiff(minerKey, newBalanceDiff(int64(minerBalanceDiff), 0, 0, false)); err != nil { return err } @@ -341,10 +346,8 @@ func (td *transactionDiffer) createDiffPayment(transaction proto.Transaction, in if err := diff.appendBalanceDiff(receiverKey.bytes(), newBalanceDiff(receiverBalanceDiff, 0, 0, updateMinIntermediateBalance)); err != nil { return txBalanceChanges{}, err } - if info.hasMiner() { - if err := td.minerPayoutInWaves(diff, tx.Fee, info); err != nil { - return txBalanceChanges{}, errors.Wrap(err, "failed to append miner payout") - } + if pErr := td.minerPayoutInWaves(diff, tx.Fee, info); pErr != nil { + return txBalanceChanges{}, errors.Wrap(pErr, "failed to append miner payout") } addresses := []proto.WavesAddress{senderAddr, tx.Recipient} changes := newTxBalanceChanges(addresses, diff) @@ -364,20 +367,29 @@ func recipientToAddress(recipient proto.Recipient, aliases *aliases) (proto.Wave } func (td *transactionDiffer) payoutMinerWithSponsorshipHandling(ch *txBalanceChanges, fee uint64, feeAsset proto.OptionalAsset, info *differInfo) error { + if !feeAsset.Present { // fast path: Waves asset + if err := td.minerPayoutInWaves(ch.diff, fee, info); err != nil { + return errors.Wrap(err, "failed to append miner payout") + } + return nil + } sponsorshipActivated, err := td.stor.sponsoredAssets.isSponsorshipActivated() if err != nil { return err } - needToApplySponsorship := sponsorshipActivated && feeAsset.Present - if !needToApplySponsorship { - // No assets sponsorship. - if info.hasMiner() { - if err := td.minerPayout(ch.diff, fee, info, feeAsset); err != nil { - return errors.Wrap(err, "failed to append miner payout") - } + if !sponsorshipActivated { // payout miner in asset without sponsorship + if pErr := td.doMinerPayoutAfterNG(ch.diff, fee, info, feeAsset); pErr != nil { + return errors.Wrap(pErr, "failed to append miner payout") } return nil } + ngActivated, err := td.stor.features.newestIsActivatedForNBlocks(int16(settings.NG), 1) + if err != nil { + return err + } + if !ngActivated { // no sponsorship handling before NG activation + return errors.New("sponsorship is activated, but NG is not") + } // Sponsorship logic. updateMinIntermediateBalance := false if info.blockInfo.Timestamp >= td.settings.CheckTempNegativeAfterTime { @@ -413,10 +425,8 @@ func (td *transactionDiffer) payoutMinerWithSponsorshipHandling(ch *txBalanceCha // Sponsor is also added to list of modified addresses. ch.appendAddr(issuerAddr) // Miner payout using sponsorship. - if info.hasMiner() { - if err := td.minerPayoutInWaves(ch.diff, feeInWaves, info); err != nil { - return errors.Wrap(err, "failed to append miner payout") - } + if pErr := td.minerPayoutInWaves(ch.diff, feeInWaves, info); pErr != nil { + return errors.Wrap(pErr, "failed to append miner payout") } return nil } @@ -636,10 +646,8 @@ func (td *transactionDiffer) createDiffIssue(tx *proto.Issue, id []byte, info *d if err := diff.appendBalanceDiff(senderAssetKey.bytes(), newBalanceDiff(senderAssetBalanceDiff, 0, 0, false)); err != nil { return txBalanceChanges{}, err } - if info.hasMiner() { - if err := td.minerPayoutInWaves(diff, tx.Fee, info); err != nil { - return txBalanceChanges{}, errors.Wrap(err, "failed to append miner payout") - } + if pErr := td.minerPayoutInWaves(diff, tx.Fee, info); pErr != nil { + return txBalanceChanges{}, errors.Wrap(pErr, "failed to append miner payout") } addrs := []proto.WavesAddress{senderAddr} changes := newTxBalanceChanges(addrs, diff) @@ -688,10 +696,8 @@ func (td *transactionDiffer) createDiffReissue(tx *proto.Reissue, info *differIn if err := diff.appendBalanceDiff(senderAssetKey.bytes(), newBalanceDiff(senderAssetBalanceDiff, 0, 0, false)); err != nil { return txBalanceChanges{}, err } - if info.hasMiner() { - if err := td.minerPayoutInWaves(diff, tx.Fee, info); err != nil { - return txBalanceChanges{}, errors.Wrap(err, "failed to append miner payout") - } + if pErr := td.minerPayoutInWaves(diff, tx.Fee, info); pErr != nil { + return txBalanceChanges{}, errors.Wrap(pErr, "failed to append miner payout") } addrs := []proto.WavesAddress{senderAddr} changes := newTxBalanceChanges(addrs, diff) @@ -732,10 +738,8 @@ func (td *transactionDiffer) createDiffBurn(tx *proto.Burn, info *differInfo) (t if err := diff.appendBalanceDiff(senderAssetKey.bytes(), newBalanceDiff(senderAssetBalanceDiff, 0, 0, false)); err != nil { return txBalanceChanges{}, err } - if info.hasMiner() { - if err := td.minerPayoutInWaves(diff, tx.Fee, info); err != nil { - return txBalanceChanges{}, errors.Wrap(err, "failed to append miner payout") - } + if pErr := td.minerPayoutInWaves(diff, tx.Fee, info); pErr != nil { + return txBalanceChanges{}, errors.Wrap(pErr, "failed to append miner payout") } addrs := []proto.WavesAddress{senderAddr} changes := newTxBalanceChanges(addrs, diff) @@ -955,10 +959,8 @@ func (td *transactionDiffer) createDiffExchange(transaction proto.Transaction, i if err := diff.appendBalanceDiff(matcherKey.bytes(), newBalanceDiff(-matcherFee, 0, 0, false)); err != nil { return txBalanceChanges{}, err } - if info.hasMiner() { - if err := td.minerPayoutInWaves(diff, tx.GetFee(), info); err != nil { - return txBalanceChanges{}, errors.Wrap(err, "failed to append miner payout") - } + if pErr := td.minerPayoutInWaves(diff, tx.GetFee(), info); pErr != nil { + return txBalanceChanges{}, errors.Wrap(pErr, "failed to append miner payout") } txSenderAddr, err := proto.NewAddressFromPublicKey(td.settings.AddressSchemeCharacter, tx.GetSenderPK()) @@ -1035,11 +1037,10 @@ func (td *transactionDiffer) createDiffForExchangeFeeValidation(transaction prot if err := diff.appendBalanceDiff(matcherFeeFromReceiverKey, newBalanceDiff(receiverFee, 0, 0, true)); err != nil { return txBalanceChanges{}, err } - if info.hasMiner() { - if err := td.minerPayoutInWaves(diff, tx.GetFee(), info); err != nil { - return txBalanceChanges{}, errors.Wrap(err, "failed to append miner payout") - } + if pErr := td.minerPayoutInWaves(diff, tx.GetFee(), info); pErr != nil { + return txBalanceChanges{}, errors.Wrap(pErr, "failed to append miner payout") } + txSenderAddr, err := proto.NewAddressFromPublicKey(td.settings.AddressSchemeCharacter, tx.GetSenderPK()) if err != nil { return txBalanceChanges{}, err @@ -1068,10 +1069,8 @@ func (td *transactionDiffer) createFeeDiffExchange(transaction proto.Transaction if err := diff.appendBalanceDiff(matcherKey.bytes(), newBalanceDiff(-matcherFee, 0, 0, true)); err != nil { return txBalanceChanges{}, err } - if info.hasMiner() { - if err := td.minerPayoutInWaves(diff, tx.GetFee(), info); err != nil { - return txBalanceChanges{}, errors.Wrap(err, "failed to append miner payout") - } + if pErr := td.minerPayoutInWaves(diff, tx.GetFee(), info); pErr != nil { + return txBalanceChanges{}, errors.Wrap(pErr, "failed to append miner payout") } txSenderAddr, err := proto.NewAddressFromPublicKey(td.settings.AddressSchemeCharacter, tx.GetSenderPK()) if err != nil { @@ -1108,10 +1107,8 @@ func (td *transactionDiffer) createDiffLease(tx *proto.Lease, info *differInfo) if err := diff.appendBalanceDiff(receiverKey.bytes(), newBalanceDiff(0, receiverLeaseInDiff, 0, false)); err != nil { return txBalanceChanges{}, err } - if info.hasMiner() { - if err := td.minerPayoutInWaves(diff, tx.Fee, info); err != nil { - return txBalanceChanges{}, errors.Wrap(err, "failed to append miner payout") - } + if pErr := td.minerPayoutInWaves(diff, tx.Fee, info); pErr != nil { + return txBalanceChanges{}, errors.Wrap(pErr, "failed to append miner payout") } addresses := []proto.WavesAddress{senderAddr, recipientAddr} changes := newTxBalanceChanges(addresses, diff) @@ -1160,10 +1157,8 @@ func (td *transactionDiffer) createDiffLeaseCancel(tx *proto.LeaseCancel, info * if err := diff.appendBalanceDiff(receiverKey.bytes(), newBalanceDiff(0, receiverLeaseInDiff, 0, false)); err != nil { return txBalanceChanges{}, err } - if info.hasMiner() { - if err := td.minerPayoutInWaves(diff, tx.Fee, info); err != nil { - return txBalanceChanges{}, errors.Wrap(err, "failed to append miner payout") - } + if pErr := td.minerPayoutInWaves(diff, tx.Fee, info); pErr != nil { + return txBalanceChanges{}, errors.Wrap(pErr, "failed to append miner payout") } addresses := []proto.WavesAddress{senderAddr, l.RecipientAddr} changes := newTxBalanceChanges(addresses, diff) @@ -1198,10 +1193,8 @@ func (td *transactionDiffer) createDiffCreateAlias(tx *proto.CreateAlias, info * if err := diff.appendBalanceDiff(senderFeeKey.bytes(), newBalanceDiff(senderFeeBalanceDiff, 0, 0, false)); err != nil { return txBalanceChanges{}, err } - if info.hasMiner() { - if err := td.minerPayoutInWaves(diff, tx.Fee, info); err != nil { - return txBalanceChanges{}, errors.Wrap(err, "failed to append miner payout") - } + if pErr := td.minerPayoutInWaves(diff, tx.Fee, info); pErr != nil { + return txBalanceChanges{}, errors.Wrap(pErr, "failed to append miner payout") } addresses := []proto.WavesAddress{senderAddr} changes := newTxBalanceChanges(addresses, diff) @@ -1268,10 +1261,8 @@ func (td *transactionDiffer) createDiffMassTransferWithProofs(transaction proto. } addresses[i+1] = recipientAddr } - if info.hasMiner() { - if err := td.minerPayoutInWaves(diff, tx.Fee, info); err != nil { - return txBalanceChanges{}, errors.Wrap(err, "failed to append miner payout") - } + if pErr := td.minerPayoutInWaves(diff, tx.Fee, info); pErr != nil { + return txBalanceChanges{}, errors.Wrap(pErr, "failed to append miner payout") } changes := newTxBalanceChanges(addresses, diff) return changes, nil @@ -1293,10 +1284,8 @@ func (td *transactionDiffer) createDiffDataWithProofs(transaction proto.Transact if err := diff.appendBalanceDiff(senderFeeKey.bytes(), newBalanceDiff(senderFeeBalanceDiff, 0, 0, false)); err != nil { return txBalanceChanges{}, err } - if info.hasMiner() { - if err := td.minerPayoutInWaves(diff, tx.Fee, info); err != nil { - return txBalanceChanges{}, errors.Wrap(err, "failed to append miner payout") - } + if pErr := td.minerPayoutInWaves(diff, tx.Fee, info); pErr != nil { + return txBalanceChanges{}, errors.Wrap(pErr, "failed to append miner payout") } addresses := []proto.WavesAddress{senderAddr} changes := newTxBalanceChanges(addresses, diff) @@ -1319,10 +1308,8 @@ func (td *transactionDiffer) createDiffSponsorshipWithProofs(transaction proto.T if err := diff.appendBalanceDiff(senderFeeKey.bytes(), newBalanceDiff(senderFeeBalanceDiff, 0, 0, false)); err != nil { return txBalanceChanges{}, err } - if info.hasMiner() { - if err := td.minerPayoutInWaves(diff, tx.Fee, info); err != nil { - return txBalanceChanges{}, errors.Wrap(err, "failed to append miner payout") - } + if pErr := td.minerPayoutInWaves(diff, tx.Fee, info); pErr != nil { + return txBalanceChanges{}, errors.Wrap(pErr, "failed to append miner payout") } addresses := []proto.WavesAddress{senderAddr} changes := newTxBalanceChanges(addresses, diff) @@ -1345,10 +1332,8 @@ func (td *transactionDiffer) createDiffSetScriptWithProofs(transaction proto.Tra if err := diff.appendBalanceDiff(senderFeeKey.bytes(), newBalanceDiff(senderFeeBalanceDiff, 0, 0, false)); err != nil { return txBalanceChanges{}, err } - if info.hasMiner() { - if err := td.minerPayoutInWaves(diff, tx.Fee, info); err != nil { - return txBalanceChanges{}, errors.Wrap(err, "failed to append miner payout") - } + if pErr := td.minerPayoutInWaves(diff, tx.Fee, info); pErr != nil { + return txBalanceChanges{}, errors.Wrap(pErr, "failed to append miner payout") } addresses := []proto.WavesAddress{senderAddr} changes := newTxBalanceChanges(addresses, diff) @@ -1371,10 +1356,8 @@ func (td *transactionDiffer) createDiffSetAssetScriptWithProofs(transaction prot if err := diff.appendBalanceDiff(senderFeeKey.bytes(), newBalanceDiff(senderFeeBalanceDiff, 0, 0, false)); err != nil { return txBalanceChanges{}, err } - if info.hasMiner() { - if err := td.minerPayoutInWaves(diff, tx.Fee, info); err != nil { - return txBalanceChanges{}, errors.Wrap(err, "failed to append miner payout") - } + if mpErr := td.minerPayoutInWaves(diff, tx.Fee, info); mpErr != nil { + return txBalanceChanges{}, errors.Wrap(mpErr, "failed to append miner payout") } addresses := []proto.WavesAddress{senderAddr} changes := newTxBalanceChanges(addresses, diff) diff --git a/pkg/state/transaction_differ_test.go b/pkg/state/transaction_differ_test.go index 0c11b82b3..9d89b5a05 100644 --- a/pkg/state/transaction_differ_test.go +++ b/pkg/state/transaction_differ_test.go @@ -65,23 +65,43 @@ func createPayment(t *testing.T) *proto.Payment { func TestCreateDiffPayment(t *testing.T) { checkerInfo := defaultCheckerInfo() - to := createDifferTestObjects(t, checkerInfo) - + ddi := defaultDifferInfo() tx := createPayment(t) - ch, err := to.td.createDiffPayment(tx, defaultDifferInfo()) - assert.NoError(t, err, "createDiffPayment() failed") - - correctDiff := txDiff{ - testGlobal.senderInfo.wavesKey: newBalanceDiff(-int64(tx.Amount+tx.Fee), 0, 0, true), - testGlobal.recipientInfo.wavesKey: newBalanceDiff(int64(tx.Amount), 0, 0, true), - testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(tx.Fee), 0, 0, false), - } - assert.Equal(t, correctDiff, ch.diff) correctAddrs := map[proto.WavesAddress]struct{}{ testGlobal.senderInfo.addr: empty, testGlobal.recipientInfo.addr: empty, } - assert.Equal(t, correctAddrs, ch.addrs) + t.Run("BeforeNG", func(t *testing.T) { + to := createDifferTestObjects(t, checkerInfo) + ch, err := to.td.createDiffPayment(tx, ddi) + assert.NoError(t, err, "createDiffPayment() failed") + + correctDiff := txDiff{ + testGlobal.senderInfo.wavesKey: newBalanceDiff(-int64(tx.Amount+tx.Fee), 0, 0, true), + testGlobal.recipientInfo.wavesKey: newBalanceDiff(int64(tx.Amount), 0, 0, true), + // No key-value for miner because NG is not activated + // Fee should be paid once at the beginning of the block for all transactions + // See doMinerPayoutBeforeNG() in block_differ.go + } + assert.Equal(t, correctDiff, ch.diff) + assert.Equal(t, correctAddrs, ch.addrs) + }) + t.Run("AfterNG", func(t *testing.T) { + to := createDifferTestObjects(t, checkerInfo) + to.stor.activateFeature(t, int16(settings.NG)) + to.stor.addBlock(t, blockID0) // act as genesis block + + ch, err := to.td.createDiffPayment(tx, defaultDifferInfo()) + assert.NoError(t, err, "createDiffPayment() failed") + feePart := calculateCurrentBlockTxFee(tx.Fee, true) // NG is activated + correctDiff := txDiff{ + testGlobal.senderInfo.wavesKey: newBalanceDiff(-int64(tx.Amount+tx.Fee), 0, 0, true), + testGlobal.recipientInfo.wavesKey: newBalanceDiff(int64(tx.Amount), 0, 0, true), + testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(feePart), 0, 0, false), + } + assert.Equal(t, correctDiff, ch.diff) + assert.Equal(t, correctAddrs, ch.addrs) + }) } func createTransferWithSig(t *testing.T) *proto.TransferWithSig { @@ -107,7 +127,7 @@ func TestCreateDiffTransferWithSig(t *testing.T) { correctDiff := txDiff{ testGlobal.senderInfo.assetKeys[0]: newBalanceDiff(-int64(tx.Amount+tx.Fee), 0, 0, true), testGlobal.recipientInfo.assetKeys[0]: newBalanceDiff(int64(tx.Amount), 0, 0, true), - testGlobal.minerInfo.assetKeys[0]: newBalanceDiff(int64(tx.Fee), 0, 0, false), + // No key-value for miner because NG is not activated } assert.Equal(t, correctDiff, ch.diff) correctAddrs := map[proto.WavesAddress]struct{}{ @@ -121,17 +141,27 @@ func TestCreateDiffTransferWithSig(t *testing.T) { assert.Error(t, err, "createDiffTransferWithSig() did not fail with unsponsored asset") err = to.stor.entities.sponsoredAssets.sponsorAsset(feeFullAssetID, 10, blockID0) assert.NoError(t, err, "sponsorAsset() failed") + + // without NG activation + _, err = to.td.createDiffTransferWithSig(tx, defaultDifferInfo()) + assert.EqualError(t, err, "sponsorship is activated, but NG is not") + + // with NG activation + to.stor.addBlock(t, blockID0) // act as genesis block + to.stor.activateFeature(t, int16(settings.NG)) + ch, err = to.td.createDiffTransferWithSig(tx, defaultDifferInfo()) assert.NoError(t, err, "createDiffTransferWithSig() failed with valid sponsored asset") feeInWaves, err := to.stor.entities.sponsoredAssets.sponsoredAssetToWaves(feeShortAssetID, tx.Fee) assert.NoError(t, err, "sponsoredAssetToWaves() failed") + minerFee := calculateCurrentBlockTxFee(feeInWaves, true) // NG is activated correctDiff = txDiff{ testGlobal.senderInfo.assetKeys[0]: newBalanceDiff(-int64(tx.Amount+tx.Fee), 0, 0, true), testGlobal.recipientInfo.assetKeys[0]: newBalanceDiff(int64(tx.Amount), 0, 0, true), testGlobal.issuerInfo.assetKeys[0]: newBalanceDiff(int64(tx.Fee), 0, 0, true), testGlobal.issuerInfo.wavesKey: newBalanceDiff(-int64(feeInWaves), 0, 0, true), - testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(feeInWaves), 0, 0, false), + testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(minerFee), 0, 0, false), } assert.Equal(t, correctDiff, ch.diff) correctAddrs = map[proto.WavesAddress]struct{}{ @@ -165,7 +195,7 @@ func TestCreateDiffTransferWithProofs(t *testing.T) { correctDiff := txDiff{ testGlobal.senderInfo.assetKeys[0]: newBalanceDiff(-int64(tx.Amount+tx.Fee), 0, 0, true), testGlobal.recipientInfo.assetKeys[0]: newBalanceDiff(int64(tx.Amount), 0, 0, true), - testGlobal.minerInfo.assetKeys[0]: newBalanceDiff(int64(tx.Fee), 0, 0, false), + // No key-value for miner because NG is not activated } assert.Equal(t, correctDiff, ch.diff) correctAddrs := map[proto.WavesAddress]struct{}{ @@ -179,17 +209,27 @@ func TestCreateDiffTransferWithProofs(t *testing.T) { assert.Error(t, err, "createDiffTransferWithProofs() did not fail with unsponsored asset") err = to.stor.entities.sponsoredAssets.sponsorAsset(feeFullAssetID, 10, blockID0) assert.NoError(t, err, "sponsorAsset() failed") + + // without NG activation + _, err = to.td.createDiffTransferWithProofs(tx, defaultDifferInfo()) + assert.EqualError(t, err, "sponsorship is activated, but NG is not") + + // with NG activation + to.stor.addBlock(t, blockID0) // act as genesis block + to.stor.activateFeature(t, int16(settings.NG)) + ch, err = to.td.createDiffTransferWithProofs(tx, defaultDifferInfo()) assert.NoError(t, err, "createDiffTransferWithProofs() failed with valid sponsored asset") feeInWaves, err := to.stor.entities.sponsoredAssets.sponsoredAssetToWaves(feeShortAssetID, tx.Fee) assert.NoError(t, err, "sponsoredAssetToWaves() failed") + minerFee := calculateCurrentBlockTxFee(feeInWaves, true) // NG is activated correctDiff = txDiff{ testGlobal.senderInfo.assetKeys[0]: newBalanceDiff(-int64(tx.Amount+tx.Fee), 0, 0, true), testGlobal.recipientInfo.assetKeys[0]: newBalanceDiff(int64(tx.Amount), 0, 0, true), testGlobal.issuerInfo.assetKeys[0]: newBalanceDiff(int64(tx.Fee), 0, 0, true), testGlobal.issuerInfo.wavesKey: newBalanceDiff(-int64(feeInWaves), 0, 0, true), - testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(feeInWaves), 0, 0, false), + testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(minerFee), 0, 0, false), } assert.Equal(t, correctDiff, ch.diff) correctAddrs = map[proto.WavesAddress]struct{}{ @@ -217,16 +257,19 @@ func createNFTIssueWithSig(t *testing.T) *proto.IssueWithSig { func TestCreateDiffIssueWithSig(t *testing.T) { checkerInfo := defaultCheckerInfo() to := createDifferTestObjects(t, checkerInfo) + to.stor.addBlock(t, blockID0) // act as genesis block + to.stor.activateFeature(t, int16(settings.NG)) tx := createIssueWithSig(t, 1000) ch, err := to.td.createDiffIssueWithSig(tx, defaultDifferInfo()) assert.NoError(t, err, "createDiffIssueWithSig() failed") issuedKey := byteKey(testGlobal.senderInfo.addr.ID(), *proto.NewOptionalAssetFromDigest(*tx.ID)) + minerFee := calculateCurrentBlockTxFee(tx.Fee, true) // NG is activated correctDiff := txDiff{ string(issuedKey): newBalanceDiff(int64(tx.Quantity), 0, 0, false), testGlobal.senderInfo.wavesKey: newBalanceDiff(-int64(tx.Fee), 0, 0, false), - testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(tx.Fee), 0, 0, false), + testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(minerFee), 0, 0, false), } assert.Equal(t, correctDiff, ch.diff) correctAddrs := map[proto.WavesAddress]struct{}{ @@ -252,16 +295,19 @@ func createNFTIssueWithProofs(t *testing.T) *proto.IssueWithProofs { func TestCreateDiffIssueWithProofs(t *testing.T) { checkerInfo := defaultCheckerInfo() to := createDifferTestObjects(t, checkerInfo) + to.stor.addBlock(t, blockID0) // act as genesis block + to.stor.activateFeature(t, int16(settings.NG)) tx := createIssueWithProofs(t, 1000) ch, err := to.td.createDiffIssueWithProofs(tx, defaultDifferInfo()) assert.NoError(t, err, "createDiffIssueWithProofs() failed") issuedKey := byteKey(testGlobal.senderInfo.addr.ID(), *proto.NewOptionalAssetFromDigest(*tx.ID)) + minerFee := calculateCurrentBlockTxFee(tx.Fee, true) // NG is activated correctDiff := txDiff{ string(issuedKey): newBalanceDiff(int64(tx.Quantity), 0, 0, false), testGlobal.senderInfo.wavesKey: newBalanceDiff(-int64(tx.Fee), 0, 0, false), - testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(tx.Fee), 0, 0, false), + testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(minerFee), 0, 0, false), } assert.Equal(t, correctDiff, ch.diff) correctAddrs := map[proto.WavesAddress]struct{}{ @@ -280,15 +326,17 @@ func createReissueWithSig(t *testing.T, feeUnits int) *proto.ReissueWithSig { func TestCreateDiffReissueWithSig(t *testing.T) { checkerInfo := defaultCheckerInfo() to := createDifferTestObjects(t, checkerInfo) + to.stor.addBlock(t, blockID0) // act as genesis block + to.stor.activateFeature(t, int16(settings.NG)) tx := createReissueWithSig(t, 1000) ch, err := to.td.createDiffReissueWithSig(tx, defaultDifferInfo()) assert.NoError(t, err, "createDiffReissueWithSig() failed") - + minerFee := calculateCurrentBlockTxFee(tx.Fee, true) // NG is activated correctDiff := txDiff{ testGlobal.senderInfo.assetKeys[0]: newBalanceDiff(int64(tx.Quantity), 0, 0, false), testGlobal.senderInfo.wavesKey: newBalanceDiff(-int64(tx.Fee), 0, 0, false), - testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(tx.Fee), 0, 0, false), + testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(minerFee), 0, 0, false), } assert.Equal(t, correctDiff, ch.diff) correctAddrs := map[proto.WavesAddress]struct{}{ @@ -307,15 +355,17 @@ func createReissueWithProofs(t *testing.T, feeUnits int) *proto.ReissueWithProof func TestCreateDiffReissueWithProofs(t *testing.T) { checkerInfo := defaultCheckerInfo() to := createDifferTestObjects(t, checkerInfo) + to.stor.addBlock(t, blockID0) // act as genesis block + to.stor.activateFeature(t, int16(settings.NG)) tx := createReissueWithProofs(t, 1000) ch, err := to.td.createDiffReissueWithProofs(tx, defaultDifferInfo()) assert.NoError(t, err, "createDiffReissueWithProofs() failed") - + minerFee := calculateCurrentBlockTxFee(tx.Fee, true) // NG is activated correctDiff := txDiff{ testGlobal.senderInfo.assetKeys[0]: newBalanceDiff(int64(tx.Quantity), 0, 0, false), testGlobal.senderInfo.wavesKey: newBalanceDiff(-int64(tx.Fee), 0, 0, false), - testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(tx.Fee), 0, 0, false), + testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(minerFee), 0, 0, false), } assert.Equal(t, correctDiff, ch.diff) correctAddrs := map[proto.WavesAddress]struct{}{ @@ -334,15 +384,17 @@ func createBurnWithSig(t *testing.T) *proto.BurnWithSig { func TestCreateDiffBurnWithSig(t *testing.T) { checkerInfo := defaultCheckerInfo() to := createDifferTestObjects(t, checkerInfo) + to.stor.addBlock(t, blockID0) // act as genesis block + to.stor.activateFeature(t, int16(settings.NG)) tx := createBurnWithSig(t) ch, err := to.td.createDiffBurnWithSig(tx, defaultDifferInfo()) assert.NoError(t, err, "createDiffBurnWithSig() failed") - + minerFee := calculateCurrentBlockTxFee(tx.Fee, true) // NG is activated correctDiff := txDiff{ testGlobal.senderInfo.assetKeys[0]: newBalanceDiff(-int64(tx.Amount), 0, 0, false), testGlobal.senderInfo.wavesKey: newBalanceDiff(-int64(tx.Fee), 0, 0, false), - testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(tx.Fee), 0, 0, false), + testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(minerFee), 0, 0, false), } assert.Equal(t, correctDiff, ch.diff) correctAddrs := map[proto.WavesAddress]struct{}{ @@ -361,15 +413,17 @@ func createBurnWithProofs(t *testing.T) *proto.BurnWithProofs { func TestCreateDiffBurnWithProofs(t *testing.T) { checkerInfo := defaultCheckerInfo() to := createDifferTestObjects(t, checkerInfo) + to.stor.addBlock(t, blockID0) // act as genesis block + to.stor.activateFeature(t, int16(settings.NG)) tx := createBurnWithProofs(t) ch, err := to.td.createDiffBurnWithProofs(tx, defaultDifferInfo()) assert.NoError(t, err, "createDiffBurnWithProofs() failed") - + minerFee := calculateCurrentBlockTxFee(tx.Fee, true) // NG is activated correctDiff := txDiff{ testGlobal.senderInfo.assetKeys[0]: newBalanceDiff(-int64(tx.Amount), 0, 0, false), testGlobal.senderInfo.wavesKey: newBalanceDiff(-int64(tx.Fee), 0, 0, false), - testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(tx.Fee), 0, 0, false), + testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(minerFee), 0, 0, false), } assert.Equal(t, correctDiff, ch.diff) correctAddrs := map[proto.WavesAddress]struct{}{ @@ -408,11 +462,13 @@ func createExchangeWithSig(t *testing.T) *proto.ExchangeWithSig { func TestCreateDiffExchangeWithSig(t *testing.T) { checkerInfo := defaultCheckerInfo() to := createDifferTestObjects(t, checkerInfo) + to.stor.addBlock(t, blockID0) // act as genesis block + to.stor.activateFeature(t, int16(settings.NG)) tx := createExchangeWithSig(t) ch, err := to.td.createDiffExchange(tx, defaultDifferInfo()) assert.NoError(t, err, "createDiffExchange() failed") - + minerFee := calculateCurrentBlockTxFee(tx.Fee, true) // NG is activated price := tx.Price * tx.Amount / priceConstant correctDiff := txDiff{ testGlobal.recipientInfo.assetKeys[0]: newBalanceDiff(-int64(tx.Amount), 0, 0, false), @@ -421,7 +477,7 @@ func TestCreateDiffExchangeWithSig(t *testing.T) { testGlobal.senderInfo.assetKeys[0]: newBalanceDiff(int64(tx.Amount), 0, 0, false), testGlobal.senderInfo.assetKeys[1]: newBalanceDiff(-int64(price), 0, 0, false), testGlobal.senderInfo.wavesKey: newBalanceDiff(-int64(tx.BuyMatcherFee), 0, 0, false), - testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(tx.Fee), 0, 0, false), + testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(minerFee), 0, 0, false), testGlobal.matcherInfo.wavesKey: newBalanceDiff(int64(tx.SellMatcherFee+tx.BuyMatcherFee-tx.Fee), 0, 0, false), } assert.Equal(t, correctDiff, ch.diff) @@ -462,11 +518,13 @@ func createUnorderedExchangeWithProofs(t *testing.T, v int) *proto.ExchangeWithP func TestCreateDiffExchangeWithProofs(t *testing.T) { checkerInfo := defaultCheckerInfo() to := createDifferTestObjects(t, checkerInfo) + to.stor.addBlock(t, blockID0) // act as genesis block + to.stor.activateFeature(t, int16(settings.NG)) tx := createExchangeWithProofs(t) ch, err := to.td.createDiffExchange(tx, defaultDifferInfo()) assert.NoError(t, err, "createDiffExchange() failed") - + minerFee := calculateCurrentBlockTxFee(tx.Fee, true) // NG is activated price := tx.Price * tx.Amount / priceConstant correctDiff := txDiff{ testGlobal.recipientInfo.assetKeys[0]: newBalanceDiff(-int64(tx.Amount), 0, 0, false), @@ -475,7 +533,7 @@ func TestCreateDiffExchangeWithProofs(t *testing.T) { testGlobal.senderInfo.assetKeys[0]: newBalanceDiff(int64(tx.Amount), 0, 0, false), testGlobal.senderInfo.assetKeys[1]: newBalanceDiff(-int64(price), 0, 0, false), testGlobal.senderInfo.wavesKey: newBalanceDiff(-int64(tx.BuyMatcherFee), 0, 0, false), - testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(tx.Fee), 0, 0, false), + testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(minerFee), 0, 0, false), testGlobal.matcherInfo.wavesKey: newBalanceDiff(int64(tx.SellMatcherFee+tx.BuyMatcherFee-tx.Fee), 0, 0, false), } assert.Equal(t, correctDiff, ch.diff) @@ -572,6 +630,8 @@ func createExchangeV2WithProofsWithOrdersV3(t *testing.T, info orderBuildInfo) * func TestCreateDiffExchangeV2WithProofsWithOrdersV3(t *testing.T) { checkerInfo := defaultCheckerInfo() to := createDifferTestObjects(t, checkerInfo) + to.stor.addBlock(t, blockID0) // act as genesis block + to.stor.activateFeature(t, int16(settings.NG)) tx := createExchangeV2WithProofsWithOrdersV3(t, orderBuildInfo{ price: 10e8, @@ -579,7 +639,7 @@ func TestCreateDiffExchangeV2WithProofsWithOrdersV3(t *testing.T) { }) ch, err := to.td.createDiffExchange(tx, defaultDifferInfo()) assert.NoError(t, err, "createDiffExchange() failed") - + minerFee := calculateCurrentBlockTxFee(tx.Fee, true) // NG is activated price := tx.Price * tx.Amount / priceConstant correctDiff := txDiff{ testGlobal.recipientInfo.assetKeys[0]: newBalanceDiff(-int64(tx.Amount), 0, 0, false), @@ -588,7 +648,7 @@ func TestCreateDiffExchangeV2WithProofsWithOrdersV3(t *testing.T) { testGlobal.senderInfo.assetKeys[0]: newBalanceDiff(int64(tx.Amount), 0, 0, false), testGlobal.senderInfo.assetKeys[1]: newBalanceDiff(-int64(price), 0, 0, false), testGlobal.senderInfo.assetKeys[2]: newBalanceDiff(-int64(tx.BuyMatcherFee), 0, 0, false), - testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(tx.Fee), 0, 0, false), + testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(minerFee), 0, 0, false), testGlobal.matcherInfo.wavesKey: newBalanceDiff(-int64(tx.Fee), 0, 0, false), testGlobal.matcherInfo.assetKeys[2]: newBalanceDiff(int64(tx.SellMatcherFee+tx.BuyMatcherFee), 0, 0, false), } @@ -604,6 +664,8 @@ func TestCreateDiffExchangeV2WithProofsWithOrdersV3(t *testing.T) { func TestCreateDiffExchangeV3WithProofsWithMixedOrders(t *testing.T) { checkerInfo := defaultCheckerInfo() to := createDifferTestObjects(t, checkerInfo) + to.stor.addBlock(t, blockID0) // act as genesis block + to.stor.activateFeature(t, int16(settings.NG)) const ( asset0Decimals = 5 @@ -683,7 +745,7 @@ func TestCreateDiffExchangeV3WithProofsWithMixedOrders(t *testing.T) { tx := createExchangeV3WithProofsWithMixedOrders(t, tc.buy, tc.sell) ch, err := to.td.createDiffExchange(tx, defaultDifferInfo()) assert.NoError(t, err, "createDiffExchange() failed") - + minerFee := calculateCurrentBlockTxFee(tx.Fee, true) // NG is activated price := priceDecimalsDiffMultiplier * tx.Price * tx.Amount / priceConstant correctDiff := txDiff{ tc.senderInfo.AssetKeys()[0]: newBalanceDiff(int64(tx.Amount), 0, 0, false), @@ -692,7 +754,7 @@ func TestCreateDiffExchangeV3WithProofsWithMixedOrders(t *testing.T) { tc.recipientInfo.AssetKeys()[0]: newBalanceDiff(-int64(tx.Amount), 0, 0, false), tc.recipientInfo.AssetKeys()[1]: newBalanceDiff(int64(price), 0, 0, false), tc.recipientInfo.AssetKeys()[2]: newBalanceDiff(-int64(tx.SellMatcherFee), 0, 0, false), - testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(tx.Fee), 0, 0, false), + testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(minerFee), 0, 0, false), testGlobal.matcherInfo.wavesKey: newBalanceDiff(-int64(tx.Fee), 0, 0, false), testGlobal.matcherInfo.assetKeys[2]: newBalanceDiff(int64(tx.SellMatcherFee+tx.BuyMatcherFee), 0, 0, false), } @@ -746,6 +808,8 @@ func TestCreateDiffExchangeV3WithProofsWithMixedOrders(t *testing.T) { func TestCreateDiffExchangeV3WithProofsWithOrdersV4(t *testing.T) { checkerInfo := defaultCheckerInfo() to := createDifferTestObjects(t, checkerInfo) + to.stor.addBlock(t, blockID0) // act as genesis block + to.stor.activateFeature(t, int16(settings.NG)) to.stor.createAssetWithDecimals(t, testGlobal.asset0.asset.ID, 0) to.stor.createAssetWithDecimals(t, testGlobal.asset1.asset.ID, 8) @@ -784,6 +848,7 @@ func TestCreateDiffExchangeV3WithProofsWithOrdersV4(t *testing.T) { ch3, err := to.td.createDiffExchange(tx3mo, defaultDifferInfo()) assert.NoError(t, err, "createDiffExchange() failed") + minerFee := calculateCurrentBlockTxFee(tx3o4.Fee, true) // NG is activated priceAmount := price * amount correctDiff := txDiff{ testGlobal.recipientInfo.assetKeys[0]: newBalanceDiff(-int64(amount), 0, 0, false), @@ -792,7 +857,7 @@ func TestCreateDiffExchangeV3WithProofsWithOrdersV4(t *testing.T) { testGlobal.senderInfo.assetKeys[0]: newBalanceDiff(int64(amount), 0, 0, false), testGlobal.senderInfo.assetKeys[1]: newBalanceDiff(-int64(priceAmount), 0, 0, false), testGlobal.senderInfo.assetKeys[2]: newBalanceDiff(-int64(tx3o4.BuyMatcherFee), 0, 0, false), - testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(tx3o4.Fee), 0, 0, false), + testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(minerFee), 0, 0, false), testGlobal.matcherInfo.wavesKey: newBalanceDiff(-int64(tx3o4.Fee), 0, 0, false), testGlobal.matcherInfo.assetKeys[2]: newBalanceDiff(int64(tx3o4.SellMatcherFee+tx3o4.BuyMatcherFee), 0, 0, false), } @@ -820,15 +885,18 @@ func createLeaseWithSig(t *testing.T) *proto.LeaseWithSig { func TestCreateDiffLeaseWithSig(t *testing.T) { checkerInfo := defaultCheckerInfo() to := createDifferTestObjects(t, checkerInfo) + to.stor.addBlock(t, blockID0) // act as genesis block + to.stor.activateFeature(t, int16(settings.NG)) tx := createLeaseWithSig(t) ch, err := to.td.createDiffLeaseWithSig(tx, defaultDifferInfo()) assert.NoError(t, err, "createDiffLeaseWithSig() failed") + minerFee := calculateCurrentBlockTxFee(tx.Fee, true) // NG is activated correctDiff := txDiff{ testGlobal.senderInfo.wavesKey: newBalanceDiff(-int64(tx.Fee), 0, int64(tx.Amount), false), testGlobal.recipientInfo.wavesKey: newBalanceDiff(0, int64(tx.Amount), 0, false), - testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(tx.Fee), 0, 0, false), + testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(minerFee), 0, 0, false), } assert.Equal(t, correctDiff, ch.diff) correctAddrs := map[proto.WavesAddress]struct{}{ @@ -848,15 +916,18 @@ func createLeaseWithProofs(t *testing.T) *proto.LeaseWithProofs { func TestCreateDiffLeaseWithProofs(t *testing.T) { checkerInfo := defaultCheckerInfo() to := createDifferTestObjects(t, checkerInfo) + to.stor.addBlock(t, blockID0) // act as genesis block + to.stor.activateFeature(t, int16(settings.NG)) tx := createLeaseWithProofs(t) ch, err := to.td.createDiffLeaseWithProofs(tx, defaultDifferInfo()) assert.NoError(t, err, "createDiffLeaseWithProofs() failed") + minerFee := calculateCurrentBlockTxFee(tx.Fee, true) // NG is activated correctDiff := txDiff{ testGlobal.senderInfo.wavesKey: newBalanceDiff(-int64(tx.Fee), 0, int64(tx.Amount), false), testGlobal.recipientInfo.wavesKey: newBalanceDiff(0, int64(tx.Amount), 0, false), - testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(tx.Fee), 0, 0, false), + testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(minerFee), 0, 0, false), } assert.Equal(t, correctDiff, ch.diff) correctAddrs := map[proto.WavesAddress]struct{}{ @@ -876,6 +947,8 @@ func createLeaseCancelWithSig(t *testing.T, leaseID crypto.Digest) *proto.LeaseC func TestCreateDiffLeaseCancelWithSig(t *testing.T) { checkerInfo := defaultCheckerInfo() to := createDifferTestObjects(t, checkerInfo) + to.stor.addBlock(t, blockID0) // act as genesis block + to.stor.activateFeature(t, int16(settings.NG)) leaseTx := createLeaseWithSig(t) info := defaultPerformerInfo() @@ -887,10 +960,11 @@ func TestCreateDiffLeaseCancelWithSig(t *testing.T) { ch, err := to.td.createDiffLeaseCancelWithSig(tx, defaultDifferInfo()) assert.NoError(t, err, "createDiffLeaseCancelWithSig() failed") + minerFee := calculateCurrentBlockTxFee(tx.Fee, true) // NG is activated correctDiff := txDiff{ testGlobal.senderInfo.wavesKey: newBalanceDiff(-int64(tx.Fee), 0, -int64(leaseTx.Amount), false), testGlobal.recipientInfo.wavesKey: newBalanceDiff(0, -int64(leaseTx.Amount), 0, false), - testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(tx.Fee), 0, 0, false), + testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(minerFee), 0, 0, false), } assert.Equal(t, correctDiff, ch.diff) correctAddrs := map[proto.WavesAddress]struct{}{ @@ -910,6 +984,8 @@ func createLeaseCancelWithProofs(t *testing.T, leaseID crypto.Digest) *proto.Lea func TestCreateDiffLeaseCancelWithProofs(t *testing.T) { checkerInfo := defaultCheckerInfo() to := createDifferTestObjects(t, checkerInfo) + to.stor.addBlock(t, blockID0) // act as genesis block + to.stor.activateFeature(t, int16(settings.NG)) leaseTx := createLeaseWithProofs(t) info := defaultPerformerInfo() @@ -921,10 +997,11 @@ func TestCreateDiffLeaseCancelWithProofs(t *testing.T) { ch, err := to.td.createDiffLeaseCancelWithProofs(tx, defaultDifferInfo()) assert.NoError(t, err, "createDiffLeaseCancelWithProofs() failed") + minerFee := calculateCurrentBlockTxFee(tx.Fee, true) // NG is activated correctDiff := txDiff{ testGlobal.senderInfo.wavesKey: newBalanceDiff(-int64(tx.Fee), 0, -int64(leaseTx.Amount), false), testGlobal.recipientInfo.wavesKey: newBalanceDiff(0, -int64(leaseTx.Amount), 0, false), - testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(tx.Fee), 0, 0, false), + testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(minerFee), 0, 0, false), } assert.Equal(t, correctDiff, ch.diff) correctAddrs := map[proto.WavesAddress]struct{}{ @@ -948,14 +1025,17 @@ func createCreateAliasWithSig(t *testing.T) *proto.CreateAliasWithSig { func TestCreateDiffCreateAliasWithSig(t *testing.T) { checkerInfo := defaultCheckerInfo() to := createDifferTestObjects(t, checkerInfo) + to.stor.addBlock(t, blockID0) // act as genesis block + to.stor.activateFeature(t, int16(settings.NG)) tx := createCreateAliasWithSig(t) ch, err := to.td.createDiffCreateAliasWithSig(tx, defaultDifferInfo()) assert.NoError(t, err, "createDiffCreateAliasWithSig failed") + minerFee := calculateCurrentBlockTxFee(tx.Fee, true) // NG is activated correctDiff := txDiff{ testGlobal.senderInfo.wavesKey: newBalanceDiff(-int64(tx.Fee), 0, 0, false), - testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(tx.Fee), 0, 0, false), + testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(minerFee), 0, 0, false), } assert.Equal(t, correctDiff, ch.diff) correctAddrs := map[proto.WavesAddress]struct{}{ @@ -978,14 +1058,17 @@ func createCreateAliasWithProofs(t *testing.T) *proto.CreateAliasWithProofs { func TestCreateDiffCreateAliasWithProofs(t *testing.T) { checkerInfo := defaultCheckerInfo() to := createDifferTestObjects(t, checkerInfo) + to.stor.addBlock(t, blockID0) // act as genesis block + to.stor.activateFeature(t, int16(settings.NG)) tx := createCreateAliasWithProofs(t) ch, err := to.td.createDiffCreateAliasWithProofs(tx, defaultDifferInfo()) assert.NoError(t, err, "createDiffCreateAliasWithProofs failed") + minerFee := calculateCurrentBlockTxFee(tx.Fee, true) // NG is activated correctDiff := txDiff{ testGlobal.senderInfo.wavesKey: newBalanceDiff(-int64(tx.Fee), 0, 0, false), - testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(tx.Fee), 0, 0, false), + testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(minerFee), 0, 0, false), } assert.Equal(t, correctDiff, ch.diff) correctAddrs := map[proto.WavesAddress]struct{}{ @@ -1015,6 +1098,8 @@ func createMassTransferWithProofs(t *testing.T, transfers []proto.MassTransferEn func TestCreateDiffMassTransferWithProofs(t *testing.T) { checkerInfo := defaultCheckerInfo() to := createDifferTestObjects(t, checkerInfo) + to.stor.addBlock(t, blockID0) // act as genesis block + to.stor.activateFeature(t, int16(settings.NG)) entriesNum := 66 entries := generateMassTransferEntries(t, entriesNum) @@ -1022,9 +1107,10 @@ func TestCreateDiffMassTransferWithProofs(t *testing.T) { ch, err := to.td.createDiffMassTransferWithProofs(tx, defaultDifferInfo()) assert.NoError(t, err, "createDiffMassTransferWithProofs failed") + minerFee := calculateCurrentBlockTxFee(tx.Fee, true) // NG is activated correctDiff := txDiff{ testGlobal.senderInfo.wavesKey: newBalanceDiff(-int64(tx.Fee), 0, 0, true), - testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(tx.Fee), 0, 0, false), + testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(minerFee), 0, 0, false), } correctAddrs := map[proto.WavesAddress]struct{}{ testGlobal.senderInfo.addr: empty, @@ -1056,14 +1142,17 @@ func createDataWithProofs(t *testing.T, entriesNum int) *proto.DataWithProofs { func TestCreateDiffDataWithProofs(t *testing.T) { checkerInfo := defaultCheckerInfo() to := createDifferTestObjects(t, checkerInfo) + to.stor.addBlock(t, blockID0) // act as genesis block + to.stor.activateFeature(t, int16(settings.NG)) tx := createDataWithProofs(t, 1) ch, err := to.td.createDiffDataWithProofs(tx, defaultDifferInfo()) assert.NoError(t, err, "createDiffDataWithProofs failed") + minerFee := calculateCurrentBlockTxFee(tx.Fee, true) // NG is activated correctDiff := txDiff{ testGlobal.senderInfo.wavesKey: newBalanceDiff(-int64(tx.Fee), 0, 0, false), - testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(tx.Fee), 0, 0, false), + testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(minerFee), 0, 0, false), } assert.Equal(t, correctDiff, ch.diff) correctAddrs := map[proto.WavesAddress]struct{}{ @@ -1082,14 +1171,17 @@ func createSponsorshipWithProofs(t *testing.T, fee uint64) *proto.SponsorshipWit func TestCreateDiffSponsorshipWithProofs(t *testing.T) { checkerInfo := defaultCheckerInfo() to := createDifferTestObjects(t, checkerInfo) + to.stor.addBlock(t, blockID0) // act as genesis block + to.stor.activateFeature(t, int16(settings.NG)) tx := createSponsorshipWithProofs(t, 1000) ch, err := to.td.createDiffSponsorshipWithProofs(tx, defaultDifferInfo()) assert.NoError(t, err, "createDiffSponsorshipWithProofs failed") + minerFee := calculateCurrentBlockTxFee(tx.Fee, true) // NG is activated correctDiff := txDiff{ testGlobal.senderInfo.wavesKey: newBalanceDiff(-int64(tx.Fee), 0, 0, false), - testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(tx.Fee), 0, 0, false), + testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(minerFee), 0, 0, false), } assert.Equal(t, correctDiff, ch.diff) correctAddrs := map[proto.WavesAddress]struct{}{ @@ -1115,14 +1207,17 @@ func createSetScriptWithProofs(t *testing.T, customScriptBytes ...[]byte) *proto func TestCreateDiffSetScriptWithProofs(t *testing.T) { checkerInfo := defaultCheckerInfo() to := createDifferTestObjects(t, checkerInfo) + to.stor.addBlock(t, blockID0) // act as genesis block + to.stor.activateFeature(t, int16(settings.NG)) tx := createSetScriptWithProofs(t) ch, err := to.td.createDiffSetScriptWithProofs(tx, defaultDifferInfo()) assert.NoError(t, err, "createDiffSetScriptWithProofs failed") + minerFee := calculateCurrentBlockTxFee(tx.Fee, true) // NG is activated correctDiff := txDiff{ testGlobal.senderInfo.wavesKey: newBalanceDiff(-int64(tx.Fee), 0, 0, false), - testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(tx.Fee), 0, 0, false), + testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(minerFee), 0, 0, false), } assert.Equal(t, correctDiff, ch.diff) correctAddrs := map[proto.WavesAddress]struct{}{ @@ -1143,14 +1238,17 @@ func createSetAssetScriptWithProofs(t *testing.T) *proto.SetAssetScriptWithProof func TestCreateDiffSetAssetScriptWithProofs(t *testing.T) { checkerInfo := defaultCheckerInfo() to := createDifferTestObjects(t, checkerInfo) + to.stor.addBlock(t, blockID0) // act as genesis block + to.stor.activateFeature(t, int16(settings.NG)) tx := createSetAssetScriptWithProofs(t) ch, err := to.td.createDiffSetAssetScriptWithProofs(tx, defaultDifferInfo()) assert.NoError(t, err, "createDiffSetAssetScriptWithProofs failed") + minerFee := calculateCurrentBlockTxFee(tx.Fee, true) // NG is activated correctDiff := txDiff{ testGlobal.senderInfo.wavesKey: newBalanceDiff(-int64(tx.Fee), 0, 0, false), - testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(tx.Fee), 0, 0, false), + testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(minerFee), 0, 0, false), } assert.Equal(t, correctDiff, ch.diff) correctAddrs := map[proto.WavesAddress]struct{}{ @@ -1169,6 +1267,8 @@ func createInvokeScriptWithProofs(t *testing.T, pmts proto.ScriptPayments, fc pr func TestCreateDiffInvokeScriptWithProofs(t *testing.T) { checkerInfo := defaultCheckerInfo() to := createDifferTestObjects(t, checkerInfo) + to.stor.addBlock(t, blockID0) // act as genesis block + to.stor.activateFeature(t, int16(settings.NG)) feeConst, ok := feeConstants[proto.InvokeScriptTransaction] assert.Equal(t, ok, true) @@ -1199,6 +1299,7 @@ func TestCreateDiffInvokeScriptWithProofs(t *testing.T) { feeInWaves, err := to.stor.entities.sponsoredAssets.sponsoredAssetToWaves(feeShortAssetID, tx.Fee) assert.NoError(t, err, "sponsoredAssetToWaves() failed") + minerFee := calculateCurrentBlockTxFee(feeInWaves, true) // NG is activated recipientAssetDiff := balanceDiff{ balance: int64(totalAssetAmount), updateMinIntermediateBalance: true, @@ -1211,7 +1312,7 @@ func TestCreateDiffInvokeScriptWithProofs(t *testing.T) { testGlobal.recipientInfo.wavesKey: newBalanceDiff(int64(totalWavesAmount), 0, 0, true), testGlobal.issuerInfo.assetKeys[0]: newBalanceDiff(int64(tx.Fee), 0, 0, true), testGlobal.issuerInfo.wavesKey: newBalanceDiff(-int64(feeInWaves), 0, 0, true), - testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(feeInWaves), 0, 0, false), + testGlobal.minerInfo.wavesKey: newBalanceDiff(int64(minerFee), 0, 0, false), } assert.Equal(t, correctDiff, ch.diff) correctAddrs := map[proto.WavesAddress]struct{}{ @@ -1245,14 +1346,17 @@ func createUpdateAssetInfoForAssetWithProofs(t *testing.T, assetID crypto.Digest func TestCreateDiffUpdateAssetInfoWithProofs(t *testing.T) { checkerInfo := defaultCheckerInfo() to := createDifferTestObjects(t, checkerInfo) + to.stor.addBlock(t, blockID0) // act as genesis block + to.stor.activateFeature(t, int16(settings.NG)) tx := createUpdateAssetInfoWithProofs(t) ch, err := to.td.createDiffUpdateAssetInfoWithProofs(tx, defaultDifferInfo()) assert.NoError(t, err, "createDiffUpdateAssetInfoWithProofs() failed") + minerFee := calculateCurrentBlockTxFee(tx.Fee, true) // NG is activated correctDiff := txDiff{ testGlobal.senderInfo.assetKeys[1]: newBalanceDiff(-int64(tx.Fee), 0, 0, false), - testGlobal.minerInfo.assetKeys[1]: newBalanceDiff(int64(tx.Fee), 0, 0, false), + testGlobal.minerInfo.assetKeys[1]: newBalanceDiff(int64(minerFee), 0, 0, false), } assert.Equal(t, correctDiff, ch.diff) correctAddrs := map[proto.WavesAddress]struct{}{ diff --git a/pkg/state/transaction_fee_counter.go b/pkg/state/transaction_fee_counter.go index d19353c8b..e6041efce 100644 --- a/pkg/state/transaction_fee_counter.go +++ b/pkg/state/transaction_fee_counter.go @@ -1,7 +1,6 @@ package state import ( - "github.com/pkg/errors" "github.com/wavesplatform/gowaves/pkg/proto" "github.com/wavesplatform/gowaves/pkg/settings" ) @@ -28,234 +27,41 @@ func newTransactionFeeCounter(stor *blockchainEntitiesStorage) (*transactionFeeC return &transactionFeeCounter{stor}, nil } -func (tf *transactionFeeCounter) minerFee(distr *feeDistribution, fee uint64, asset proto.OptionalAsset) error { +func (tf *transactionFeeCounter) minerFeeByTransaction(transaction proto.Transaction, distr *feeDistribution) error { + var ( + fee = transaction.GetFee() + feeAsset = transaction.GetFeeAsset() + ) + return tf.minerFee(distr, fee, feeAsset) +} + +func (tf *transactionFeeCounter) minerFee(distr *feeDistribution, fee uint64, feeAsset proto.OptionalAsset) error { amount := fee sponsorshipActivated, err := tf.stor.sponsoredAssets.isSponsorshipActivated() if err != nil { return err } - if sponsorshipActivated && asset.Present { + if sponsorshipActivated && feeAsset.Present { // If sponsorship is activated and there is fee asset, we must convert it to Waves. - amount, err = tf.stor.sponsoredAssets.sponsoredAssetToWaves(proto.AssetIDFromDigest(asset.ID), fee) + amount, err = tf.stor.sponsoredAssets.sponsoredAssetToWaves(proto.AssetIDFromDigest(feeAsset.ID), fee) if err != nil { return err } // Asset is now Waves. - asset = proto.NewOptionalAssetWaves() + feeAsset = proto.NewOptionalAssetWaves() } ngActivated, err := tf.stor.features.newestIsActivatedForNBlocks(int16(settings.NG), 1) if err != nil { return err } - if !asset.Present { + if !feeAsset.Present { // Waves. distr.totalWavesFees += amount distr.currentWavesBlockFees += calculateCurrentBlockTxFee(amount, ngActivated) } else { // Other asset. - distr.totalFees[asset.ID] += amount - distr.currentBlockFees[asset.ID] += calculateCurrentBlockTxFee(amount, ngActivated) + distr.totalFees[feeAsset.ID] += amount + distr.currentBlockFees[feeAsset.ID] += calculateCurrentBlockTxFee(amount, ngActivated) } return nil } - -func (tf *transactionFeeCounter) minerFeePayment(transaction proto.Transaction, distr *feeDistribution) error { - tx, ok := transaction.(*proto.Payment) - if !ok { - return errors.New("failed to convert interface to Payment tx") - } - return tf.minerFee(distr, tx.Fee, proto.NewOptionalAssetWaves()) -} - -func (tf *transactionFeeCounter) minerFeeTransferWithSig(transaction proto.Transaction, distr *feeDistribution) error { - tx, ok := transaction.(*proto.TransferWithSig) - if !ok { - return errors.New("failed to convert interface to TransferWithSig tx") - } - return tf.minerFee(distr, tx.Fee, tx.FeeAsset) -} - -func (tf *transactionFeeCounter) minerFeeTransferWithProofs(transaction proto.Transaction, distr *feeDistribution) error { - tx, ok := transaction.(*proto.TransferWithProofs) - if !ok { - return errors.New("failed to convert interface to TransferWithProofs tx") - } - return tf.minerFee(distr, tx.Fee, tx.FeeAsset) -} - -func (tf *transactionFeeCounter) minerFeeEthereumTxWithProofs(transaction proto.Transaction, distr *feeDistribution) error { - tx, ok := transaction.(*proto.EthereumTransaction) - if !ok { - return errors.New("failed to convert interface to EthereumTransaction transaction") - } - - return tf.minerFee(distr, tx.GetFee(), proto.NewOptionalAssetWaves()) -} - -func (tf *transactionFeeCounter) minerFeeIssueWithSig(transaction proto.Transaction, distr *feeDistribution) error { - tx, ok := transaction.(*proto.IssueWithSig) - if !ok { - return errors.New("failed to convert interface to IssueWithSig tx") - } - return tf.minerFee(distr, tx.Fee, proto.NewOptionalAssetWaves()) -} - -func (tf *transactionFeeCounter) minerFeeIssueWithProofs(transaction proto.Transaction, distr *feeDistribution) error { - tx, ok := transaction.(*proto.IssueWithProofs) - if !ok { - return errors.New("failed to convert interface to IssueWithProofs tx") - } - return tf.minerFee(distr, tx.Fee, proto.NewOptionalAssetWaves()) -} - -func (tf *transactionFeeCounter) minerFeeReissueWithSig(transaction proto.Transaction, distr *feeDistribution) error { - tx, ok := transaction.(*proto.ReissueWithSig) - if !ok { - return errors.New("failed to convert interface to ReissueWithSig tx") - } - return tf.minerFee(distr, tx.Fee, proto.NewOptionalAssetWaves()) -} - -func (tf *transactionFeeCounter) minerFeeReissueWithProofs(transaction proto.Transaction, distr *feeDistribution) error { - tx, ok := transaction.(*proto.ReissueWithProofs) - if !ok { - return errors.New("failed to convert interface to ReissueWithProofs tx") - } - return tf.minerFee(distr, tx.Fee, proto.NewOptionalAssetWaves()) -} - -func (tf *transactionFeeCounter) minerFeeBurnWithSig(transaction proto.Transaction, distr *feeDistribution) error { - tx, ok := transaction.(*proto.BurnWithSig) - if !ok { - return errors.New("failed to convert interface to BurnWithSig tx") - } - return tf.minerFee(distr, tx.Fee, proto.NewOptionalAssetWaves()) -} - -func (tf *transactionFeeCounter) minerFeeBurnWithProofs(transaction proto.Transaction, distr *feeDistribution) error { - tx, ok := transaction.(*proto.BurnWithProofs) - if !ok { - return errors.New("failed to convert interface to BurnWithProofs tx") - } - return tf.minerFee(distr, tx.Fee, proto.NewOptionalAssetWaves()) -} - -func (tf *transactionFeeCounter) minerFeeExchange(transaction proto.Transaction, distr *feeDistribution) error { - tx, ok := transaction.(proto.Exchange) - if !ok { - return errors.New("failed to convert interface to Exchange tx") - } - return tf.minerFee(distr, tx.GetFee(), proto.NewOptionalAssetWaves()) -} - -func (tf *transactionFeeCounter) minerFeeLeaseWithSig(transaction proto.Transaction, distr *feeDistribution) error { - tx, ok := transaction.(*proto.LeaseWithSig) - if !ok { - return errors.New("failed to convert interface to LeaseWithSig tx") - } - return tf.minerFee(distr, tx.Fee, proto.NewOptionalAssetWaves()) -} - -func (tf *transactionFeeCounter) minerFeeLeaseWithProofs(transaction proto.Transaction, distr *feeDistribution) error { - tx, ok := transaction.(*proto.LeaseWithProofs) - if !ok { - return errors.New("failed to convert interface to LeaseWithProofs tx") - } - return tf.minerFee(distr, tx.Fee, proto.NewOptionalAssetWaves()) -} - -func (tf *transactionFeeCounter) minerFeeLeaseCancelWithSig(transaction proto.Transaction, distr *feeDistribution) error { - tx, ok := transaction.(*proto.LeaseCancelWithSig) - if !ok { - return errors.New("failed to convert interface to LeaseCancelWithSig tx") - } - return tf.minerFee(distr, tx.Fee, proto.NewOptionalAssetWaves()) -} - -func (tf *transactionFeeCounter) minerFeeLeaseCancelWithProofs(transaction proto.Transaction, distr *feeDistribution) error { - tx, ok := transaction.(*proto.LeaseCancelWithProofs) - if !ok { - return errors.New("failed to convert interface to LeaseCancelWithProofs tx") - } - return tf.minerFee(distr, tx.Fee, proto.NewOptionalAssetWaves()) -} - -func (tf *transactionFeeCounter) minerFeeCreateAliasWithSig(transaction proto.Transaction, distr *feeDistribution) error { - tx, ok := transaction.(*proto.CreateAliasWithSig) - if !ok { - return errors.New("failed to convert interface to CreateAliasWithSig tx") - } - return tf.minerFee(distr, tx.Fee, proto.NewOptionalAssetWaves()) -} - -func (tf *transactionFeeCounter) minerFeeCreateAliasWithProofs(transaction proto.Transaction, distr *feeDistribution) error { - tx, ok := transaction.(*proto.CreateAliasWithProofs) - if !ok { - return errors.New("failed to convert interface to CreateAliasWithProofs tx") - } - return tf.minerFee(distr, tx.Fee, proto.NewOptionalAssetWaves()) -} - -func (tf *transactionFeeCounter) minerFeeMassTransferWithProofs(transaction proto.Transaction, distr *feeDistribution) error { - tx, ok := transaction.(*proto.MassTransferWithProofs) - if !ok { - return errors.New("failed to convert interface to MassTransferWithProofs tx") - } - return tf.minerFee(distr, tx.Fee, proto.NewOptionalAssetWaves()) -} - -func (tf *transactionFeeCounter) minerFeeDataWithProofs(transaction proto.Transaction, distr *feeDistribution) error { - tx, ok := transaction.(*proto.DataWithProofs) - if !ok { - return errors.New("failed to convert interface to DataWithProofs tx") - } - return tf.minerFee(distr, tx.Fee, proto.NewOptionalAssetWaves()) -} - -func (tf *transactionFeeCounter) minerFeeSponsorshipWithProofs(transaction proto.Transaction, distr *feeDistribution) error { - tx, ok := transaction.(*proto.SponsorshipWithProofs) - if !ok { - return errors.New("failed to convert interface to SponsorshipWithProofs tx") - } - return tf.minerFee(distr, tx.Fee, proto.NewOptionalAssetWaves()) -} - -func (tf *transactionFeeCounter) minerFeeSetScriptWithProofs(transaction proto.Transaction, distr *feeDistribution) error { - tx, ok := transaction.(*proto.SetScriptWithProofs) - if !ok { - return errors.New("failed to convert interface to SetScriptWithProofs tx") - } - return tf.minerFee(distr, tx.Fee, proto.NewOptionalAssetWaves()) -} - -func (tf *transactionFeeCounter) minerFeeSetAssetScriptWithProofs(transaction proto.Transaction, distr *feeDistribution) error { - tx, ok := transaction.(*proto.SetAssetScriptWithProofs) - if !ok { - return errors.New("failed to convert interface to SetAssetScriptWithProofs tx") - } - return tf.minerFee(distr, tx.Fee, proto.NewOptionalAssetWaves()) -} - -func (tf *transactionFeeCounter) minerFeeInvokeScriptWithProofs(transaction proto.Transaction, distr *feeDistribution) error { - tx, ok := transaction.(*proto.InvokeScriptWithProofs) - if !ok { - return errors.New("failed to convert interface to InvokeScriptWithProofs tx") - } - return tf.minerFee(distr, tx.Fee, tx.FeeAsset) -} - -func (tf *transactionFeeCounter) minerFeeInvokeExpressionWithProofs(transaction proto.Transaction, distr *feeDistribution) error { - tx, ok := transaction.(*proto.InvokeExpressionTransactionWithProofs) - if !ok { - return errors.New("failed to convert interface to InvokeExpressionWithProofs tx") - } - return tf.minerFee(distr, tx.Fee, tx.FeeAsset) -} - -func (tf *transactionFeeCounter) minerFeeUpdateAssetInfoWithProofs(transaction proto.Transaction, distr *feeDistribution) error { - tx, ok := transaction.(*proto.UpdateAssetInfoWithProofs) - if !ok { - return errors.New("failed to convert interface to UpdateAssetInfoWithProofs tx") - } - return tf.minerFee(distr, tx.Fee, tx.FeeAsset) -} diff --git a/pkg/state/transaction_handler.go b/pkg/state/transaction_handler.go index 671017eb1..bcdea00e7 100644 --- a/pkg/state/transaction_handler.go +++ b/pkg/state/transaction_handler.go @@ -64,107 +64,107 @@ func buildHandles( //nolint:funlen }, proto.TransactionTypeInfo{Type: proto.PaymentTransaction, ProofVersion: proto.Signature}: txHandleFuncs{ tc.checkPayment, tp.performPayment, - td.createDiffPayment, tf.minerFeePayment, + td.createDiffPayment, tf.minerFeeByTransaction, }, proto.TransactionTypeInfo{Type: proto.TransferTransaction, ProofVersion: proto.Signature}: txHandleFuncs{ tc.checkTransferWithSig, tp.performTransferWithSig, - td.createDiffTransferWithSig, tf.minerFeeTransferWithSig, + td.createDiffTransferWithSig, tf.minerFeeByTransaction, }, proto.TransactionTypeInfo{Type: proto.TransferTransaction, ProofVersion: proto.Proof}: txHandleFuncs{ tc.checkTransferWithProofs, tp.performTransferWithProofs, - td.createDiffTransferWithProofs, tf.minerFeeTransferWithProofs, + td.createDiffTransferWithProofs, tf.minerFeeByTransaction, }, proto.TransactionTypeInfo{Type: proto.IssueTransaction, ProofVersion: proto.Signature}: txHandleFuncs{ tc.checkIssueWithSig, tp.performIssueWithSig, - td.createDiffIssueWithSig, tf.minerFeeIssueWithSig, + td.createDiffIssueWithSig, tf.minerFeeByTransaction, }, proto.TransactionTypeInfo{Type: proto.IssueTransaction, ProofVersion: proto.Proof}: txHandleFuncs{ tc.checkIssueWithProofs, tp.performIssueWithProofs, - td.createDiffIssueWithProofs, tf.minerFeeIssueWithProofs, + td.createDiffIssueWithProofs, tf.minerFeeByTransaction, }, proto.TransactionTypeInfo{Type: proto.ReissueTransaction, ProofVersion: proto.Signature}: txHandleFuncs{ tc.checkReissueWithSig, tp.performReissueWithSig, - td.createDiffReissueWithSig, tf.minerFeeReissueWithSig, + td.createDiffReissueWithSig, tf.minerFeeByTransaction, }, proto.TransactionTypeInfo{Type: proto.ReissueTransaction, ProofVersion: proto.Proof}: txHandleFuncs{ tc.checkReissueWithProofs, tp.performReissueWithProofs, - td.createDiffReissueWithProofs, tf.minerFeeReissueWithProofs, + td.createDiffReissueWithProofs, tf.minerFeeByTransaction, }, proto.TransactionTypeInfo{Type: proto.BurnTransaction, ProofVersion: proto.Signature}: txHandleFuncs{ tc.checkBurnWithSig, tp.performBurnWithSig, - td.createDiffBurnWithSig, tf.minerFeeBurnWithSig, + td.createDiffBurnWithSig, tf.minerFeeByTransaction, }, proto.TransactionTypeInfo{Type: proto.BurnTransaction, ProofVersion: proto.Proof}: txHandleFuncs{ tc.checkBurnWithProofs, tp.performBurnWithProofs, - td.createDiffBurnWithProofs, tf.minerFeeBurnWithProofs, + td.createDiffBurnWithProofs, tf.minerFeeByTransaction, }, proto.TransactionTypeInfo{Type: proto.ExchangeTransaction, ProofVersion: proto.Signature}: txHandleFuncs{ tc.checkExchangeWithSig, tp.performExchange, - td.createDiffExchange, tf.minerFeeExchange, + td.createDiffExchange, tf.minerFeeByTransaction, }, proto.TransactionTypeInfo{Type: proto.ExchangeTransaction, ProofVersion: proto.Proof}: txHandleFuncs{ tc.checkExchangeWithProofs, tp.performExchange, - td.createDiffExchange, tf.minerFeeExchange, + td.createDiffExchange, tf.minerFeeByTransaction, }, proto.TransactionTypeInfo{Type: proto.LeaseTransaction, ProofVersion: proto.Signature}: txHandleFuncs{ tc.checkLeaseWithSig, tp.performLeaseWithSig, - td.createDiffLeaseWithSig, tf.minerFeeLeaseWithSig, + td.createDiffLeaseWithSig, tf.minerFeeByTransaction, }, proto.TransactionTypeInfo{Type: proto.LeaseTransaction, ProofVersion: proto.Proof}: txHandleFuncs{ tc.checkLeaseWithProofs, tp.performLeaseWithProofs, - td.createDiffLeaseWithProofs, tf.minerFeeLeaseWithProofs, + td.createDiffLeaseWithProofs, tf.minerFeeByTransaction, }, proto.TransactionTypeInfo{Type: proto.LeaseCancelTransaction, ProofVersion: proto.Signature}: txHandleFuncs{ tc.checkLeaseCancelWithSig, tp.performLeaseCancelWithSig, - td.createDiffLeaseCancelWithSig, tf.minerFeeLeaseCancelWithSig, + td.createDiffLeaseCancelWithSig, tf.minerFeeByTransaction, }, proto.TransactionTypeInfo{Type: proto.LeaseCancelTransaction, ProofVersion: proto.Proof}: txHandleFuncs{ tc.checkLeaseCancelWithProofs, tp.performLeaseCancelWithProofs, - td.createDiffLeaseCancelWithProofs, tf.minerFeeLeaseCancelWithProofs, + td.createDiffLeaseCancelWithProofs, tf.minerFeeByTransaction, }, proto.TransactionTypeInfo{Type: proto.CreateAliasTransaction, ProofVersion: proto.Signature}: txHandleFuncs{ tc.checkCreateAliasWithSig, tp.performCreateAliasWithSig, - td.createDiffCreateAliasWithSig, tf.minerFeeCreateAliasWithSig, + td.createDiffCreateAliasWithSig, tf.minerFeeByTransaction, }, proto.TransactionTypeInfo{Type: proto.CreateAliasTransaction, ProofVersion: proto.Proof}: txHandleFuncs{ tc.checkCreateAliasWithProofs, tp.performCreateAliasWithProofs, - td.createDiffCreateAliasWithProofs, tf.minerFeeCreateAliasWithProofs, + td.createDiffCreateAliasWithProofs, tf.minerFeeByTransaction, }, proto.TransactionTypeInfo{Type: proto.MassTransferTransaction, ProofVersion: proto.Proof}: txHandleFuncs{ tc.checkMassTransferWithProofs, tp.performMassTransferWithProofs, - td.createDiffMassTransferWithProofs, tf.minerFeeMassTransferWithProofs, + td.createDiffMassTransferWithProofs, tf.minerFeeByTransaction, }, proto.TransactionTypeInfo{Type: proto.DataTransaction, ProofVersion: proto.Proof}: txHandleFuncs{ tc.checkDataWithProofs, tp.performDataWithProofs, - td.createDiffDataWithProofs, tf.minerFeeDataWithProofs, + td.createDiffDataWithProofs, tf.minerFeeByTransaction, }, proto.TransactionTypeInfo{Type: proto.SponsorshipTransaction, ProofVersion: proto.Proof}: txHandleFuncs{ tc.checkSponsorshipWithProofs, tp.performSponsorshipWithProofs, - td.createDiffSponsorshipWithProofs, tf.minerFeeSponsorshipWithProofs, + td.createDiffSponsorshipWithProofs, tf.minerFeeByTransaction, }, proto.TransactionTypeInfo{Type: proto.SetScriptTransaction, ProofVersion: proto.Proof}: txHandleFuncs{ tc.checkSetScriptWithProofs, tp.performSetScriptWithProofs, - td.createDiffSetScriptWithProofs, tf.minerFeeSetScriptWithProofs, + td.createDiffSetScriptWithProofs, tf.minerFeeByTransaction, }, proto.TransactionTypeInfo{Type: proto.SetAssetScriptTransaction, ProofVersion: proto.Proof}: txHandleFuncs{ tc.checkSetAssetScriptWithProofs, tp.performSetAssetScriptWithProofs, - td.createDiffSetAssetScriptWithProofs, tf.minerFeeSetAssetScriptWithProofs, + td.createDiffSetAssetScriptWithProofs, tf.minerFeeByTransaction, }, proto.TransactionTypeInfo{Type: proto.InvokeScriptTransaction, ProofVersion: proto.Proof}: txHandleFuncs{ tc.checkInvokeScriptWithProofs, tp.performInvokeScriptWithProofs, - td.createDiffInvokeScriptWithProofs, tf.minerFeeInvokeScriptWithProofs, + td.createDiffInvokeScriptWithProofs, tf.minerFeeByTransaction, }, proto.TransactionTypeInfo{Type: proto.InvokeExpressionTransaction, ProofVersion: proto.Proof}: txHandleFuncs{ tc.checkInvokeExpressionWithProofs, tp.performInvokeExpressionWithProofs, - td.createDiffInvokeExpressionWithProofs, tf.minerFeeInvokeExpressionWithProofs, + td.createDiffInvokeExpressionWithProofs, tf.minerFeeByTransaction, }, proto.TransactionTypeInfo{Type: proto.UpdateAssetInfoTransaction, ProofVersion: proto.Proof}: txHandleFuncs{ tc.checkUpdateAssetInfoWithProofs, tp.performUpdateAssetInfoWithProofs, - td.createDiffUpdateAssetInfoWithProofs, tf.minerFeeUpdateAssetInfoWithProofs, + td.createDiffUpdateAssetInfoWithProofs, tf.minerFeeByTransaction, }, proto.TransactionTypeInfo{Type: proto.EthereumMetamaskTransaction, ProofVersion: proto.Proof}: txHandleFuncs{ tc.checkEthereumTransactionWithProofs, tp.performEthereumTransactionWithProofs, - td.createDiffEthereumTransactionWithProofs, tf.minerFeeEthereumTxWithProofs, + td.createDiffEthereumTransactionWithProofs, tf.minerFeeByTransaction, }, } }