Skip to content

Commit

Permalink
Implement lsig size pooling
Browse files Browse the repository at this point in the history
  • Loading branch information
giuliop committed Jul 7, 2024
1 parent 1b29523 commit 9d7d6a6
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 6 deletions.
13 changes: 11 additions & 2 deletions cmd/goal/clerk.go
Original file line number Diff line number Diff line change
Expand Up @@ -986,7 +986,7 @@ func assembleFileImpl(fname string, printWarnings bool) *logic.OpStream {
reportErrorf(tealAppSize, fname, len(ops.Program), config.MaxAvailableAppProgramLen)
}
} else {
if uint64(len(ops.Program)) > params.LogicSigMaxSize {
if !params.EnableLogicSigSizePooling && uint64(len(ops.Program)) > params.LogicSigMaxSize {
reportErrorf(tealLogicSigSize, fname, len(ops.Program), params.LogicSigMaxSize)
}
}
Expand Down Expand Up @@ -1179,14 +1179,19 @@ var dryrunCmd = &cobra.Command{
if timeStamp <= 0 {
timeStamp = time.Now().Unix()
}

lSigPooledSize := 0
for i, txn := range stxns {
if txn.Lsig.Blank() {
continue
}
if uint64(txn.Lsig.Len()) > params.LogicSigMaxSize {
lsigLen := txn.Lsig.Len()
lSigPooledSize += lsigLen
if !params.EnableLogicSigSizePooling && uint64(lsigLen) > params.LogicSigMaxSize {
reportErrorf("program size too large: %d > %d", len(txn.Lsig.Logic), params.LogicSigMaxSize)
}
ep := logic.NewSigEvalParams(stxns, &params, logic.NoHeaderLedger{})

err := logic.CheckSignature(i, ep)
if err != nil {
reportErrorf("program failed Check: %s", err)
Expand All @@ -1204,6 +1209,10 @@ var dryrunCmd = &cobra.Command{
fmt.Fprintf(os.Stdout, "ERROR: %s\n", err.Error())
}
}
lSigMaxPooledSize := len(stxns) * int(params.LogicSigMaxSize)
if params.EnableLogicSigSizePooling && lSigPooledSize > lSigMaxPooledSize {
reportErrorf("total lsigs size too large: %d > %d", lSigPooledSize, lSigMaxPooledSize)
}

},
}
Expand Down
12 changes: 9 additions & 3 deletions config/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,13 @@ type ConsensusParams struct {
EnableAppCostPooling bool

// EnableLogicSigCostPooling specifies LogicSig budgets are pooled across a
// group. The total available is len(group) * LogicSigMaxCost)
// group. The total available is len(group) * LogicSigMaxCost
EnableLogicSigCostPooling bool

// EnableLogicSigSizePooling specifies LogicSig sizes are pooled across a
// group. The total available is len(group) * LogicSigMaxSize
EnableLogicSigSizePooling bool

// RewardUnit specifies the number of MicroAlgos corresponding to one reward
// unit.
//
Expand Down Expand Up @@ -228,7 +232,7 @@ type ConsensusParams struct {
// 0 for no support, otherwise highest version supported
LogicSigVersion uint64

// len(LogicSig.Logic) + len(LogicSig.Args[*]) must be less than this
// len(LogicSig.Logic) + len(LogicSig.Args[*]) must be less than this (unless pooling is enabled)
LogicSigMaxSize uint64

// sum of estimated op cost must be less than this
Expand Down Expand Up @@ -765,7 +769,7 @@ func checkSetAllocBounds(p ConsensusParams) {
checkSetMax(p.MaxAppProgramLen, &MaxStateDeltaKeys)
checkSetMax(p.MaxAppProgramLen, &MaxEvalDeltaAccounts)
checkSetMax(p.MaxAppProgramLen, &MaxAppProgramLen)
checkSetMax(int(p.LogicSigMaxSize), &MaxLogicSigMaxSize)
checkSetMax(int(p.LogicSigMaxSize*uint64(p.MaxTxGroupSize)), &MaxLogicSigMaxSize)
checkSetMax(p.MaxTxnNoteBytes, &MaxTxnNoteBytes)
checkSetMax(p.MaxTxGroupSize, &MaxTxGroupSize)
// MaxBytesKeyValueLen is max of MaxAppKeyLen and MaxAppBytesValueLen
Expand Down Expand Up @@ -1512,6 +1516,8 @@ func initConsensusProtocols() {

vFuture.LogicSigVersion = 11 // When moving this to a release, put a new higher LogicSigVersion here

vFuture.EnableLogicSigSizePooling = true

vFuture.Payouts.Enabled = true
vFuture.Payouts.Percent = 75
vFuture.Payouts.GoOnlineFee = 2_000_000 // 2 algos
Expand Down
15 changes: 14 additions & 1 deletion data/transactions/verify/txn.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ func txnGroupBatchPrep(stxs []transactions.SignedTxn, contextHdr *bookkeeping.Bl

minFeeCount := uint64(0)
feesPaid := uint64(0)
lSigPooledSize := 0
for i, stxn := range stxs {
prepErr := txnBatchPrep(i, groupCtx, verifier)
if prepErr != nil {
Expand All @@ -225,6 +226,18 @@ func txnGroupBatchPrep(stxs []transactions.SignedTxn, contextHdr *bookkeeping.Bl
minFeeCount++
}
feesPaid = basics.AddSaturate(feesPaid, stxn.Txn.Fee.Raw)
lSigPooledSize += stxn.Lsig.Len()
}
if groupCtx.consensusParams.EnableLogicSigSizePooling {
lSigMaxPooledSize := len(stxs) * int(groupCtx.consensusParams.LogicSigMaxSize)
if lSigPooledSize > lSigMaxPooledSize {
errorMsg := fmt.Sprintf(
"txgroup had %d bytes of LogicSigs, more than the available pool of %d bytes",
lSigPooledSize, lSigMaxPooledSize,
)
err = &TxGroupError{err: errors.New(errorMsg), GroupIndex: -1, Reason: TxGroupErrorReasonLogicSigFailed}
return nil, err
}
}
feeNeeded, overflow := basics.OMul(groupCtx.consensusParams.MinTxnFee, minFeeCount)
if overflow {
Expand Down Expand Up @@ -361,7 +374,7 @@ func logicSigSanityCheckBatchPrep(gi int, groupCtx *GroupContext, batchVerifier
if version > groupCtx.consensusParams.LogicSigVersion {
return errors.New("LogicSig.Logic version too new")
}
if uint64(lsig.Len()) > groupCtx.consensusParams.LogicSigMaxSize {
if !groupCtx.consensusParams.EnableLogicSigSizePooling && uint64(lsig.Len()) > groupCtx.consensusParams.LogicSigMaxSize {
return errors.New("LogicSig.Logic too long")
}

Expand Down

0 comments on commit 9d7d6a6

Please sign in to comment.