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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add checker for no transaction cost #3158

Open
wants to merge 9 commits into
base: sprint-1.14
Choose a base branch
from
1 change: 1 addition & 0 deletions code/go/0chain.net/chaincore/block/entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ var (
ErrPreviousStateUnavailable = common.NewError("prev_state_unavailable", "Previous state not available")
ErrPreviousStateNotComputed = common.NewError("prev_state_not_computed", "Previous state not computed")
ErrCostTooBig = common.NewError("cost_too_big", "Block cost is too big")
ErrCostNotFound = common.NewError("cost_not_found", "Cost if not defined for transaction")

// ErrPreviousBlockUnavailable - error for previous block is not available.
ErrPreviousBlockUnavailable = common.NewError(PreviousBlockUnavailable,
Expand Down
15 changes: 14 additions & 1 deletion code/go/0chain.net/miner/protocol_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ import (
// InsufficientTxns - to indicate an error when the transactions are not sufficient to make a block
const InsufficientTxns = "insufficient_txns"

const NoTransactionCost = "no_transaction_cost"

// ErrLFBClientStateNil is returned when client state of latest finalized block is nil
var ErrLFBClientStateNil = errors.New("client state of latest finalized block is empty")

Expand Down Expand Up @@ -353,6 +355,9 @@ func (mc *Chain) VerifyBlock(ctx context.Context, b *block.Block) (
if err != nil {
return err
}
if c == math.MaxInt {
return block.ErrCostNotFound
}

cost += c
costs = append(costs, c)
Expand Down Expand Up @@ -945,7 +950,7 @@ func txnIterHandlerFunc(
tii.invalidTxns = append(tii.invalidTxns, txn)
return false, errors.New("invalid transaction value, exceeds max token supply")
}

cost, fee, err := mc.EstimateTransactionCostFee(ctx, lfb, txn, chain.WithSync(), chain.WithNotifyC(waitC))
if err != nil {
logging.Logger.Debug("generate block - bad transaction cost fee",
Expand All @@ -960,6 +965,10 @@ func txnIterHandlerFunc(
// skipping and continue
return true, nil
}
if cost == math.MaxInt {
logging.Logger.Debug("generate block (no transaction cost , skipping)")
return true, nil
}

if mc.IsFeeEnabled() {
confMinFee := mc.ChainConfig.MinTxnFee()
Expand Down Expand Up @@ -1171,6 +1180,10 @@ func (mc *Chain) generateBlock(ctx context.Context, b *block.Block,
logging.Logger.Debug("Bad transaction cost", zap.Error(err), zap.String("txn_hash", txn.Hash))
break
}
if cost == math.MaxInt {
logging.Logger.Debug("No transaction cost")
break
}
if iterInfo.cost+cost >= mc.ChainConfig.MaxBlockCost() {
logging.Logger.Debug("generate block (too big cost, skipping)")
break
Expand Down
115 changes: 115 additions & 0 deletions code/go/0chain.net/miner/protocol_block_main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -356,3 +356,118 @@ func TestChain_deletingTxns(t *testing.T) {
}

}

func TestChain_generateBlock(t *testing.T) {
transaction.SetTxnTimeout(int64(3 * time.Minute))
txs := []*transaction.Transaction{
{ClientID: "1", Nonce: 0},
{ClientID: "1", Nonce: 1},
{ClientID: "1", Nonce: 2},
{ClientID: "1", Nonce: 3},
{ClientID: "1", Nonce: 4},
{ClientID: "2", Fee: 1, Nonce: 5},
{ClientID: "2", Fee: 10, Nonce: 6},
{ClientID: "2", Fee: 12, Nonce: 7},
{ClientID: "2", Fee: 34, Nonce: 8},
}

tests := []struct {
name string
txns []*transaction.Transaction
}{
{
name: "test_sample",
txns: txs,
},
}

require.NoError(t, initDefaultPool())

logging.InitLogging("testing", "")

n1 := &node.Node{Type: node.NodeTypeMiner, Host: "", Port: 7071, Status: node.NodeStatusActive}
n1.ID = "24e23c52e2e40689fdb700180cd68ac083a42ed292d90cc021119adaa4d21509"
n2 := &node.Node{Type: node.NodeTypeMiner, Host: "", Port: 7072, Status: node.NodeStatusActive}
n2.ID = "5fbb6924c222e96df6c491dfc4a542e1bbfc75d821bcca992544899d62121b55"
n3 := &node.Node{Type: node.NodeTypeMiner, Host: "", Port: 7073, Status: node.NodeStatusActive}
n3.ID = "103c274502661e78a2b5c470057e57699e372a4382a4b96b29c1bec993b1d19c"

node.Self = &node.SelfNode{}
node.Self.Node = n1

setupSelfNodeKeys()

np := node.NewPool(node.NodeTypeMiner)
np.AddNode(n1)
np.AddNode(n2)
np.AddNode(n3)

mb := block.NewMagicBlock()
mb.Miners = np

c := chain.Provider().(*chain.Chain)
c.ID = datastore.ToKey(config.GetServerChainID())
c.SetMagicBlock(mb)
chain.SetServerChain(c)
SetupMinerChain(c)
mc := GetMinerChain()
mc.SetMagicBlock(mb)
SetupM2MSenders()

setupTempRocksDBDir()
common.SetupRootContext(node.GetNodeContext())
config.SetServerChainID(config.GetMainChainID())
transaction.SetupEntity(memorystore.GetStorageProvider())
client.SetupEntity(memorystore.GetStorageProvider())
chain.SetupEntity(memorystore.GetStorageProvider(), "")

memorystore.AddPool("txndb", memorystore.DefaultPool)
memorystore.AddPool("clientdb", memorystore.DefaultPool)

sigScheme := encryption.GetSignatureScheme("bls0chain")
require.NoError(t, sigScheme.GenerateKeys())

var cl *client.Client
cl = client.NewClient(client.SignatureScheme(encryption.SignatureSchemeBls0chain))
cl.EntityCollection = &datastore.EntityCollection{CollectionName: "collection.cli", CollectionSize: 60000000000, CollectionDuration: time.Minute}
require.NoError(t, cl.SetPublicKey(sigScheme.GetPublicKey()))
ctx := context.Background()
b := block.NewBlock("", 1)
var waitC chan struct{}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

// storing txns
for _, txn := range tt.txns {
txn.CreationDate = common.Now()
txn.PublicKey = cl.PublicKey
txn.ClientID = cl.ID
txn.Hash = txn.ComputeHash()

txnData, err := json.Marshal(struct {
name string
}{
name: "test",
})
require.NoError(t, err)
txn.TransactionData = string(txnData)

sig, err := txn.Sign(sigScheme)
require.NoError(t, err)

txn.Signature = sig

_, err = transaction.PutTransaction(ctx, txn)
require.NoError(t, err)

}

// generating block
err := mc.GenerateBlock(ctx, b, false, waitC)
require.NoError(t, err)

})
}

}