github.com/ava-labs/avalanchego@v1.11.11/vms/components/gas/state.go (about)

     1  // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
     2  // See the file LICENSE for licensing terms.
     3  
     4  package gas
     5  
     6  import (
     7  	"errors"
     8  	"math"
     9  
    10  	safemath "github.com/ava-labs/avalanchego/utils/math"
    11  )
    12  
    13  var ErrInsufficientCapacity = errors.New("insufficient capacity")
    14  
    15  type State struct {
    16  	Capacity Gas `serialize:"true" json:"capacity"`
    17  	Excess   Gas `serialize:"true" json:"excess"`
    18  }
    19  
    20  // AdvanceTime adds maxPerSecond to capacity and subtracts targetPerSecond
    21  // from excess over the provided duration.
    22  //
    23  // Capacity is capped at maxCapacity.
    24  // Excess to be removed is capped at excess.
    25  func (s State) AdvanceTime(
    26  	maxCapacity Gas,
    27  	maxPerSecond Gas,
    28  	targetPerSecond Gas,
    29  	duration uint64,
    30  ) State {
    31  	return State{
    32  		Capacity: min(
    33  			s.Capacity.AddPerSecond(maxPerSecond, duration),
    34  			maxCapacity,
    35  		),
    36  		Excess: s.Excess.SubPerSecond(targetPerSecond, duration),
    37  	}
    38  }
    39  
    40  // ConsumeGas removes gas from capacity and adds gas to excess.
    41  //
    42  // If the capacity is insufficient, an error is returned.
    43  // If the excess would overflow, it is capped at MaxUint64.
    44  func (s State) ConsumeGas(gas Gas) (State, error) {
    45  	newCapacity, err := safemath.Sub(uint64(s.Capacity), uint64(gas))
    46  	if err != nil {
    47  		return State{}, ErrInsufficientCapacity
    48  	}
    49  
    50  	newExcess, err := safemath.Add(uint64(s.Excess), uint64(gas))
    51  	if err != nil {
    52  		//nolint:nilerr // excess is capped at MaxUint64
    53  		return State{
    54  			Capacity: Gas(newCapacity),
    55  			Excess:   math.MaxUint64,
    56  		}, nil
    57  	}
    58  
    59  	return State{
    60  		Capacity: Gas(newCapacity),
    61  		Excess:   Gas(newExcess),
    62  	}, nil
    63  }