mirror of
https://github.com/hyperledger/fabric-samples.git
synced 2026-06-22 17:45:10 +00:00
fix: harden token quantity parsing boundaries and enforce zero-output interception logic
Signed-off-by: Madhu Sripada <madhu.s.sripada@gmail.com> Signed-off-by: Madhu18S <madhu.s.sripada@gmail.com>
This commit is contained in:
parent
b1a8117c6f
commit
da9245aa5f
2 changed files with 26 additions and 7 deletions
|
|
@ -39,14 +39,29 @@ func (v *AuditView) Call(context view.Context) (interface{}, error) {
|
||||||
}
|
}
|
||||||
auditor := ttx.NewAuditor(context, w)
|
auditor := ttx.NewAuditor(context, w)
|
||||||
|
|
||||||
// Validate
|
// Validate structural proofs
|
||||||
err = auditor.Validate(tx)
|
err = auditor.Validate(tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.Wrapf(err, "transaction invalid: [%s]", tx.ID())
|
err = errors.Wrapf(err, "transaction invalid: [%s]", tx.ID())
|
||||||
logger.Error(err.Error())
|
logger.Error(err.Error())
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
// See https://github.com/hyperledger-labs/fabric-token-sdk/blob/main/samples/fungible/views/auditor.go for examples of auditor checks
|
|
||||||
|
// Technical Interception Layer: Assert total outputs match transactional bounds
|
||||||
|
// This ensures our runtime state adheres strictly to non-zero, sound parameters.
|
||||||
|
outputs, err := tx.Outputs()
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "failed extracting transaction outputs for tracking audit")
|
||||||
|
logger.Error(err.Error())
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reject empty or unpopulated transfer actions explicitly at the application layer
|
||||||
|
if outputs.Count() == 0 {
|
||||||
|
err = errors.Errorf("transaction rejected: [%s] contains no valid outputs", tx.ID())
|
||||||
|
logger.Error(err.Error())
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
logger.Infof("transaction valid: [%s]", tx.ID())
|
logger.Infof("transaction valid: [%s]", tx.ID())
|
||||||
res, err := context.RunView(ttx.NewAuditApproveView(w, tx))
|
res, err := context.RunView(ttx.NewAuditApproveView(w, tx))
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import (
|
||||||
|
|
||||||
// SERVICE
|
// SERVICE
|
||||||
type BalanceByWallet map[string]ValueByTokenType
|
type BalanceByWallet map[string]ValueByTokenType
|
||||||
type ValueByTokenType map[string]int64
|
type ValueByTokenType map[string]uint64 // Changed value type from int64 to uint64 to eliminate signed overflow anomalies
|
||||||
|
|
||||||
// GetAllBalances returns a map of all wallets with their balances per token type
|
// GetAllBalances returns a map of all wallets with their balances per token type
|
||||||
func (s TokenService) GetAllBalances() (walletBalance BalanceByWallet, err error) {
|
func (s TokenService) GetAllBalances() (walletBalance BalanceByWallet, err error) {
|
||||||
|
|
@ -53,17 +53,21 @@ func (s TokenService) GetBalance(wallet string, tokenType string) (typeVal Value
|
||||||
}
|
}
|
||||||
|
|
||||||
unspentTokens, err := w.ListUnspentTokens(ttx.WithType(tokenType))
|
unspentTokens, err := w.ListUnspentTokens(ttx.WithType(tokenType))
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed listing unspent tokens")
|
||||||
|
}
|
||||||
if len(unspentTokens.Tokens) == 0 {
|
if len(unspentTokens.Tokens) == 0 {
|
||||||
return typeVal, nil
|
return typeVal, nil
|
||||||
}
|
}
|
||||||
// Add the value of all unspent tokens in the wallet
|
|
||||||
|
// Safely accumulate the values using strict unsigned boundaries matching transfer parameters
|
||||||
for _, token := range unspentTokens.Tokens {
|
for _, token := range unspentTokens.Tokens {
|
||||||
val, err := strconv.ParseInt(token.Quantity, 0, 64)
|
val, err := strconv.ParseUint(token.Quantity, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return typeVal, errors.Wrap(err, "Error parsing token "+token.Id.String())
|
return typeVal, errors.Wrapf(err, "failed parsing token quantity for asset %s", token.Id.String())
|
||||||
}
|
}
|
||||||
typeVal[token.Type] += val
|
typeVal[token.Type] += val
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return typeVal, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue