Skip to content

Commit

Permalink
go/txsource/workload: extract "fund sign submit" into helper function
Browse files Browse the repository at this point in the history
  • Loading branch information
ptrus committed Mar 20, 2020
1 parent 3a09db5 commit 8c42399
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 143 deletions.
80 changes: 12 additions & 68 deletions go/oasis-node/cmd/debug/txsource/workload/delegation.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,42 +80,14 @@ func (d *delegation) doEscrowTx(ctx context.Context, rng *rand.Rand, cnsc consen

tx := staking.NewAddEscrowTx(d.accounts[selectedIdx].reckonedNonce, &transaction.Fee{}, escrow)
d.accounts[selectedIdx].reckonedNonce++

// Estimate gas.
gas, err := cnsc.EstimateGas(ctx, &consensus.EstimateGasRequest{
Caller: d.accounts[selectedIdx].signer.Public(),
Transaction: tx,
})
if err != nil {
return fmt.Errorf("failed to estimate gas: %w", err)
}
tx.Fee.Gas = gas
feeAmount := int64(gas) * gasPrice
if err = tx.Fee.Amount.FromInt64(feeAmount); err != nil {
return fmt.Errorf("fee amount from int64: %w", err)
}

// Fund account to cover Escrow fees.
// We only do one escrow per account at a time, so `delegateAmount`
// funds (that are Escrowed) should already be in the balance.
fundAmount := int64(gas) * gasPrice // transaction costs
if err = transferFunds(ctx, d.logger, cnsc, d.fundingAccount, d.accounts[selectedIdx].signer.Public(), fundAmount); err != nil {
return fmt.Errorf("account funding failure: %w", err)
}

// Sign transaction.
signedTx, err := transaction.Sign(d.accounts[selectedIdx].signer, tx)
if err != nil {
return fmt.Errorf("transaction.Sign: %w", err)
}
d.logger.Debug("submitting escrow transaction",
"from", d.accounts[selectedIdx].signer.Public(),
"to", d.accounts[selectedIdx].delegatedTo,
)

// Submit transaction.
if err = cnsc.SubmitTx(ctx, signedTx); err != nil {
return fmt.Errorf("cnsc.SubmitTx: %w", err)
if err := fundSignAndSubmitTx(ctx, d.logger, cnsc, d.accounts[selectedIdx].signer, tx, d.fundingAccount); err != nil {
d.logger.Error("failed to sign and submit escrow transaction",
"tx", tx,
"signer", d.accounts[selectedIdx].signer,
)
return fmt.Errorf("failed to sign and submit tx: %w", err)
}

return nil
Expand Down Expand Up @@ -166,40 +138,12 @@ func (d *delegation) doReclaimEscrowTx(ctx context.Context, rng *rand.Rand, cnsc
}
tx := staking.NewReclaimEscrowTx(d.accounts[selectedIdx].reckonedNonce, &transaction.Fee{}, reclaim)
d.accounts[selectedIdx].reckonedNonce++

// Estimate gas.
gas, err := cnsc.EstimateGas(ctx, &consensus.EstimateGasRequest{
Caller: d.accounts[selectedIdx].signer.Public(),
Transaction: tx,
})
if err != nil {
return fmt.Errorf("failed to estimate gas: %w", err)
}
tx.Fee.Gas = gas
feeAmount := int64(gas) * gasPrice
if err = tx.Fee.Amount.FromInt64(feeAmount); err != nil {
return fmt.Errorf("fee amount from int64: %w", err)
}

// Fund account to cover reclaim escrow fees.
fundAmount := int64(gas) * gasPrice // transaction costs
if err = transferFunds(ctx, d.logger, cnsc, d.fundingAccount, d.accounts[selectedIdx].signer.Public(), fundAmount); err != nil {
return fmt.Errorf("account funding failure: %w", err)
}

signedTx, err := transaction.Sign(d.accounts[selectedIdx].signer, tx)
if err != nil {
return fmt.Errorf("transaction.Sign: %w", err)
}

d.logger.Debug("submitting reclaim escrow transaction",
"reclaim_from", d.accounts[selectedIdx].delegatedTo,
"account", d.accounts[selectedIdx].signer.Public(),
)

// Submit transaction.
if err = cnsc.SubmitTx(ctx, signedTx); err != nil {
return fmt.Errorf("cnsc.SubmitTx: %w", err)
if err = fundSignAndSubmitTx(ctx, d.logger, cnsc, d.accounts[selectedIdx].signer, tx, d.fundingAccount); err != nil {
d.logger.Error("failed to sign and submit reclaim escrow transaction",
"tx", tx,
"signer", d.accounts[selectedIdx].signer,
)
return fmt.Errorf("failed to sign and submit tx: %w", err)
}

// Query debonding end epoch for the account.
Expand Down
94 changes: 19 additions & 75 deletions go/oasis-node/cmd/debug/txsource/workload/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,30 +243,12 @@ func (r *registration) Run( // nolint: gocyclo
// Estimate gas and submit transaction.
tx := registry.NewRegisterEntityTx(entityAccs[i].reckonedNonce, &transaction.Fee{}, sigEntity)
entityAccs[i].reckonedNonce++
gas, err := cnsc.EstimateGas(ctx, &consensus.EstimateGasRequest{
Caller: entityAccs[i].signer.Public(),
Transaction: tx,
})
if err != nil {
return fmt.Errorf("failed to estimate gas: %w", err)
}
tx.Fee.Gas = gas
feeAmount := int64(gas) * gasPrice
if err = tx.Fee.Amount.FromInt64(feeAmount); err != nil {
return fmt.Errorf("fee amount from int64: %w", err)
}

// Fund entity account to cover registration fees.
if err = transferFunds(ctx, registrationLogger, cnsc, fundingAccount, entityAccs[i].signer.Public(), feeAmount); err != nil {
return fmt.Errorf("account funding failure: %w", err)
}

signedTx, err := transaction.Sign(entityAccs[i].signer, tx)
if err != nil {
return fmt.Errorf("transaction.Sign: %w", err)
}
if err = cnsc.SubmitTx(ctx, signedTx); err != nil {
return fmt.Errorf("cnsc.SubmitTx: %w", err)
if err := fundSignAndSubmitTx(ctx, registrationLogger, cnsc, entityAccs[i].signer, tx, fundingAccount); err != nil {
registrationLogger.Error("failed to sign and submit regsiter entity transaction",
"tx", tx,
"signer", entityAccs[i].signer,
)
return fmt.Errorf("failed to sign and submit tx: %w", err)
}

// Register runtime.
Expand All @@ -280,31 +262,13 @@ func (r *registration) Run( // nolint: gocyclo
}

tx := registry.NewRegisterRuntimeTx(entityAccs[i].reckonedNonce, &transaction.Fee{}, sigRuntime)
gas, err := cnsc.EstimateGas(ctx, &consensus.EstimateGasRequest{
Caller: entityAccs[i].signer.Public(),
Transaction: tx,
})
if err != nil {
return fmt.Errorf("failed to estimate gas: %w", err)
}
tx.Fee.Gas = gas
feeAmount := int64(gas) * gasPrice
if err = tx.Fee.Amount.FromInt64(feeAmount); err != nil {
return fmt.Errorf("fee amount from uint64: %w", err)
}

// Fund entity account to cover entity registration fees.
if err = transferFunds(ctx, registrationLogger, cnsc, fundingAccount, entityAccs[i].signer.Public(), feeAmount); err != nil {
return fmt.Errorf("account funding failure: %w", err)
}

entityAccs[i].reckonedNonce++
signedTx, err := transaction.Sign(entityAccs[i].signer, tx)
if err != nil {
return fmt.Errorf("transaction.Sign: %w", err)
}
if err = cnsc.SubmitTx(ctx, signedTx); err != nil {
return fmt.Errorf("cnsc.SubmitTx: %w", err)
if err := fundSignAndSubmitTx(ctx, registrationLogger, cnsc, entityAccs[i].signer, tx, fundingAccount); err != nil {
registrationLogger.Error("failed to sign and submit register runtime transaction",
"tx", tx,
"signer", entityAccs[i].signer,
)
return fmt.Errorf("failed to sign and submit tx: %w", err)
}
}
}
Expand All @@ -331,35 +295,15 @@ func (r *registration) Run( // nolint: gocyclo

// Register node.
tx := registry.NewRegisterNodeTx(selectedNode.reckonedNonce, &transaction.Fee{}, sigNode)
gas, err := cnsc.EstimateGas(ctx, &consensus.EstimateGasRequest{
Caller: selectedNode.id.NodeSigner.Public(),
Transaction: tx,
})
if err != nil {
return fmt.Errorf("failed to estimate gas: %w", err)
}
tx.Fee.Gas = gas
feeAmount := gas * gasPrice
if err = tx.Fee.Amount.FromUint64(uint64(feeAmount)); err != nil {
return fmt.Errorf("fee amount from uint64: %w", err)
}

// Fund node account to cover registration fees.
if err = transferFunds(ctx, registrationLogger, cnsc, fundingAccount, selectedNode.id.NodeSigner.Public(), int64(feeAmount)); err != nil {
return fmt.Errorf("account funding failure: %w", err)
}
selectedNode.reckonedNonce++

signedTx, err := transaction.Sign(selectedNode.id.NodeSigner, tx)
if err != nil {
return fmt.Errorf("transaction.Sign: %w", err)
}
registrationLogger.Debug("submitting registration",
"node", selectedNode.nodeDesc,
)
if err = cnsc.SubmitTx(ctx, signedTx); err != nil {
return fmt.Errorf("cnsc.SubmitTx: %w", err)
if err := fundSignAndSubmitTx(ctx, registrationLogger, cnsc, selectedNode.id.NodeSigner, tx, fundingAccount); err != nil {
registrationLogger.Error("failed to sign and submit register node transaction",
"tx", tx,
"signer", selectedNode.id.NodeSigner,
)
return fmt.Errorf("failed to sign and submit tx: %w", err)
}

registrationLogger.Debug("registered node",
"node", selectedNode.nodeDesc,
)
Expand Down
54 changes: 54 additions & 0 deletions go/oasis-node/cmd/debug/txsource/workload/workload.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,60 @@ func FundAccountFromTestEntity(ctx context.Context, logger *logging.Logger, cnsc
return transferFunds(ctx, logger, cnsc, testEntitySigner, to, fundAccountAmount)
}

func fundSignAndSubmitTx(ctx context.Context, logger *logging.Logger, cnsc consensus.ClientBackend, caller signature.Signer, tx *transaction.Transaction, fundingAccount signature.Signer) error {
// Estimate gas needed if not set.
if tx.Fee.Gas == 0 {
gas, err := cnsc.EstimateGas(ctx, &consensus.EstimateGasRequest{
Caller: caller.Public(),
Transaction: tx,
})
if err != nil {
return fmt.Errorf("failed to estimate gas: %w", err)
}
tx.Fee.Gas = gas
}

// Fund caller to cover transaction fees.
feeAmount := int64(tx.Fee.Gas) * gasPrice
if err := tx.Fee.Amount.FromInt64(feeAmount); err != nil {
return fmt.Errorf("fee amount from int64: %w", err)
}
if err := transferFunds(ctx, logger, cnsc, fundingAccount, caller.Public(), feeAmount); err != nil {
return fmt.Errorf("account funding failure: %w", err)
}

// Sign tx.
signedTx, err := transaction.Sign(caller, tx)
if err != nil {
return fmt.Errorf("transaction.Sign: %w", err)
}

logger.Debug("submitting transaction",
"tx", tx,
"signed_tx", signedTx,
"caller", caller,
)

// SubmitTx.
// Wait for a maximum of 60 seconds to submit transaction.
submitCtx, cancel := context.WithTimeout(ctx, 60*time.Second)
err = cnsc.SubmitTx(submitCtx, signedTx)
switch err {
case nil:
cancel()
return nil
default:
cancel()
logger.Error("failed to submit transaction",
"err", err,
"tx", tx,
"signed_tx", signedTx,
"caller", caller,
)
return fmt.Errorf("cnsc.SubmitTx: %w", err)
}
}

// transferFunds transfer funds between accounts.
func transferFunds(ctx context.Context, logger *logging.Logger, cnsc consensus.ClientBackend, from signature.Signer, to signature.PublicKey, transferAmount int64) error {
sched := backoff.NewExponentialBackOff()
Expand Down

0 comments on commit 8c42399

Please sign in to comment.