Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added ZCN Service Fee #1975

Merged
merged 7 commits into from Jan 16, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -87,6 +87,7 @@ func MakeMockStateContext() *mockStateContext {
// Transfers

var transfers []*state.Transfer
var mints []*state.Mint

// EventsDB
events = make(map[string]*AuthorizerNode, 100)
Expand Down Expand Up @@ -188,7 +189,13 @@ func MakeMockStateContext() *mockStateContext {
return nil
})

ctx.On("AddMint", mock.AnythingOfType("*state.Mint")).Return(nil)
ctx.On("AddMint", mock.AnythingOfType("*state.Mint")).Return(func(m *state.Mint) error {
mints = append(mints, m)
return nil
})
ctx.On("GetMints").Return(func() []*state.Mint {
return mints
})

// EventsDB

Expand Down
48 changes: 40 additions & 8 deletions code/go/0chain.net/smartcontract/zcnsc/mint.go
Expand Up @@ -8,6 +8,7 @@ import (
"0chain.net/chaincore/state"
"0chain.net/chaincore/transaction"
"0chain.net/core/common"
"github.com/0chain/common/core/currency"
"github.com/0chain/common/core/logging"
"github.com/pkg/errors"
"go.uber.org/zap"
Expand All @@ -19,13 +20,11 @@ func (zcn *ZCNSmartContract) Mint(trans *transaction.Transaction, inputData []by
code = "failed to mint"
)

var (
info = fmt.Sprintf(
"transaction hash %s, clientID: %s, payload: %s",
trans.Hash,
trans.ClientID,
string(inputData),
)
info := fmt.Sprintf(
"transaction hash %s, clientID: %s, payload: %s",
trans.Hash,
trans.ClientID,
string(inputData),
)

gn, err := GetGlobalNode(ctx)
Expand Down Expand Up @@ -114,14 +113,47 @@ func (zcn *ZCNSmartContract) Mint(trans *transaction.Transaction, inputData []by
// record the global nonce from solidity smart contract
gn.WZCNNonceMinted[payload.Nonce] = true

var (
amount currency.Coin
n currency.Coin
share currency.Coin
)
share, _, err = currency.DistributeCoin(gn.ZCNSConfig.MaxFee, int64(len(payload.Signatures)))
if err != nil {
err = errors.Wrap(err, fmt.Sprintf("%s, DistributeCoin operation, %s", code, info))
return
}
n, err = currency.Int64ToCoin(int64(len(payload.Signatures)))
peterlimg marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
err = errors.Wrap(err, fmt.Sprintf("%s, convert len signatures to coin, %s", code, info))
return
}
amount, err = currency.MinusCoin(payload.Amount, share*n)
peterlimg marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
err = errors.Wrap(err, fmt.Sprintf("%s, payload.Amount - share * len(signatures), %s", code, info))
return
}
payload.Amount = amount
for _, sig := range payload.Signatures {
din-mukhammed marked this conversation as resolved.
Show resolved Hide resolved
err = ctx.AddMint(&state.Mint{
Minter: gn.ID,
ToClientID: sig.ID,
Amount: share,
})
if err != nil {
err = errors.Wrap(err, fmt.Sprintf("%s, AddMint for authorizers, %s", code, info))
return
}
}

// mint the tokens
err = ctx.AddMint(&state.Mint{
Minter: gn.ID,
ToClientID: trans.ClientID,
Amount: payload.Amount,
})
if err != nil {
err = errors.Wrap(err, fmt.Sprintf("%s, add mint operation, %s", code, info))
err = errors.Wrap(err, fmt.Sprintf("%s, Add mint operation, %s", code, info))
return
}

Expand Down
34 changes: 34 additions & 0 deletions code/go/0chain.net/smartcontract/zcnsc/mint_test.go
Expand Up @@ -6,6 +6,7 @@ import (
"time"

. "0chain.net/smartcontract/zcnsc"
"github.com/0chain/common/core/currency"
"github.com/0chain/common/core/logging"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
Expand Down Expand Up @@ -66,6 +67,39 @@ func Test_FuzzyMintTest(t *testing.T) {
}
}

func Test_MaxFeeMint(t *testing.T) {
const maxFee = 9
ctx := MakeMockStateContext()
ctx.globalNode.ZCNSConfig.MaxFee = maxFee
contract := CreateZCNSmartContract()
payload, err := CreateMintPayload(ctx, defaultClient)
require.NoError(t, err)

transaction, err := CreateTransaction(defaultClient, "mint", payload.Encode(), ctx)
require.NoError(t, err)

response, err := contract.Mint(transaction, payload.Encode(), ctx)
require.NoError(t, err, "Testing authorizer: '%s'", defaultClient)
require.NotNil(t, response)
require.NotEmpty(t, response)

mm := ctx.GetMints()
require.Equal(t, len(mm), len(authorizersID)+1)
expectedShare, err := currency.Int64ToCoin(int64(maxFee / len(authorizersID)))
require.NoError(t, err)
for i := 0; i < 3; i++ {
require.Equal(t, mm[i].ToClientID, authorizersID[i])
require.Equal(t, mm[i].Amount, expectedShare)
}

rp := &MintPayload{}
require.NoError(t, rp.Decode([]byte(response)))
require.Equal(t, payload.ReceivingClientID, rp.ReceivingClientID)
expectedAmount, err := currency.MinusCoin(payload.Amount, maxFee)
require.NoError(t, err)
require.Equal(t, rp.Amount, expectedAmount)
din-mukhammed marked this conversation as resolved.
Show resolved Hide resolved
}

func Test_EmptySignaturesShouldFail(t *testing.T) {
ctx := MakeMockStateContext()
contract := CreateZCNSmartContract()
Expand Down