github.com/mavryk-network/mvgo@v1.19.9/mavryk/params.go (about) 1 // Copyright (c) 2020-2024 Blockwatch Data Inc. 2 // Author: alex@blockwatch.cc 3 4 package mavryk 5 6 import ( 7 "time" 8 ) 9 10 var ( 11 // DefaultParams defines the blockchain configuration for Mainnet under the latest 12 // protocol. It is used to generate compliant transaction encodings. To change, 13 // either overwrite this default or set custom params per operation using 14 // op.WithParams(). 15 DefaultParams = (&Params{ 16 MinimalBlockDelay: 10 * time.Second, 17 CostPerByte: 250, 18 OriginationSize: 257, 19 HardGasLimitPerOperation: 1040000, 20 HardGasLimitPerBlock: 1733333, 21 HardStorageLimitPerOperation: 60000, 22 MaxOperationDataLength: 32768, 23 MaxOperationsTTL: 360, 24 }). 25 WithChainId(Mainnet). 26 WithDeployment(Deployments[Mainnet].AtProtocol(ProtoV002)) 27 28 // BasenetParams defines the blockchain configuration for Basenet testnet. 29 // To produce compliant transactions, use these defaults in op.WithParams(). 30 BasenetParams = (&Params{ 31 MinimalBlockDelay: 8 * time.Second, 32 CostPerByte: 250, 33 OriginationSize: 257, 34 HardGasLimitPerOperation: 1040000, 35 HardGasLimitPerBlock: 1733333, 36 HardStorageLimitPerOperation: 60000, 37 MaxOperationDataLength: 32768, 38 MaxOperationsTTL: 360, 39 }). 40 WithChainId(Basenet). 41 WithDeployment(Deployments[Basenet].AtProtocol(ProtoV002)) 42 43 // AtlasnetParams defines the blockchain configuration for Atlas testnet. 44 // To produce compliant transactions, use these defaults in op.WithParams(). 45 AtlasnetParams = (&Params{ 46 MinimalBlockDelay: 8 * time.Second, 47 CostPerByte: 250, 48 OriginationSize: 257, 49 HardGasLimitPerOperation: 1040000, 50 HardGasLimitPerBlock: 1733333, 51 HardStorageLimitPerOperation: 60000, 52 MaxOperationDataLength: 32768, 53 MaxOperationsTTL: 360, 54 }). 55 WithChainId(Atlasnet). 56 WithDeployment(Deployments[Atlasnet].AtProtocol(ProtoV001)) 57 58 // BoreasnetParams defines the blockchain configuration for Paris testnet. 59 // To produce compliant transactions, use these defaults in op.WithParams(). 60 BoreasnetParams = (&Params{ 61 MinimalBlockDelay: 5 * time.Second, 62 CostPerByte: 250, 63 OriginationSize: 257, 64 HardGasLimitPerOperation: 1040000, 65 HardGasLimitPerBlock: 1733333, 66 HardStorageLimitPerOperation: 60000, 67 MaxOperationDataLength: 32768, 68 MaxOperationsTTL: 360, 69 }). 70 WithChainId(Boreasnet). 71 WithDeployment(Deployments[Boreasnet].AtProtocol(ProtoV002)) 72 ) 73 74 // Params contains a subset of protocol configuration settings that are relevant 75 // for dapps and most indexers. For additional protocol data, call rpc.GetCustomConstants() 76 // with a custom data struct. 77 type Params struct { 78 // identity 79 Network string `json:"network,omitempty"` 80 ChainId ChainIdHash `json:"chain_id"` 81 Protocol ProtocolHash `json:"protocol"` 82 Version int `json:"version"` 83 84 // timing 85 MinimalBlockDelay time.Duration `json:"minimal_block_delay"` 86 87 // costs 88 CostPerByte int64 `json:"cost_per_byte"` 89 OriginationSize int64 `json:"origination_size"` 90 91 // limits 92 BlocksPerCycle int64 `json:"blocks_per_cycle"` 93 ConsensusRightsDelay int64 `json:"consensus_rights_delay"` 94 BlocksPerSnapshot int64 `json:"blocks_per_snapshot"` 95 HardGasLimitPerOperation int64 `json:"hard_gas_limit_per_operation"` 96 HardGasLimitPerBlock int64 `json:"hard_gas_limit_per_block"` 97 HardStorageLimitPerOperation int64 `json:"hard_storage_limit_per_operation"` 98 MaxOperationDataLength int `json:"max_operation_data_length"` 99 MaxOperationsTTL int64 `json:"max_operations_ttl"` 100 101 // extra features to follow protocol upgrades 102 OperationTagsVersion int `json:"operation_tags_version,omitempty"` // 1: v5..v11, 2: v12..v18, 3:v19+ 103 StartHeight int64 `json:"start_height"` // protocol start (may be != cycle start!!) 104 EndHeight int64 `json:"end_height"` // protocol end (may be != cycle end!!) 105 StartOffset int64 `json:"start_offset"` // correction for cycle start 106 StartCycle int64 `json:"start_cycle"` // correction cycle length 107 } 108 109 func NewParams() *Params { 110 return &Params{ 111 Network: "unknown", 112 StartHeight: 1<<63 - 1, 113 } 114 } 115 116 func (p Params) Clone() *Params { 117 np := p 118 return &np 119 } 120 121 func (p *Params) WithChainId(id ChainIdHash) *Params { 122 p.ChainId = id 123 if p.Network == "unknown" || p.Network == "" { 124 switch id { 125 case Mainnet: 126 p.Network = "Mainnet" 127 case Basenet: 128 p.Network = "Basenet" 129 case Atlasnet: 130 p.Network = "Atlasnet" 131 case Boreasnet: 132 p.Network = "Boreasnet" 133 } 134 } 135 return p 136 } 137 138 func (p *Params) WithProtocol(h ProtocolHash) *Params { 139 var ok bool 140 p.Protocol = h 141 versionsMtx.RLock() 142 p.Version, ok = Versions[h] 143 versionsMtx.RUnlock() 144 if !ok { 145 var max int 146 for _, v := range Versions { 147 if v < max { 148 continue 149 } 150 max = v 151 } 152 p.Version = max + 1 153 versionsMtx.Lock() 154 defer versionsMtx.Unlock() 155 Versions[h] = p.Version 156 } 157 switch { 158 case p.Version > 18: 159 p.OperationTagsVersion = 3 160 case p.Version > 11: 161 p.OperationTagsVersion = 2 162 case p.Version > 4: 163 p.OperationTagsVersion = 1 164 } 165 return p 166 } 167 168 func (p *Params) WithNetwork(n string) *Params { 169 if p.Network == "unknown" || p.Network == "" { 170 p.Network = n 171 } 172 return p 173 } 174 175 func (p *Params) WithDeployment(d Deployment) *Params { 176 if d.BlocksPerCycle > 0 { 177 p.WithProtocol(d.Protocol) 178 p.StartOffset = d.StartOffset 179 p.StartHeight = d.StartHeight 180 p.EndHeight = d.EndHeight 181 p.StartCycle = d.StartCycle 182 p.ConsensusRightsDelay = d.ConsensusRightsDelay 183 p.BlocksPerCycle = d.BlocksPerCycle 184 p.BlocksPerSnapshot = d.BlocksPerSnapshot 185 } 186 return p 187 } 188 189 func (p *Params) WithBlock(height int64) *Params { 190 d := Deployments[p.ChainId].AtBlock(height) 191 p.StartOffset = d.StartOffset 192 p.StartHeight = d.StartHeight 193 p.EndHeight = d.EndHeight 194 p.StartCycle = d.StartCycle 195 return p 196 } 197 198 func (p *Params) AtBlock(height int64) *Params { 199 if p.ContainsHeight(height) { 200 return p 201 } 202 return p.Clone().WithDeployment(Deployments[p.ChainId].AtBlock(height)) 203 } 204 205 func (p *Params) AtCycle(cycle int64) *Params { 206 if p.ContainsCycle(cycle) { 207 return p 208 } 209 return p.Clone().WithDeployment(Deployments[p.ChainId].AtCycle(cycle)) 210 } 211 212 func (p Params) SnapshotBaseCycle(cycle int64) int64 { 213 var offset int64 = 2 214 if p.Version >= 12 { 215 offset = 1 216 } 217 return cycle - (p.ConsensusRightsDelay + offset) 218 } 219 220 func (p Params) IsMainnet() bool { 221 return p.ChainId.Equal(Mainnet) 222 } 223 224 // Note: functions below require StartHeight, EndHeight and/or StartCycle! 225 func (p Params) ContainsHeight(height int64) bool { 226 // treat -1 as special height query that matches open interval params only 227 return (height < 0 && p.EndHeight < 0) || 228 (p.StartHeight <= height && (p.EndHeight < 0 || p.EndHeight >= height)) 229 } 230 231 func (p Params) ContainsCycle(c int64) bool { 232 // FIX granada early start 233 s := p.StartCycle 234 if c == 387 && p.IsMainnet() { 235 s-- 236 } 237 return s <= c 238 } 239 240 func (p *Params) CycleFromHeight(height int64) int64 { 241 // adjust to target height 242 at := p.AtBlock(height) 243 244 // FIX granada early start 245 s := at.StartCycle 246 if height == 1589248 && at.IsMainnet() { 247 s-- 248 } 249 return s + (height-(at.StartHeight-at.StartOffset))/at.BlocksPerCycle 250 } 251 252 func (p *Params) CycleStartHeight(c int64) int64 { 253 // adjust to target cycle 254 at := p.AtCycle(c) 255 res := at.StartHeight - at.StartOffset + (c-at.StartCycle)*at.BlocksPerCycle 256 return res 257 } 258 259 func (p *Params) CycleEndHeight(c int64) int64 { 260 // adjust to target cycle 261 at := p.AtCycle(c) 262 return at.CycleStartHeight(c) + at.BlocksPerCycle - 1 263 } 264 265 func (p *Params) CyclePosition(height int64) int64 { 266 // adjust to target height 267 at := p.AtBlock(height) 268 pos := (height - (at.StartHeight - at.StartOffset)) % at.BlocksPerCycle 269 if pos < 0 { 270 pos += at.BlocksPerCycle 271 } 272 return pos 273 } 274 275 func (p *Params) IsCycleStart(height int64) bool { 276 return height > 0 && (height == 1 || p.CyclePosition(height) == 0) 277 } 278 279 func (p *Params) IsCycleEnd(height int64) bool { 280 // adjust to target height 281 at := p.AtBlock(height) 282 return at.CyclePosition(height)+1 == at.BlocksPerCycle 283 } 284 285 func (p *Params) IsSnapshotBlock(height int64) bool { 286 // no more snapshots in Paris 287 if p.Version > 18 && p.IsCycleEnd(height) { 288 return true 289 } 290 291 // adjust to target height 292 at := p.AtBlock(height) 293 pos := at.CyclePosition(height) + 1 294 return pos > 0 && pos%at.BlocksPerSnapshot == 0 295 } 296 297 func (p *Params) SnapshotBlock(cycle int64, index int) int64 { 298 // adjust to target cycle 299 at := p.AtCycle(cycle) 300 base := at.SnapshotBaseCycle(cycle) 301 if base < 0 { 302 return 0 303 } 304 offset := int64(index+1) * at.BlocksPerSnapshot 305 if offset > at.BlocksPerCycle { 306 offset = at.BlocksPerCycle 307 } 308 return at.CycleStartHeight(base) + offset - 1 309 } 310 311 func (p *Params) SnapshotIndex(height int64) int { 312 // no more snapshots in Paris 313 if p.Version > 18 { 314 return 15 315 } 316 // FIX granada early start 317 if height == 1589248 && p.IsMainnet() { 318 return 15 319 } 320 // adjust to target height 321 at := p.AtBlock(height) 322 return int((at.CyclePosition(height)+1)/at.BlocksPerSnapshot) - 1 323 }