github.com/onflow/flow-go@v0.33.17/utils/unittest/fixtures.go (about) 1 package unittest 2 3 import ( 4 "bytes" 5 crand "crypto/rand" 6 "fmt" 7 "math/rand" 8 "net" 9 "testing" 10 "time" 11 12 "github.com/ipfs/go-cid" 13 pubsub "github.com/libp2p/go-libp2p-pubsub" 14 pubsub_pb "github.com/libp2p/go-libp2p-pubsub/pb" 15 "github.com/libp2p/go-libp2p/core/peer" 16 "github.com/onflow/cadence" 17 "github.com/stretchr/testify/require" 18 19 sdk "github.com/onflow/flow-go-sdk" 20 hotstuff "github.com/onflow/flow-go/consensus/hotstuff/model" 21 "github.com/onflow/flow-go/crypto" 22 "github.com/onflow/flow-go/crypto/hash" 23 "github.com/onflow/flow-go/engine" 24 "github.com/onflow/flow-go/engine/access/rest/util" 25 "github.com/onflow/flow-go/fvm/storage/snapshot" 26 "github.com/onflow/flow-go/ledger" 27 "github.com/onflow/flow-go/ledger/common/bitutils" 28 "github.com/onflow/flow-go/ledger/common/testutils" 29 "github.com/onflow/flow-go/model/bootstrap" 30 "github.com/onflow/flow-go/model/chainsync" 31 "github.com/onflow/flow-go/model/chunks" 32 "github.com/onflow/flow-go/model/cluster" 33 "github.com/onflow/flow-go/model/encoding" 34 "github.com/onflow/flow-go/model/flow" 35 "github.com/onflow/flow-go/model/flow/filter" 36 "github.com/onflow/flow-go/model/messages" 37 "github.com/onflow/flow-go/model/verification" 38 "github.com/onflow/flow-go/module" 39 "github.com/onflow/flow-go/module/executiondatasync/execution_data" 40 "github.com/onflow/flow-go/module/mempool/entity" 41 "github.com/onflow/flow-go/module/signature" 42 "github.com/onflow/flow-go/module/updatable_configs" 43 "github.com/onflow/flow-go/network/channels" 44 "github.com/onflow/flow-go/network/message" 45 p2pconfig "github.com/onflow/flow-go/network/p2p/config" 46 "github.com/onflow/flow-go/network/p2p/keyutils" 47 "github.com/onflow/flow-go/state/protocol" 48 "github.com/onflow/flow-go/state/protocol/inmem" 49 "github.com/onflow/flow-go/utils/dsl" 50 ) 51 52 const ( 53 DefaultSeedFixtureLength = 64 54 DefaultAddress = "localhost:0" 55 ) 56 57 // returns a deterministic math/rand PRG that can be used for deterministic randomness in tests only. 58 // The PRG seed is logged in case the test iteration needs to be reproduced. 59 func GetPRG(t *testing.T) *rand.Rand { 60 random := time.Now().UnixNano() 61 t.Logf("rng seed is %d", random) 62 rng := rand.New(rand.NewSource(random)) 63 return rng 64 } 65 66 func IPPort(port string) string { 67 return net.JoinHostPort("localhost", port) 68 } 69 70 func AddressFixture() flow.Address { 71 return flow.Testnet.Chain().ServiceAddress() 72 } 73 74 func RandomAddressFixture() flow.Address { 75 return RandomAddressFixtureForChain(flow.Testnet) 76 } 77 78 func RandomAddressFixtureForChain(chainID flow.ChainID) flow.Address { 79 // we use a 32-bit index - since the linear address generator uses 45 bits, 80 // this won't error 81 addr, err := chainID.Chain().AddressAtIndex(uint64(rand.Uint32())) 82 if err != nil { 83 panic(err) 84 } 85 return addr 86 } 87 88 // Uint64InRange returns a uint64 value drawn from the uniform random distribution [min,max]. 89 func Uint64InRange(min, max uint64) uint64 { 90 return min + uint64(rand.Intn(int(max)+1-int(min))) 91 } 92 93 func RandomSDKAddressFixture() sdk.Address { 94 addr := RandomAddressFixture() 95 var sdkAddr sdk.Address 96 copy(sdkAddr[:], addr[:]) 97 return sdkAddr 98 } 99 100 func InvalidAddressFixture() flow.Address { 101 addr := AddressFixture() 102 addr[0] ^= 1 // alter one bit to obtain an invalid address 103 if flow.Testnet.Chain().IsValid(addr) { 104 panic("invalid address fixture generated valid address") 105 } 106 return addr 107 } 108 109 func InvalidFormatSignature() flow.TransactionSignature { 110 return flow.TransactionSignature{ 111 Address: AddressFixture(), 112 SignerIndex: 0, 113 Signature: make([]byte, crypto.SignatureLenECDSAP256), // zero signature is invalid 114 KeyIndex: 1, 115 } 116 } 117 118 func TransactionSignatureFixture() flow.TransactionSignature { 119 sigLen := crypto.SignatureLenECDSAP256 120 s := flow.TransactionSignature{ 121 Address: AddressFixture(), 122 SignerIndex: 0, 123 Signature: SeedFixture(sigLen), 124 KeyIndex: 1, 125 } 126 // make sure the ECDSA signature passes the format check 127 s.Signature[sigLen/2] = 0 128 s.Signature[0] = 0 129 s.Signature[sigLen/2-1] |= 1 130 s.Signature[sigLen-1] |= 1 131 return s 132 } 133 134 func ProposalKeyFixture() flow.ProposalKey { 135 return flow.ProposalKey{ 136 Address: AddressFixture(), 137 KeyIndex: 1, 138 SequenceNumber: 0, 139 } 140 } 141 142 // AccountKeyDefaultFixture returns a randomly generated ECDSA/SHA3 account key. 143 func AccountKeyDefaultFixture() (*flow.AccountPrivateKey, error) { 144 return AccountKeyFixture(crypto.KeyGenSeedMinLen, crypto.ECDSAP256, hash.SHA3_256) 145 } 146 147 // AccountKeyFixture returns a randomly generated account key. 148 func AccountKeyFixture( 149 seedLength int, 150 signingAlgo crypto.SigningAlgorithm, 151 hashAlgo hash.HashingAlgorithm, 152 ) (*flow.AccountPrivateKey, error) { 153 seed := make([]byte, seedLength) 154 155 _, err := crand.Read(seed) 156 if err != nil { 157 return nil, err 158 } 159 160 key, err := crypto.GeneratePrivateKey(signingAlgo, seed) 161 if err != nil { 162 return nil, err 163 } 164 165 return &flow.AccountPrivateKey{ 166 PrivateKey: key, 167 SignAlgo: key.Algorithm(), 168 HashAlgo: hashAlgo, 169 }, nil 170 } 171 172 // AccountFixture returns a randomly generated account. 173 func AccountFixture() (*flow.Account, error) { 174 key, err := AccountKeyFixture(128, crypto.ECDSAP256, hash.SHA3_256) 175 if err != nil { 176 return nil, err 177 } 178 179 contracts := make(map[string][]byte, 2) 180 contracts["contract1"] = []byte("contract1") 181 contracts["contract2"] = []byte("contract2") 182 183 return &flow.Account{ 184 Address: RandomAddressFixture(), 185 Balance: 100, 186 Keys: []flow.AccountPublicKey{key.PublicKey(1000)}, 187 Contracts: contracts, 188 }, nil 189 } 190 191 func BlockFixture() flow.Block { 192 header := BlockHeaderFixture() 193 return *BlockWithParentFixture(header) 194 } 195 196 func FullBlockFixture() flow.Block { 197 block := BlockFixture() 198 payload := block.Payload 199 payload.Seals = Seal.Fixtures(10) 200 payload.Results = []*flow.ExecutionResult{ 201 ExecutionResultFixture(), 202 ExecutionResultFixture(), 203 } 204 payload.Receipts = []*flow.ExecutionReceiptMeta{ 205 ExecutionReceiptFixture(WithResult(payload.Results[0])).Meta(), 206 ExecutionReceiptFixture(WithResult(payload.Results[1])).Meta(), 207 } 208 209 header := block.Header 210 header.PayloadHash = payload.Hash() 211 212 return flow.Block{ 213 Header: header, 214 Payload: payload, 215 } 216 } 217 218 func BlockFixtures(number int) []*flow.Block { 219 blocks := make([]*flow.Block, 0, number) 220 for ; number > 0; number-- { 221 block := BlockFixture() 222 blocks = append(blocks, &block) 223 } 224 return blocks 225 } 226 227 func ProposalFixture() *messages.BlockProposal { 228 block := BlockFixture() 229 return ProposalFromBlock(&block) 230 } 231 232 func ProposalFromBlock(block *flow.Block) *messages.BlockProposal { 233 return messages.NewBlockProposal(block) 234 } 235 236 func ClusterProposalFromBlock(block *cluster.Block) *messages.ClusterBlockProposal { 237 return messages.NewClusterBlockProposal(block) 238 } 239 240 func BlockchainFixture(length int) []*flow.Block { 241 blocks := make([]*flow.Block, length) 242 243 genesis := BlockFixture() 244 blocks[0] = &genesis 245 for i := 1; i < length; i++ { 246 blocks[i] = BlockWithParentFixture(blocks[i-1].Header) 247 } 248 249 return blocks 250 } 251 252 // AsSlashable returns the input message T, wrapped as a flow.Slashable instance with a random origin ID. 253 func AsSlashable[T any](msg T) flow.Slashable[T] { 254 slashable := flow.Slashable[T]{ 255 OriginID: IdentifierFixture(), 256 Message: msg, 257 } 258 return slashable 259 } 260 261 func ReceiptAndSealForBlock(block *flow.Block) (*flow.ExecutionReceipt, *flow.Seal) { 262 receipt := ReceiptForBlockFixture(block) 263 seal := Seal.Fixture(Seal.WithBlock(block.Header), Seal.WithResult(&receipt.ExecutionResult)) 264 return receipt, seal 265 } 266 267 func PayloadFixture(options ...func(*flow.Payload)) flow.Payload { 268 payload := flow.EmptyPayload() 269 for _, option := range options { 270 option(&payload) 271 } 272 return payload 273 } 274 275 // WithAllTheFixins ensures a payload contains no empty slice fields. When 276 // encoding and decoding, nil vs empty slices are not preserved, which can 277 // result in two models that are semantically equal being considered non-equal 278 // by our testing framework. 279 func WithAllTheFixins(payload *flow.Payload) { 280 payload.Seals = Seal.Fixtures(3) 281 payload.Guarantees = CollectionGuaranteesFixture(4) 282 for i := 0; i < 10; i++ { 283 receipt := ExecutionReceiptFixture( 284 WithResult(ExecutionResultFixture(WithServiceEvents(3))), 285 WithSpocks(SignaturesFixture(3)), 286 ) 287 payload.Receipts = flow.ExecutionReceiptMetaList{receipt.Meta()} 288 payload.Results = flow.ExecutionResultList{&receipt.ExecutionResult} 289 } 290 } 291 292 func WithSeals(seals ...*flow.Seal) func(*flow.Payload) { 293 return func(payload *flow.Payload) { 294 payload.Seals = append(payload.Seals, seals...) 295 } 296 } 297 298 func WithGuarantees(guarantees ...*flow.CollectionGuarantee) func(*flow.Payload) { 299 return func(payload *flow.Payload) { 300 payload.Guarantees = append(payload.Guarantees, guarantees...) 301 } 302 } 303 304 func WithReceipts(receipts ...*flow.ExecutionReceipt) func(*flow.Payload) { 305 return func(payload *flow.Payload) { 306 for _, receipt := range receipts { 307 payload.Receipts = append(payload.Receipts, receipt.Meta()) 308 payload.Results = append(payload.Results, &receipt.ExecutionResult) 309 } 310 } 311 } 312 313 // WithReceiptsAndNoResults will add receipt to payload only 314 func WithReceiptsAndNoResults(receipts ...*flow.ExecutionReceipt) func(*flow.Payload) { 315 return func(payload *flow.Payload) { 316 for _, receipt := range receipts { 317 payload.Receipts = append(payload.Receipts, receipt.Meta()) 318 } 319 } 320 } 321 322 // WithExecutionResults will add execution results to payload 323 func WithExecutionResults(results ...*flow.ExecutionResult) func(*flow.Payload) { 324 return func(payload *flow.Payload) { 325 for _, result := range results { 326 payload.Results = append(payload.Results, result) 327 } 328 } 329 } 330 331 func BlockWithParentFixture(parent *flow.Header) *flow.Block { 332 payload := PayloadFixture() 333 header := BlockHeaderWithParentFixture(parent) 334 header.PayloadHash = payload.Hash() 335 return &flow.Block{ 336 Header: header, 337 Payload: &payload, 338 } 339 } 340 341 func BlockWithGuaranteesFixture(guarantees []*flow.CollectionGuarantee) *flow.Block { 342 payload := PayloadFixture(WithGuarantees(guarantees...)) 343 header := BlockHeaderFixture() 344 header.PayloadHash = payload.Hash() 345 return &flow.Block{ 346 Header: header, 347 Payload: &payload, 348 } 349 350 } 351 352 func WithoutGuarantee(payload *flow.Payload) { 353 payload.Guarantees = nil 354 } 355 356 func StateInteractionsFixture() *snapshot.ExecutionSnapshot { 357 return &snapshot.ExecutionSnapshot{} 358 } 359 360 func BlockWithParentAndProposerFixture( 361 t *testing.T, 362 parent *flow.Header, 363 proposer flow.Identifier, 364 ) flow.Block { 365 block := BlockWithParentFixture(parent) 366 367 indices, err := signature.EncodeSignersToIndices( 368 []flow.Identifier{proposer}, []flow.Identifier{proposer}) 369 require.NoError(t, err) 370 371 block.Header.ProposerID = proposer 372 block.Header.ParentVoterIndices = indices 373 if block.Header.LastViewTC != nil { 374 block.Header.LastViewTC.SignerIndices = indices 375 block.Header.LastViewTC.NewestQC.SignerIndices = indices 376 } 377 378 return *block 379 } 380 381 func BlockWithParentAndSeals(parent *flow.Header, seals []*flow.Header) *flow.Block { 382 block := BlockWithParentFixture(parent) 383 payload := flow.Payload{ 384 Guarantees: nil, 385 } 386 387 if len(seals) > 0 { 388 payload.Seals = make([]*flow.Seal, len(seals)) 389 for i, seal := range seals { 390 payload.Seals[i] = Seal.Fixture( 391 Seal.WithBlockID(seal.ID()), 392 ) 393 } 394 } 395 396 block.SetPayload(payload) 397 return block 398 } 399 400 func GenesisFixture() *flow.Block { 401 genesis := flow.Genesis(flow.Emulator) 402 return genesis 403 } 404 405 func WithHeaderHeight(height uint64) func(header *flow.Header) { 406 return func(header *flow.Header) { 407 header.Height = height 408 } 409 } 410 411 func HeaderWithView(view uint64) func(*flow.Header) { 412 return func(header *flow.Header) { 413 header.View = view 414 } 415 } 416 417 func BlockHeaderFixture(opts ...func(header *flow.Header)) *flow.Header { 418 height := 1 + uint64(rand.Uint32()) // avoiding edge case of height = 0 (genesis block) 419 view := height + uint64(rand.Intn(1000)) 420 header := BlockHeaderWithParentFixture(&flow.Header{ 421 ChainID: flow.Emulator, 422 ParentID: IdentifierFixture(), 423 Height: height, 424 View: view, 425 }) 426 427 for _, opt := range opts { 428 opt(header) 429 } 430 431 return header 432 } 433 434 func BlockHeaderFixtureOnChain( 435 chainID flow.ChainID, 436 opts ...func(header *flow.Header), 437 ) *flow.Header { 438 height := 1 + uint64(rand.Uint32()) // avoiding edge case of height = 0 (genesis block) 439 view := height + uint64(rand.Intn(1000)) 440 header := BlockHeaderWithParentFixture(&flow.Header{ 441 ChainID: chainID, 442 ParentID: IdentifierFixture(), 443 Height: height, 444 View: view, 445 }) 446 447 for _, opt := range opts { 448 opt(header) 449 } 450 451 return header 452 } 453 454 func BlockHeaderWithParentFixture(parent *flow.Header) *flow.Header { 455 height := parent.Height + 1 456 view := parent.View + 1 + uint64(rand.Intn(10)) // Intn returns [0, n) 457 var lastViewTC *flow.TimeoutCertificate 458 if view != parent.View+1 { 459 newestQC := QuorumCertificateFixture(func(qc *flow.QuorumCertificate) { 460 qc.View = parent.View 461 }) 462 lastViewTC = &flow.TimeoutCertificate{ 463 View: view - 1, 464 NewestQCViews: []uint64{newestQC.View}, 465 NewestQC: newestQC, 466 SignerIndices: SignerIndicesFixture(4), 467 SigData: SignatureFixture(), 468 } 469 } 470 return &flow.Header{ 471 ChainID: parent.ChainID, 472 ParentID: parent.ID(), 473 Height: height, 474 PayloadHash: IdentifierFixture(), 475 Timestamp: time.Now().UTC(), 476 View: view, 477 ParentView: parent.View, 478 ParentVoterIndices: SignerIndicesFixture(4), 479 ParentVoterSigData: QCSigDataFixture(), 480 ProposerID: IdentifierFixture(), 481 ProposerSigData: SignatureFixture(), 482 LastViewTC: lastViewTC, 483 } 484 } 485 486 func BlockHeaderWithParentWithSoRFixture(parent *flow.Header, source []byte) *flow.Header { 487 height := parent.Height + 1 488 view := parent.View + 1 + uint64(rand.Intn(10)) // Intn returns [0, n) 489 var lastViewTC *flow.TimeoutCertificate 490 if view != parent.View+1 { 491 newestQC := QuorumCertificateFixture(func(qc *flow.QuorumCertificate) { 492 qc.View = parent.View 493 }) 494 lastViewTC = &flow.TimeoutCertificate{ 495 View: view - 1, 496 NewestQCViews: []uint64{newestQC.View}, 497 NewestQC: newestQC, 498 SignerIndices: SignerIndicesFixture(4), 499 SigData: SignatureFixture(), 500 } 501 } 502 return &flow.Header{ 503 ChainID: parent.ChainID, 504 ParentID: parent.ID(), 505 Height: height, 506 PayloadHash: IdentifierFixture(), 507 Timestamp: time.Now().UTC(), 508 View: view, 509 ParentView: parent.View, 510 ParentVoterIndices: SignerIndicesFixture(4), 511 ParentVoterSigData: QCSigDataWithSoRFixture(source), 512 ProposerID: IdentifierFixture(), 513 ProposerSigData: SignatureFixture(), 514 LastViewTC: lastViewTC, 515 } 516 } 517 518 func ClusterPayloadFixture(n int) *cluster.Payload { 519 transactions := make([]*flow.TransactionBody, n) 520 for i := 0; i < n; i++ { 521 tx := TransactionBodyFixture() 522 transactions[i] = &tx 523 } 524 payload := cluster.PayloadFromTransactions(flow.ZeroID, transactions...) 525 return &payload 526 } 527 528 func ClusterBlockFixture() cluster.Block { 529 530 payload := ClusterPayloadFixture(3) 531 header := BlockHeaderFixture() 532 header.PayloadHash = payload.Hash() 533 534 return cluster.Block{ 535 Header: header, 536 Payload: payload, 537 } 538 } 539 540 func ClusterBlockChainFixture(n int) []cluster.Block { 541 clusterBlocks := make([]cluster.Block, 0, n) 542 543 parent := ClusterBlockFixture() 544 545 for i := 0; i < n; i++ { 546 block := ClusterBlockWithParent(&parent) 547 clusterBlocks = append(clusterBlocks, block) 548 parent = block 549 } 550 551 return clusterBlocks 552 } 553 554 // ClusterBlockWithParent creates a new cluster consensus block that is valid 555 // with respect to the given parent block. 556 func ClusterBlockWithParent(parent *cluster.Block) cluster.Block { 557 558 payload := ClusterPayloadFixture(3) 559 560 header := BlockHeaderFixture() 561 header.Height = parent.Header.Height + 1 562 header.View = parent.Header.View + 1 563 header.ChainID = parent.Header.ChainID 564 header.Timestamp = time.Now() 565 header.ParentID = parent.ID() 566 header.ParentView = parent.Header.View 567 header.PayloadHash = payload.Hash() 568 569 block := cluster.Block{ 570 Header: header, 571 Payload: payload, 572 } 573 574 return block 575 } 576 577 func WithCollRef(refID flow.Identifier) func(*flow.CollectionGuarantee) { 578 return func(guarantee *flow.CollectionGuarantee) { 579 guarantee.ReferenceBlockID = refID 580 } 581 } 582 583 func WithCollection(collection *flow.Collection) func(guarantee *flow.CollectionGuarantee) { 584 return func(guarantee *flow.CollectionGuarantee) { 585 guarantee.CollectionID = collection.ID() 586 } 587 } 588 589 func CollectionGuaranteeFixture(options ...func(*flow.CollectionGuarantee)) *flow.CollectionGuarantee { 590 guarantee := &flow.CollectionGuarantee{ 591 CollectionID: IdentifierFixture(), 592 SignerIndices: RandomBytes(16), 593 Signature: SignatureFixture(), 594 } 595 for _, option := range options { 596 option(guarantee) 597 } 598 return guarantee 599 } 600 601 func CollectionGuaranteesWithCollectionIDFixture(collections []*flow.Collection) []*flow.CollectionGuarantee { 602 guarantees := make([]*flow.CollectionGuarantee, 0, len(collections)) 603 for i := 0; i < len(collections); i++ { 604 guarantee := CollectionGuaranteeFixture(WithCollection(collections[i])) 605 guarantees = append(guarantees, guarantee) 606 } 607 return guarantees 608 } 609 610 func CollectionGuaranteesFixture( 611 n int, 612 options ...func(*flow.CollectionGuarantee), 613 ) []*flow.CollectionGuarantee { 614 guarantees := make([]*flow.CollectionGuarantee, 0, n) 615 for i := 1; i <= n; i++ { 616 guarantee := CollectionGuaranteeFixture(options...) 617 guarantees = append(guarantees, guarantee) 618 } 619 return guarantees 620 } 621 622 func BlockSealsFixture(n int) []*flow.Seal { 623 seals := make([]*flow.Seal, 0, n) 624 for i := 0; i < n; i++ { 625 seal := Seal.Fixture() 626 seals = append(seals, seal) 627 } 628 return seals 629 } 630 631 func CollectionListFixture(n int, options ...func(*flow.Collection)) []*flow.Collection { 632 collections := make([]*flow.Collection, n) 633 for i := 0; i < n; i++ { 634 collection := CollectionFixture(1, options...) 635 collections[i] = &collection 636 } 637 638 return collections 639 } 640 641 func CollectionFixture(n int, options ...func(*flow.Collection)) flow.Collection { 642 transactions := make([]*flow.TransactionBody, 0, n) 643 644 for i := 0; i < n; i++ { 645 tx := TransactionFixture() 646 transactions = append(transactions, &tx.TransactionBody) 647 } 648 649 col := flow.Collection{Transactions: transactions} 650 for _, opt := range options { 651 opt(&col) 652 } 653 return col 654 } 655 656 func FixedReferenceBlockID() flow.Identifier { 657 blockID := flow.Identifier{} 658 blockID[0] = byte(1) 659 return blockID 660 } 661 662 func CompleteCollectionFixture() *entity.CompleteCollection { 663 txBody := TransactionBodyFixture() 664 return &entity.CompleteCollection{ 665 Guarantee: &flow.CollectionGuarantee{ 666 CollectionID: flow.Collection{Transactions: []*flow.TransactionBody{&txBody}}.ID(), 667 Signature: SignatureFixture(), 668 ReferenceBlockID: FixedReferenceBlockID(), 669 SignerIndices: SignerIndicesFixture(1), 670 }, 671 Transactions: []*flow.TransactionBody{&txBody}, 672 } 673 } 674 675 func CompleteCollectionFromTransactions(txs []*flow.TransactionBody) *entity.CompleteCollection { 676 return &entity.CompleteCollection{ 677 Guarantee: &flow.CollectionGuarantee{ 678 CollectionID: flow.Collection{Transactions: txs}.ID(), 679 Signature: SignatureFixture(), 680 ReferenceBlockID: IdentifierFixture(), 681 SignerIndices: SignerIndicesFixture(3), 682 }, 683 Transactions: txs, 684 } 685 } 686 687 func ExecutableBlockFixture( 688 collectionsSignerIDs [][]flow.Identifier, 689 startState *flow.StateCommitment, 690 ) *entity.ExecutableBlock { 691 692 header := BlockHeaderFixture() 693 return ExecutableBlockFixtureWithParent(collectionsSignerIDs, header, startState) 694 } 695 696 func ExecutableBlockFixtureWithParent( 697 collectionsSignerIDs [][]flow.Identifier, 698 parent *flow.Header, 699 startState *flow.StateCommitment, 700 ) *entity.ExecutableBlock { 701 702 completeCollections := make(map[flow.Identifier]*entity.CompleteCollection, len(collectionsSignerIDs)) 703 block := BlockWithParentFixture(parent) 704 block.Payload.Guarantees = nil 705 706 for range collectionsSignerIDs { 707 completeCollection := CompleteCollectionFixture() 708 block.Payload.Guarantees = append(block.Payload.Guarantees, completeCollection.Guarantee) 709 completeCollections[completeCollection.Guarantee.CollectionID] = completeCollection 710 } 711 712 block.Header.PayloadHash = block.Payload.Hash() 713 714 executableBlock := &entity.ExecutableBlock{ 715 Block: block, 716 CompleteCollections: completeCollections, 717 StartState: startState, 718 } 719 return executableBlock 720 } 721 722 func ExecutableBlockFromTransactions( 723 chain flow.ChainID, 724 txss [][]*flow.TransactionBody, 725 ) *entity.ExecutableBlock { 726 727 completeCollections := make(map[flow.Identifier]*entity.CompleteCollection, len(txss)) 728 blockHeader := BlockHeaderFixtureOnChain(chain) 729 block := *BlockWithParentFixture(blockHeader) 730 block.Payload.Guarantees = nil 731 732 for _, txs := range txss { 733 cc := CompleteCollectionFromTransactions(txs) 734 block.Payload.Guarantees = append(block.Payload.Guarantees, cc.Guarantee) 735 completeCollections[cc.Guarantee.CollectionID] = cc 736 } 737 738 block.Header.PayloadHash = block.Payload.Hash() 739 740 executableBlock := &entity.ExecutableBlock{ 741 Block: &block, 742 CompleteCollections: completeCollections, 743 } 744 // Preload the id 745 executableBlock.ID() 746 return executableBlock 747 } 748 749 func WithExecutorID(executorID flow.Identifier) func(*flow.ExecutionReceipt) { 750 return func(er *flow.ExecutionReceipt) { 751 er.ExecutorID = executorID 752 } 753 } 754 755 func WithResult(result *flow.ExecutionResult) func(*flow.ExecutionReceipt) { 756 return func(receipt *flow.ExecutionReceipt) { 757 receipt.ExecutionResult = *result 758 } 759 } 760 761 func WithSpocks(spocks []crypto.Signature) func(*flow.ExecutionReceipt) { 762 return func(receipt *flow.ExecutionReceipt) { 763 receipt.Spocks = spocks 764 } 765 } 766 767 func ExecutionReceiptFixture(opts ...func(*flow.ExecutionReceipt)) *flow.ExecutionReceipt { 768 receipt := &flow.ExecutionReceipt{ 769 ExecutorID: IdentifierFixture(), 770 ExecutionResult: *ExecutionResultFixture(), 771 Spocks: nil, 772 ExecutorSignature: SignatureFixture(), 773 } 774 775 for _, apply := range opts { 776 apply(receipt) 777 } 778 779 return receipt 780 } 781 782 func ReceiptForBlockFixture(block *flow.Block) *flow.ExecutionReceipt { 783 return ReceiptForBlockExecutorFixture(block, IdentifierFixture()) 784 } 785 786 func ReceiptForBlockExecutorFixture( 787 block *flow.Block, 788 executor flow.Identifier, 789 ) *flow.ExecutionReceipt { 790 result := ExecutionResultFixture(WithBlock(block)) 791 receipt := ExecutionReceiptFixture(WithResult(result), WithExecutorID(executor)) 792 return receipt 793 } 794 795 func ReceiptsForBlockFixture( 796 block *flow.Block, 797 ids []flow.Identifier, 798 ) []*flow.ExecutionReceipt { 799 result := ExecutionResultFixture(WithBlock(block)) 800 var ers []*flow.ExecutionReceipt 801 for _, id := range ids { 802 ers = append(ers, ExecutionReceiptFixture(WithResult(result), WithExecutorID(id))) 803 } 804 return ers 805 } 806 807 func WithPreviousResult(prevResult flow.ExecutionResult) func(*flow.ExecutionResult) { 808 return func(result *flow.ExecutionResult) { 809 result.PreviousResultID = prevResult.ID() 810 finalState, err := prevResult.FinalStateCommitment() 811 if err != nil { 812 panic("missing final state commitment") 813 } 814 result.Chunks[0].StartState = finalState 815 } 816 } 817 818 func WithBlock(block *flow.Block) func(*flow.ExecutionResult) { 819 chunks := 1 // tailing chunk is always system chunk 820 var previousResultID flow.Identifier 821 if block.Payload != nil { 822 chunks += len(block.Payload.Guarantees) 823 } 824 blockID := block.ID() 825 826 return func(result *flow.ExecutionResult) { 827 startState := result.Chunks[0].StartState // retain previous start state in case it was user-defined 828 result.BlockID = blockID 829 result.Chunks = ChunkListFixture(uint(chunks), blockID) 830 result.Chunks[0].StartState = startState // set start state to value before update 831 result.PreviousResultID = previousResultID 832 } 833 } 834 835 func WithChunks(n uint) func(*flow.ExecutionResult) { 836 return func(result *flow.ExecutionResult) { 837 result.Chunks = ChunkListFixture(n, result.BlockID) 838 } 839 } 840 841 func ExecutionResultListFixture( 842 n int, 843 opts ...func(*flow.ExecutionResult), 844 ) []*flow.ExecutionResult { 845 results := make([]*flow.ExecutionResult, 0, n) 846 for i := 0; i < n; i++ { 847 results = append(results, ExecutionResultFixture(opts...)) 848 } 849 850 return results 851 } 852 853 func WithExecutionResultBlockID(blockID flow.Identifier) func(*flow.ExecutionResult) { 854 return func(result *flow.ExecutionResult) { 855 result.BlockID = blockID 856 for _, chunk := range result.Chunks { 857 chunk.BlockID = blockID 858 } 859 } 860 } 861 862 func WithFinalState(commit flow.StateCommitment) func(*flow.ExecutionResult) { 863 return func(result *flow.ExecutionResult) { 864 result.Chunks[len(result.Chunks)-1].EndState = commit 865 } 866 } 867 868 func WithServiceEvents(n int) func(result *flow.ExecutionResult) { 869 return func(result *flow.ExecutionResult) { 870 result.ServiceEvents = ServiceEventsFixture(n) 871 } 872 } 873 874 func WithExecutionDataID(id flow.Identifier) func(result *flow.ExecutionResult) { 875 return func(result *flow.ExecutionResult) { 876 result.ExecutionDataID = id 877 } 878 } 879 880 func ServiceEventsFixture(n int) flow.ServiceEventList { 881 sel := make(flow.ServiceEventList, n) 882 883 for i := 0; i < n; i++ { 884 switch i % 3 { 885 case 0: 886 sel[i] = EpochCommitFixture().ServiceEvent() 887 case 1: 888 sel[i] = EpochSetupFixture().ServiceEvent() 889 case 2: 890 sel[i] = VersionBeaconFixture().ServiceEvent() 891 } 892 } 893 894 return sel 895 } 896 897 func ExecutionResultFixture(opts ...func(*flow.ExecutionResult)) *flow.ExecutionResult { 898 blockID := IdentifierFixture() 899 result := &flow.ExecutionResult{ 900 PreviousResultID: IdentifierFixture(), 901 BlockID: IdentifierFixture(), 902 Chunks: ChunkListFixture(2, blockID), 903 ExecutionDataID: IdentifierFixture(), 904 } 905 906 for _, apply := range opts { 907 apply(result) 908 } 909 910 return result 911 } 912 913 func WithApproverID(approverID flow.Identifier) func(*flow.ResultApproval) { 914 return func(ra *flow.ResultApproval) { 915 ra.Body.ApproverID = approverID 916 } 917 } 918 919 func WithAttestationBlock(block *flow.Block) func(*flow.ResultApproval) { 920 return func(ra *flow.ResultApproval) { 921 ra.Body.Attestation.BlockID = block.ID() 922 } 923 } 924 925 func WithExecutionResultID(id flow.Identifier) func(*flow.ResultApproval) { 926 return func(ra *flow.ResultApproval) { 927 ra.Body.ExecutionResultID = id 928 } 929 } 930 931 func WithBlockID(id flow.Identifier) func(*flow.ResultApproval) { 932 return func(ra *flow.ResultApproval) { 933 ra.Body.BlockID = id 934 } 935 } 936 937 func WithChunk(chunkIdx uint64) func(*flow.ResultApproval) { 938 return func(approval *flow.ResultApproval) { 939 approval.Body.ChunkIndex = chunkIdx 940 } 941 } 942 943 func ResultApprovalFixture(opts ...func(*flow.ResultApproval)) *flow.ResultApproval { 944 attestation := flow.Attestation{ 945 BlockID: IdentifierFixture(), 946 ExecutionResultID: IdentifierFixture(), 947 ChunkIndex: uint64(0), 948 } 949 950 approval := flow.ResultApproval{ 951 Body: flow.ResultApprovalBody{ 952 Attestation: attestation, 953 ApproverID: IdentifierFixture(), 954 AttestationSignature: SignatureFixture(), 955 Spock: nil, 956 }, 957 VerifierSignature: SignatureFixture(), 958 } 959 960 for _, apply := range opts { 961 apply(&approval) 962 } 963 964 return &approval 965 } 966 967 func AttestationFixture() *flow.Attestation { 968 return &flow.Attestation{ 969 BlockID: IdentifierFixture(), 970 ExecutionResultID: IdentifierFixture(), 971 ChunkIndex: uint64(0), 972 } 973 } 974 975 func StateCommitmentFixture() flow.StateCommitment { 976 var state flow.StateCommitment 977 _, _ = crand.Read(state[:]) 978 return state 979 } 980 981 func StateCommitmentPointerFixture() *flow.StateCommitment { 982 state := StateCommitmentFixture() 983 return &state 984 } 985 986 func HashFixture(size int) hash.Hash { 987 hash := make(hash.Hash, size) 988 for i := 0; i < size; i++ { 989 hash[i] = byte(i) 990 } 991 return hash 992 } 993 994 func IdentifierListFixture(n int) flow.IdentifierList { 995 list := make([]flow.Identifier, n) 996 for i := 0; i < n; i++ { 997 list[i] = IdentifierFixture() 998 } 999 return list 1000 } 1001 1002 func IdentifierFixture() flow.Identifier { 1003 var id flow.Identifier 1004 _, _ = crand.Read(id[:]) 1005 return id 1006 } 1007 1008 func SignerIndicesFixture(n int) []byte { 1009 indices := bitutils.MakeBitVector(10) 1010 for i := 0; i < n; i++ { 1011 bitutils.SetBit(indices, 1) 1012 } 1013 return indices 1014 } 1015 1016 func SignerIndicesByIndices(n int, indices []int) []byte { 1017 signers := bitutils.MakeBitVector(n) 1018 for _, i := range indices { 1019 bitutils.SetBit(signers, i) 1020 } 1021 return signers 1022 } 1023 1024 // WithRole adds a role to an identity fixture. 1025 func WithRole(role flow.Role) func(*flow.Identity) { 1026 return func(identity *flow.Identity) { 1027 identity.Role = role 1028 } 1029 } 1030 1031 // WithWeight sets the weight on an identity fixture. 1032 func WithWeight(weight uint64) func(*flow.Identity) { 1033 return func(identity *flow.Identity) { 1034 identity.Weight = weight 1035 } 1036 } 1037 1038 func WithEjected(ejected bool) func(*flow.Identity) { 1039 return func(identity *flow.Identity) { 1040 identity.Ejected = ejected 1041 } 1042 } 1043 1044 // WithAddress sets the network address of identity fixture. 1045 func WithAddress(address string) func(*flow.Identity) { 1046 return func(identity *flow.Identity) { 1047 identity.Address = address 1048 } 1049 } 1050 1051 // WithNetworkingKey sets the networking public key of identity fixture. 1052 func WithNetworkingKey(key crypto.PublicKey) func(*flow.Identity) { 1053 return func(identity *flow.Identity) { 1054 identity.NetworkPubKey = key 1055 } 1056 } 1057 1058 func RandomBytes(n int) []byte { 1059 b := make([]byte, n) 1060 read, err := crand.Read(b) 1061 if err != nil { 1062 panic("cannot read random bytes") 1063 } 1064 if read != n { 1065 panic(fmt.Errorf("cannot read enough random bytes (got %d of %d)", read, n)) 1066 } 1067 return b 1068 } 1069 1070 func NodeConfigFixture(opts ...func(*flow.Identity)) bootstrap.NodeConfig { 1071 identity := IdentityFixture(opts...) 1072 return bootstrap.NodeConfig{ 1073 Role: identity.Role, 1074 Address: identity.Address, 1075 Weight: identity.Weight, 1076 } 1077 } 1078 1079 func NodeInfoFixture(opts ...func(*flow.Identity)) bootstrap.NodeInfo { 1080 opts = append(opts, WithKeys) 1081 return bootstrap.NodeInfoFromIdentity(IdentityFixture(opts...)) 1082 } 1083 1084 func NodeInfosFixture(n int, opts ...func(*flow.Identity)) []bootstrap.NodeInfo { 1085 opts = append(opts, WithKeys) 1086 il := IdentityListFixture(n, opts...) 1087 nodeInfos := make([]bootstrap.NodeInfo, 0, n) 1088 for _, identity := range il { 1089 nodeInfos = append(nodeInfos, bootstrap.NodeInfoFromIdentity(identity)) 1090 } 1091 return nodeInfos 1092 } 1093 1094 func PrivateNodeInfosFixture(n int, opts ...func(*flow.Identity)) []bootstrap.NodeInfo { 1095 il := IdentityListFixture(n, opts...) 1096 nodeInfos := make([]bootstrap.NodeInfo, 0, n) 1097 for _, identity := range il { 1098 nodeInfo := bootstrap.PrivateNodeInfoFromIdentity(identity, KeyFixture(crypto.ECDSAP256), KeyFixture(crypto.BLSBLS12381)) 1099 nodeInfos = append(nodeInfos, nodeInfo) 1100 } 1101 return nodeInfos 1102 } 1103 1104 // IdentityFixture returns a node identity. 1105 func IdentityFixture(opts ...func(*flow.Identity)) *flow.Identity { 1106 nodeID := IdentifierFixture() 1107 stakingKey := StakingPrivKeyByIdentifier(nodeID) 1108 identity := flow.Identity{ 1109 NodeID: nodeID, 1110 Address: fmt.Sprintf("address-%x", nodeID[0:7]), 1111 Role: flow.RoleConsensus, 1112 Weight: 1000, 1113 StakingPubKey: stakingKey.PublicKey(), 1114 } 1115 for _, apply := range opts { 1116 apply(&identity) 1117 } 1118 return &identity 1119 } 1120 1121 // IdentityWithNetworkingKeyFixture returns a node identity and networking private key 1122 func IdentityWithNetworkingKeyFixture(opts ...func(*flow.Identity)) ( 1123 *flow.Identity, 1124 crypto.PrivateKey, 1125 ) { 1126 networkKey := NetworkingPrivKeyFixture() 1127 opts = append(opts, WithNetworkingKey(networkKey.PublicKey())) 1128 id := IdentityFixture(opts...) 1129 return id, networkKey 1130 } 1131 1132 func WithKeys(identity *flow.Identity) { 1133 staking := StakingPrivKeyFixture() 1134 networking := NetworkingPrivKeyFixture() 1135 identity.StakingPubKey = staking.PublicKey() 1136 identity.NetworkPubKey = networking.PublicKey() 1137 } 1138 1139 // WithNodeID adds a node ID with the given first byte to an identity. 1140 func WithNodeID(id flow.Identifier) func(*flow.Identity) { 1141 return func(identity *flow.Identity) { 1142 identity.NodeID = id 1143 } 1144 } 1145 1146 // WithStakingPubKey adds a staking public key to the identity 1147 func WithStakingPubKey(pubKey crypto.PublicKey) func(*flow.Identity) { 1148 return func(identity *flow.Identity) { 1149 identity.StakingPubKey = pubKey 1150 } 1151 } 1152 1153 // WithRandomPublicKeys adds random public keys to an identity. 1154 func WithRandomPublicKeys() func(*flow.Identity) { 1155 return func(identity *flow.Identity) { 1156 identity.StakingPubKey = KeyFixture(crypto.BLSBLS12381).PublicKey() 1157 identity.NetworkPubKey = KeyFixture(crypto.ECDSAP256).PublicKey() 1158 } 1159 } 1160 1161 // WithAllRoles can be used used to ensure an IdentityList fixtures contains 1162 // all the roles required for a valid genesis block. 1163 func WithAllRoles() func(*flow.Identity) { 1164 return WithAllRolesExcept() 1165 } 1166 1167 // Same as above, but omitting a certain role for cases where we are manually 1168 // setting up nodes or a particular role. 1169 func WithAllRolesExcept(except ...flow.Role) func(*flow.Identity) { 1170 i := 0 1171 roles := flow.Roles() 1172 1173 // remove omitted roles 1174 for _, omitRole := range except { 1175 for i, role := range roles { 1176 if role == omitRole { 1177 roles = append(roles[:i], roles[i+1:]...) 1178 } 1179 } 1180 } 1181 1182 return func(id *flow.Identity) { 1183 id.Role = roles[i%len(roles)] 1184 i++ 1185 } 1186 } 1187 1188 // CompleteIdentitySet takes a number of identities and completes the missing roles. 1189 func CompleteIdentitySet(identities ...*flow.Identity) flow.IdentityList { 1190 required := map[flow.Role]struct{}{ 1191 flow.RoleCollection: {}, 1192 flow.RoleConsensus: {}, 1193 flow.RoleExecution: {}, 1194 flow.RoleVerification: {}, 1195 } 1196 // don't add identities for roles that already exist 1197 for _, identity := range identities { 1198 delete(required, identity.Role) 1199 } 1200 // add identities for missing roles 1201 for role := range required { 1202 identities = append(identities, IdentityFixture(WithRole(role))) 1203 } 1204 return identities 1205 } 1206 1207 // IdentityListFixture returns a list of node identity objects. The identities 1208 // can be customized (ie. set their role) by passing in a function that modifies 1209 // the input identities as required. 1210 func IdentityListFixture(n int, opts ...func(*flow.Identity)) flow.IdentityList { 1211 identities := make(flow.IdentityList, 0, n) 1212 1213 for i := 0; i < n; i++ { 1214 identity := IdentityFixture() 1215 identity.Address = fmt.Sprintf("%x@flow.com:1234", identity.NodeID) 1216 for _, opt := range opts { 1217 opt(identity) 1218 } 1219 identities = append(identities, identity) 1220 } 1221 1222 return identities 1223 } 1224 1225 func WithChunkStartState(startState flow.StateCommitment) func(chunk *flow.Chunk) { 1226 return func(chunk *flow.Chunk) { 1227 chunk.StartState = startState 1228 } 1229 } 1230 1231 func ChunkFixture( 1232 blockID flow.Identifier, 1233 collectionIndex uint, 1234 opts ...func(*flow.Chunk), 1235 ) *flow.Chunk { 1236 chunk := &flow.Chunk{ 1237 ChunkBody: flow.ChunkBody{ 1238 CollectionIndex: collectionIndex, 1239 StartState: StateCommitmentFixture(), 1240 EventCollection: IdentifierFixture(), 1241 TotalComputationUsed: 4200, 1242 NumberOfTransactions: 42, 1243 BlockID: blockID, 1244 }, 1245 Index: 0, 1246 EndState: StateCommitmentFixture(), 1247 } 1248 1249 for _, opt := range opts { 1250 opt(chunk) 1251 } 1252 1253 return chunk 1254 } 1255 1256 func ChunkListFixture(n uint, blockID flow.Identifier) flow.ChunkList { 1257 chunks := make([]*flow.Chunk, 0, n) 1258 for i := uint64(0); i < uint64(n); i++ { 1259 chunk := ChunkFixture(blockID, uint(i)) 1260 chunk.Index = i 1261 chunks = append(chunks, chunk) 1262 } 1263 return chunks 1264 } 1265 1266 func ChunkLocatorListFixture(n uint) chunks.LocatorList { 1267 locators := chunks.LocatorList{} 1268 resultID := IdentifierFixture() 1269 for i := uint64(0); i < uint64(n); i++ { 1270 locator := ChunkLocatorFixture(resultID, i) 1271 locators = append(locators, locator) 1272 } 1273 return locators 1274 } 1275 1276 func ChunkLocatorFixture(resultID flow.Identifier, index uint64) *chunks.Locator { 1277 return &chunks.Locator{ 1278 ResultID: resultID, 1279 Index: index, 1280 } 1281 } 1282 1283 // ChunkStatusListToChunkLocatorFixture extracts chunk locators from a list of chunk statuses. 1284 func ChunkStatusListToChunkLocatorFixture(statuses []*verification.ChunkStatus) chunks.LocatorMap { 1285 locators := chunks.LocatorMap{} 1286 for _, status := range statuses { 1287 locator := ChunkLocatorFixture(status.ExecutionResult.ID(), status.ChunkIndex) 1288 locators[locator.ID()] = locator 1289 } 1290 1291 return locators 1292 } 1293 1294 // ChunkStatusListFixture receives an execution result, samples `n` chunks out of it and 1295 // creates a chunk status for them. 1296 // It returns the list of sampled chunk statuses for the result. 1297 func ChunkStatusListFixture( 1298 t *testing.T, 1299 blockHeight uint64, 1300 result *flow.ExecutionResult, 1301 n int, 1302 ) verification.ChunkStatusList { 1303 statuses := verification.ChunkStatusList{} 1304 1305 // result should have enough chunk to sample 1306 require.GreaterOrEqual(t, len(result.Chunks), n) 1307 1308 chunkList := make(flow.ChunkList, n) 1309 copy(chunkList, result.Chunks) 1310 rand.Shuffle(len(chunkList), func(i, j int) { chunkList[i], chunkList[j] = chunkList[j], chunkList[i] }) 1311 1312 for _, chunk := range chunkList[:n] { 1313 status := &verification.ChunkStatus{ 1314 ChunkIndex: chunk.Index, 1315 BlockHeight: blockHeight, 1316 ExecutionResult: result, 1317 } 1318 statuses = append(statuses, status) 1319 } 1320 1321 return statuses 1322 } 1323 1324 func qcSignatureDataFixture() hotstuff.SignatureData { 1325 sigType := RandomBytes(5) 1326 for i := range sigType { 1327 sigType[i] = sigType[i] % 2 1328 } 1329 sigData := hotstuff.SignatureData{ 1330 SigType: sigType, 1331 AggregatedStakingSig: SignatureFixture(), 1332 AggregatedRandomBeaconSig: SignatureFixture(), 1333 ReconstructedRandomBeaconSig: SignatureFixture(), 1334 } 1335 return sigData 1336 } 1337 1338 func QCSigDataFixture() []byte { 1339 packer := hotstuff.SigDataPacker{} 1340 sigData := qcSignatureDataFixture() 1341 encoded, _ := packer.Encode(&sigData) 1342 return encoded 1343 } 1344 1345 func QCSigDataWithSoRFixture(sor []byte) []byte { 1346 packer := hotstuff.SigDataPacker{} 1347 sigData := qcSignatureDataFixture() 1348 sigData.ReconstructedRandomBeaconSig = sor 1349 encoded, _ := packer.Encode(&sigData) 1350 return encoded 1351 } 1352 1353 func SignatureFixture() crypto.Signature { 1354 sig := make([]byte, crypto.SignatureLenBLSBLS12381) 1355 _, _ = crand.Read(sig) 1356 return sig 1357 } 1358 1359 func SignaturesFixture(n int) []crypto.Signature { 1360 var sigs []crypto.Signature 1361 for i := 0; i < n; i++ { 1362 sigs = append(sigs, SignatureFixture()) 1363 } 1364 return sigs 1365 } 1366 1367 func RandomSourcesFixture(n int) [][]byte { 1368 var sigs [][]byte 1369 for i := 0; i < n; i++ { 1370 sigs = append(sigs, SignatureFixture()) 1371 } 1372 return sigs 1373 } 1374 1375 func TransactionFixture(n ...func(t *flow.Transaction)) flow.Transaction { 1376 tx := flow.Transaction{TransactionBody: TransactionBodyFixture()} 1377 if len(n) > 0 { 1378 n[0](&tx) 1379 } 1380 return tx 1381 } 1382 1383 func TransactionBodyFixture(opts ...func(*flow.TransactionBody)) flow.TransactionBody { 1384 tb := flow.TransactionBody{ 1385 Script: []byte("pub fun main() {}"), 1386 ReferenceBlockID: IdentifierFixture(), 1387 GasLimit: 10, 1388 ProposalKey: ProposalKeyFixture(), 1389 Payer: AddressFixture(), 1390 Authorizers: []flow.Address{AddressFixture()}, 1391 EnvelopeSignatures: []flow.TransactionSignature{TransactionSignatureFixture()}, 1392 } 1393 1394 for _, apply := range opts { 1395 apply(&tb) 1396 } 1397 1398 return tb 1399 } 1400 1401 func TransactionBodyListFixture(n int) []flow.TransactionBody { 1402 l := make([]flow.TransactionBody, n) 1403 for i := 0; i < n; i++ { 1404 l[i] = TransactionBodyFixture() 1405 } 1406 1407 return l 1408 } 1409 1410 func WithTransactionDSL(txDSL dsl.Transaction) func(tx *flow.TransactionBody) { 1411 return func(tx *flow.TransactionBody) { 1412 tx.Script = []byte(txDSL.ToCadence()) 1413 } 1414 } 1415 1416 func WithReferenceBlock(id flow.Identifier) func(tx *flow.TransactionBody) { 1417 return func(tx *flow.TransactionBody) { 1418 tx.ReferenceBlockID = id 1419 } 1420 } 1421 1422 func TransactionDSLFixture(chain flow.Chain) dsl.Transaction { 1423 return dsl.Transaction{ 1424 Import: dsl.Import{Address: sdk.Address(chain.ServiceAddress())}, 1425 Content: dsl.Prepare{ 1426 Content: dsl.Code(` 1427 pub fun main() {} 1428 `), 1429 }, 1430 } 1431 } 1432 1433 // RegisterIDFixture returns a RegisterID with a fixed key and owner 1434 func RegisterIDFixture() flow.RegisterID { 1435 return flow.NewRegisterID(RandomAddressFixture(), "key") 1436 } 1437 1438 // VerifiableChunkDataFixture returns a complete verifiable chunk with an 1439 // execution receipt referencing the block/collections. 1440 func VerifiableChunkDataFixture(chunkIndex uint64) *verification.VerifiableChunkData { 1441 1442 guarantees := make([]*flow.CollectionGuarantee, 0) 1443 1444 var col flow.Collection 1445 1446 for i := 0; i <= int(chunkIndex); i++ { 1447 col = CollectionFixture(1) 1448 guarantee := col.Guarantee() 1449 guarantees = append(guarantees, &guarantee) 1450 } 1451 1452 payload := flow.Payload{ 1453 Guarantees: guarantees, 1454 Seals: nil, 1455 } 1456 header := BlockHeaderFixture() 1457 header.PayloadHash = payload.Hash() 1458 1459 block := flow.Block{ 1460 Header: header, 1461 Payload: &payload, 1462 } 1463 1464 chunks := make([]*flow.Chunk, 0) 1465 1466 var chunk flow.Chunk 1467 1468 for i := 0; i <= int(chunkIndex); i++ { 1469 chunk = flow.Chunk{ 1470 ChunkBody: flow.ChunkBody{ 1471 CollectionIndex: uint(i), 1472 StartState: StateCommitmentFixture(), 1473 BlockID: block.ID(), 1474 }, 1475 Index: uint64(i), 1476 } 1477 chunks = append(chunks, &chunk) 1478 } 1479 1480 result := flow.ExecutionResult{ 1481 BlockID: block.ID(), 1482 Chunks: chunks, 1483 } 1484 1485 // computes chunk end state 1486 index := chunk.Index 1487 var endState flow.StateCommitment 1488 if int(index) == len(result.Chunks)-1 { 1489 // last chunk in receipt takes final state commitment 1490 endState = StateCommitmentFixture() 1491 } else { 1492 // any chunk except last takes the subsequent chunk's start state 1493 endState = result.Chunks[index+1].StartState 1494 } 1495 1496 return &verification.VerifiableChunkData{ 1497 Chunk: &chunk, 1498 Header: block.Header, 1499 Result: &result, 1500 ChunkDataPack: ChunkDataPackFixture(result.ID()), 1501 EndState: endState, 1502 } 1503 } 1504 1505 // ChunkDataResponseMsgFixture creates a chunk data response message with a single-transaction collection, and random chunk ID. 1506 // Use options to customize the response. 1507 func ChunkDataResponseMsgFixture( 1508 chunkID flow.Identifier, 1509 opts ...func(*messages.ChunkDataResponse), 1510 ) *messages.ChunkDataResponse { 1511 cdp := &messages.ChunkDataResponse{ 1512 ChunkDataPack: *ChunkDataPackFixture(chunkID), 1513 Nonce: rand.Uint64(), 1514 } 1515 1516 for _, opt := range opts { 1517 opt(cdp) 1518 } 1519 1520 return cdp 1521 } 1522 1523 // WithApproximateSize sets the ChunkDataResponse to be approximately bytes in size. 1524 func WithApproximateSize(bytes uint64) func(*messages.ChunkDataResponse) { 1525 return func(request *messages.ChunkDataResponse) { 1526 // 1 tx fixture is approximately 350 bytes 1527 txCount := bytes / 350 1528 collection := CollectionFixture(int(txCount) + 1) 1529 pack := ChunkDataPackFixture(request.ChunkDataPack.ChunkID, WithChunkDataPackCollection(&collection)) 1530 request.ChunkDataPack = *pack 1531 } 1532 } 1533 1534 // ChunkDataResponseMessageListFixture creates a list of chunk data response messages each with a single-transaction collection, and random chunk ID. 1535 func ChunkDataResponseMessageListFixture(chunkIDs flow.IdentifierList) []*messages.ChunkDataResponse { 1536 lst := make([]*messages.ChunkDataResponse, 0, len(chunkIDs)) 1537 for _, chunkID := range chunkIDs { 1538 lst = append(lst, ChunkDataResponseMsgFixture(chunkID)) 1539 } 1540 return lst 1541 } 1542 1543 // ChunkDataPackRequestListFixture creates and returns a list of chunk data pack requests fixtures. 1544 func ChunkDataPackRequestListFixture( 1545 n int, 1546 opts ...func(*verification.ChunkDataPackRequest), 1547 ) verification.ChunkDataPackRequestList { 1548 lst := make([]*verification.ChunkDataPackRequest, 0, n) 1549 for i := 0; i < n; i++ { 1550 lst = append(lst, ChunkDataPackRequestFixture(opts...)) 1551 } 1552 return lst 1553 } 1554 1555 func WithHeight(height uint64) func(*verification.ChunkDataPackRequest) { 1556 return func(request *verification.ChunkDataPackRequest) { 1557 request.Height = height 1558 } 1559 } 1560 1561 func WithHeightGreaterThan(height uint64) func(*verification.ChunkDataPackRequest) { 1562 return func(request *verification.ChunkDataPackRequest) { 1563 request.Height = height + 1 1564 } 1565 } 1566 1567 func WithAgrees(list flow.IdentifierList) func(*verification.ChunkDataPackRequest) { 1568 return func(request *verification.ChunkDataPackRequest) { 1569 request.Agrees = list 1570 } 1571 } 1572 1573 func WithDisagrees(list flow.IdentifierList) func(*verification.ChunkDataPackRequest) { 1574 return func(request *verification.ChunkDataPackRequest) { 1575 request.Disagrees = list 1576 } 1577 } 1578 1579 func WithChunkID(chunkID flow.Identifier) func(*verification.ChunkDataPackRequest) { 1580 return func(request *verification.ChunkDataPackRequest) { 1581 request.ChunkID = chunkID 1582 } 1583 } 1584 1585 // ChunkDataPackRequestFixture creates a chunk data request with some default values, i.e., one agree execution node, one disagree execution node, 1586 // and height of zero. 1587 // Use options to customize the request. 1588 func ChunkDataPackRequestFixture(opts ...func(*verification.ChunkDataPackRequest)) *verification. 1589 ChunkDataPackRequest { 1590 1591 req := &verification.ChunkDataPackRequest{ 1592 Locator: chunks.Locator{ 1593 ResultID: IdentifierFixture(), 1594 Index: 0, 1595 }, 1596 ChunkDataPackRequestInfo: verification.ChunkDataPackRequestInfo{ 1597 ChunkID: IdentifierFixture(), 1598 Height: 0, 1599 Agrees: IdentifierListFixture(1), 1600 Disagrees: IdentifierListFixture(1), 1601 }, 1602 } 1603 1604 for _, opt := range opts { 1605 opt(req) 1606 } 1607 1608 // creates identity fixtures for target ids as union of agrees and disagrees 1609 // TODO: remove this inner fixture once we have filter for identifier list. 1610 targets := flow.IdentityList{} 1611 for _, id := range req.Agrees { 1612 targets = append(targets, IdentityFixture(WithNodeID(id), WithRole(flow.RoleExecution))) 1613 } 1614 for _, id := range req.Disagrees { 1615 targets = append(targets, IdentityFixture(WithNodeID(id), WithRole(flow.RoleExecution))) 1616 } 1617 1618 req.Targets = targets 1619 1620 return req 1621 } 1622 1623 func WithChunkDataPackCollection(collection *flow.Collection) func(*flow.ChunkDataPack) { 1624 return func(cdp *flow.ChunkDataPack) { 1625 cdp.Collection = collection 1626 } 1627 } 1628 1629 func WithStartState(startState flow.StateCommitment) func(*flow.ChunkDataPack) { 1630 return func(cdp *flow.ChunkDataPack) { 1631 cdp.StartState = startState 1632 } 1633 } 1634 1635 func ChunkDataPackFixture( 1636 chunkID flow.Identifier, 1637 opts ...func(*flow.ChunkDataPack), 1638 ) *flow.ChunkDataPack { 1639 coll := CollectionFixture(1) 1640 cdp := &flow.ChunkDataPack{ 1641 ChunkID: chunkID, 1642 StartState: StateCommitmentFixture(), 1643 Proof: []byte{'p'}, 1644 Collection: &coll, 1645 ExecutionDataRoot: flow.BlockExecutionDataRoot{ 1646 BlockID: IdentifierFixture(), 1647 ChunkExecutionDataIDs: []cid.Cid{flow.IdToCid(IdentifierFixture())}, 1648 }, 1649 } 1650 1651 for _, opt := range opts { 1652 opt(cdp) 1653 } 1654 1655 return cdp 1656 } 1657 1658 func ChunkDataPacksFixture( 1659 count int, 1660 opts ...func(*flow.ChunkDataPack), 1661 ) []*flow.ChunkDataPack { 1662 chunkDataPacks := make([]*flow.ChunkDataPack, count) 1663 for i := 0; i < count; i++ { 1664 chunkDataPacks[i] = ChunkDataPackFixture(IdentifierFixture()) 1665 } 1666 1667 return chunkDataPacks 1668 } 1669 1670 // SeedFixture returns a random []byte with length n 1671 func SeedFixture(n int) []byte { 1672 var seed = make([]byte, n) 1673 _, _ = crand.Read(seed) 1674 return seed 1675 } 1676 1677 // SeedFixtures returns a list of m random []byte, each having length n 1678 func SeedFixtures(m int, n int) [][]byte { 1679 var seeds = make([][]byte, m, n) 1680 for i := range seeds { 1681 seeds[i] = SeedFixture(n) 1682 } 1683 return seeds 1684 } 1685 1686 // BlockEventsFixture returns a block events model populated with random events of length n. 1687 func BlockEventsFixture( 1688 header *flow.Header, 1689 n int, 1690 types ...flow.EventType, 1691 ) flow.BlockEvents { 1692 return flow.BlockEvents{ 1693 BlockID: header.ID(), 1694 BlockHeight: header.Height, 1695 BlockTimestamp: header.Timestamp, 1696 Events: EventsFixture(n, types...), 1697 } 1698 } 1699 1700 func EventsFixture( 1701 n int, 1702 types ...flow.EventType, 1703 ) []flow.Event { 1704 if len(types) == 0 { 1705 types = []flow.EventType{"A.0x1.Foo.Bar", "A.0x2.Zoo.Moo", "A.0x3.Goo.Hoo"} 1706 } 1707 1708 events := make([]flow.Event, n) 1709 for i := 0; i < n; i++ { 1710 events[i] = EventFixture(types[i%len(types)], 0, uint32(i), IdentifierFixture(), 0) 1711 } 1712 1713 return events 1714 } 1715 1716 func EventTypeFixture(chainID flow.ChainID) flow.EventType { 1717 eventType := fmt.Sprintf("A.%s.TestContract.TestEvent1", RandomAddressFixtureForChain(chainID)) 1718 return flow.EventType(eventType) 1719 } 1720 1721 // EventFixture returns an event 1722 func EventFixture( 1723 eType flow.EventType, 1724 transactionIndex uint32, 1725 eventIndex uint32, 1726 txID flow.Identifier, 1727 _ int, 1728 ) flow.Event { 1729 return flow.Event{ 1730 Type: eType, 1731 TransactionIndex: transactionIndex, 1732 EventIndex: eventIndex, 1733 Payload: []byte{}, 1734 TransactionID: txID, 1735 } 1736 } 1737 1738 func EmulatorRootKey() (*flow.AccountPrivateKey, error) { 1739 1740 // TODO seems this key literal doesn't decode anymore 1741 emulatorRootKey, err := crypto.DecodePrivateKey(crypto.ECDSAP256, 1742 []byte("f87db87930770201010420ae2cc975dcbdd0ebc56f268b1d8a95834c2955970aea27042d35ec9f298b9e5aa00a06082a8648ce3d030107a1440342000417f5a527137785d2d773fee84b4c7ee40266a1dd1f36ddd46ecf25db6df6a499459629174de83256f2a44ebd4325b9def67d523b755a8926218c4efb7904f8ce0203")) 1743 if err != nil { 1744 return nil, err 1745 } 1746 1747 return &flow.AccountPrivateKey{ 1748 PrivateKey: emulatorRootKey, 1749 SignAlgo: emulatorRootKey.Algorithm(), 1750 HashAlgo: hash.SHA3_256, 1751 }, nil 1752 } 1753 1754 // NoopTxScript returns a Cadence script for a no-op transaction. 1755 func NoopTxScript() []byte { 1756 return []byte("transaction {}") 1757 } 1758 1759 func RangeFixture() chainsync.Range { 1760 return chainsync.Range{ 1761 From: rand.Uint64(), 1762 To: rand.Uint64(), 1763 } 1764 } 1765 1766 func BatchFixture() chainsync.Batch { 1767 return chainsync.Batch{ 1768 BlockIDs: IdentifierListFixture(10), 1769 } 1770 } 1771 1772 func RangeListFixture(n int) []chainsync.Range { 1773 if n <= 0 { 1774 return nil 1775 } 1776 ranges := make([]chainsync.Range, n) 1777 for i := range ranges { 1778 ranges[i] = RangeFixture() 1779 } 1780 return ranges 1781 } 1782 1783 func BatchListFixture(n int) []chainsync.Batch { 1784 if n <= 0 { 1785 return nil 1786 } 1787 batches := make([]chainsync.Batch, n) 1788 for i := range batches { 1789 batches[i] = BatchFixture() 1790 } 1791 return batches 1792 } 1793 1794 func BootstrapExecutionResultFixture( 1795 block *flow.Block, 1796 commit flow.StateCommitment, 1797 ) *flow.ExecutionResult { 1798 result := &flow.ExecutionResult{ 1799 BlockID: block.ID(), 1800 PreviousResultID: flow.ZeroID, 1801 Chunks: chunks.ChunkListFromCommit(commit), 1802 } 1803 return result 1804 } 1805 1806 func KeyFixture(algo crypto.SigningAlgorithm) crypto.PrivateKey { 1807 key, err := crypto.GeneratePrivateKey(algo, SeedFixture(128)) 1808 if err != nil { 1809 panic(err) 1810 } 1811 return key 1812 } 1813 1814 func KeysFixture(n int, algo crypto.SigningAlgorithm) []crypto.PrivateKey { 1815 keys := make([]crypto.PrivateKey, 0, n) 1816 for i := 0; i < n; i++ { 1817 keys = append(keys, KeyFixture(algo)) 1818 } 1819 return keys 1820 } 1821 1822 func PublicKeysFixture(n int, algo crypto.SigningAlgorithm) []crypto.PublicKey { 1823 pks := make([]crypto.PublicKey, 0, n) 1824 sks := KeysFixture(n, algo) 1825 for _, sk := range sks { 1826 pks = append(pks, sk.PublicKey()) 1827 } 1828 return pks 1829 } 1830 1831 func QuorumCertificateWithSignerIDsFixture(opts ...func(*flow.QuorumCertificateWithSignerIDs)) *flow.QuorumCertificateWithSignerIDs { 1832 qc := flow.QuorumCertificateWithSignerIDs{ 1833 View: uint64(rand.Uint32()), 1834 BlockID: IdentifierFixture(), 1835 SignerIDs: IdentifierListFixture(3), 1836 SigData: QCSigDataFixture(), 1837 } 1838 for _, apply := range opts { 1839 apply(&qc) 1840 } 1841 return &qc 1842 } 1843 1844 func QuorumCertificatesWithSignerIDsFixtures( 1845 n uint, 1846 opts ...func(*flow.QuorumCertificateWithSignerIDs), 1847 ) []*flow.QuorumCertificateWithSignerIDs { 1848 qcs := make([]*flow.QuorumCertificateWithSignerIDs, 0, n) 1849 for i := 0; i < int(n); i++ { 1850 qcs = append(qcs, QuorumCertificateWithSignerIDsFixture(opts...)) 1851 } 1852 return qcs 1853 } 1854 1855 func QuorumCertificatesFromAssignments(assignment flow.AssignmentList) []*flow.QuorumCertificateWithSignerIDs { 1856 qcs := make([]*flow.QuorumCertificateWithSignerIDs, 0, len(assignment)) 1857 for _, nodes := range assignment { 1858 qc := QuorumCertificateWithSignerIDsFixture() 1859 qc.SignerIDs = nodes 1860 qcs = append(qcs, qc) 1861 } 1862 return qcs 1863 } 1864 1865 func QuorumCertificateFixture(opts ...func(*flow.QuorumCertificate)) *flow.QuorumCertificate { 1866 qc := flow.QuorumCertificate{ 1867 View: uint64(rand.Uint32()), 1868 BlockID: IdentifierFixture(), 1869 SignerIndices: SignerIndicesFixture(3), 1870 SigData: QCSigDataFixture(), 1871 } 1872 for _, apply := range opts { 1873 apply(&qc) 1874 } 1875 return &qc 1876 } 1877 1878 // CertifyBlock returns a quorum certificate for the given block header 1879 func CertifyBlock(header *flow.Header) *flow.QuorumCertificate { 1880 qc := QuorumCertificateFixture(func(qc *flow.QuorumCertificate) { 1881 qc.View = header.View 1882 qc.BlockID = header.ID() 1883 }) 1884 return qc 1885 } 1886 1887 func QuorumCertificatesFixtures( 1888 n uint, 1889 opts ...func(*flow.QuorumCertificate), 1890 ) []*flow.QuorumCertificate { 1891 qcs := make([]*flow.QuorumCertificate, 0, n) 1892 for i := 0; i < int(n); i++ { 1893 qcs = append(qcs, QuorumCertificateFixture(opts...)) 1894 } 1895 return qcs 1896 } 1897 1898 func QCWithBlockID(blockID flow.Identifier) func(*flow.QuorumCertificate) { 1899 return func(qc *flow.QuorumCertificate) { 1900 qc.BlockID = blockID 1901 } 1902 } 1903 1904 func QCWithSignerIndices(signerIndices []byte) func(*flow.QuorumCertificate) { 1905 return func(qc *flow.QuorumCertificate) { 1906 qc.SignerIndices = signerIndices 1907 } 1908 } 1909 1910 func QCWithRootBlockID(blockID flow.Identifier) func(*flow.QuorumCertificate) { 1911 return func(qc *flow.QuorumCertificate) { 1912 qc.BlockID = blockID 1913 qc.View = 0 1914 } 1915 } 1916 1917 func VoteFixture(opts ...func(vote *hotstuff.Vote)) *hotstuff.Vote { 1918 vote := &hotstuff.Vote{ 1919 View: uint64(rand.Uint32()), 1920 BlockID: IdentifierFixture(), 1921 SignerID: IdentifierFixture(), 1922 SigData: RandomBytes(128), 1923 } 1924 1925 for _, opt := range opts { 1926 opt(vote) 1927 } 1928 1929 return vote 1930 } 1931 1932 func WithVoteSignerID(signerID flow.Identifier) func(*hotstuff.Vote) { 1933 return func(vote *hotstuff.Vote) { 1934 vote.SignerID = signerID 1935 } 1936 } 1937 1938 func WithVoteView(view uint64) func(*hotstuff.Vote) { 1939 return func(vote *hotstuff.Vote) { 1940 vote.View = view 1941 } 1942 } 1943 1944 func WithVoteBlockID(blockID flow.Identifier) func(*hotstuff.Vote) { 1945 return func(vote *hotstuff.Vote) { 1946 vote.BlockID = blockID 1947 } 1948 } 1949 1950 func VoteForBlockFixture( 1951 block *hotstuff.Block, 1952 opts ...func(vote *hotstuff.Vote), 1953 ) *hotstuff.Vote { 1954 vote := VoteFixture(WithVoteView(block.View), 1955 WithVoteBlockID(block.BlockID)) 1956 1957 for _, opt := range opts { 1958 opt(vote) 1959 } 1960 1961 return vote 1962 } 1963 1964 func VoteWithStakingSig() func(*hotstuff.Vote) { 1965 return func(vote *hotstuff.Vote) { 1966 vote.SigData = append([]byte{byte(encoding.SigTypeStaking)}, vote.SigData...) 1967 } 1968 } 1969 1970 func VoteWithBeaconSig() func(*hotstuff.Vote) { 1971 return func(vote *hotstuff.Vote) { 1972 vote.SigData = append([]byte{byte(encoding.SigTypeRandomBeacon)}, vote.SigData...) 1973 } 1974 } 1975 1976 func WithParticipants(participants flow.IdentityList) func(*flow.EpochSetup) { 1977 return func(setup *flow.EpochSetup) { 1978 setup.Participants = participants.Sort(flow.Canonical) 1979 setup.Assignments = ClusterAssignment(1, participants) 1980 } 1981 } 1982 1983 func SetupWithCounter(counter uint64) func(*flow.EpochSetup) { 1984 return func(setup *flow.EpochSetup) { 1985 setup.Counter = counter 1986 } 1987 } 1988 1989 func WithFinalView(view uint64) func(*flow.EpochSetup) { 1990 return func(setup *flow.EpochSetup) { 1991 setup.FinalView = view 1992 } 1993 } 1994 1995 func WithFirstView(view uint64) func(*flow.EpochSetup) { 1996 return func(setup *flow.EpochSetup) { 1997 setup.FirstView = view 1998 } 1999 } 2000 2001 // EpochSetupFixture creates a valid EpochSetup with default properties for 2002 // testing. The default properties can be overwritten with optional parameter 2003 // functions. 2004 func EpochSetupFixture(opts ...func(setup *flow.EpochSetup)) *flow.EpochSetup { 2005 participants := IdentityListFixture(5, WithAllRoles()) 2006 setup := &flow.EpochSetup{ 2007 Counter: uint64(rand.Uint32()), 2008 FirstView: uint64(0), 2009 FinalView: uint64(rand.Uint32() + 1000), 2010 Participants: participants.Sort(flow.Canonical), 2011 RandomSource: SeedFixture(flow.EpochSetupRandomSourceLength), 2012 DKGPhase1FinalView: 100, 2013 DKGPhase2FinalView: 200, 2014 DKGPhase3FinalView: 300, 2015 } 2016 for _, apply := range opts { 2017 apply(setup) 2018 } 2019 if setup.Assignments == nil { 2020 setup.Assignments = ClusterAssignment(1, setup.Participants) 2021 } 2022 return setup 2023 } 2024 2025 func EpochStatusFixture() *flow.EpochStatus { 2026 return &flow.EpochStatus{ 2027 PreviousEpoch: flow.EventIDs{ 2028 SetupID: IdentifierFixture(), 2029 CommitID: IdentifierFixture(), 2030 }, 2031 CurrentEpoch: flow.EventIDs{ 2032 SetupID: IdentifierFixture(), 2033 CommitID: IdentifierFixture(), 2034 }, 2035 NextEpoch: flow.EventIDs{ 2036 SetupID: IdentifierFixture(), 2037 CommitID: IdentifierFixture(), 2038 }, 2039 } 2040 } 2041 2042 func IndexFixture() *flow.Index { 2043 return &flow.Index{ 2044 CollectionIDs: IdentifierListFixture(5), 2045 SealIDs: IdentifierListFixture(5), 2046 ReceiptIDs: IdentifierListFixture(5), 2047 } 2048 } 2049 2050 func WithDKGFromParticipants(participants flow.IdentityList) func(*flow.EpochCommit) { 2051 count := len(participants.Filter(filter.IsValidDKGParticipant)) 2052 return func(commit *flow.EpochCommit) { 2053 commit.DKGParticipantKeys = PublicKeysFixture(count, crypto.BLSBLS12381) 2054 } 2055 } 2056 2057 func WithClusterQCsFromAssignments(assignments flow.AssignmentList) func(*flow.EpochCommit) { 2058 qcs := make([]*flow.QuorumCertificateWithSignerIDs, 0, len(assignments)) 2059 for _, assignment := range assignments { 2060 qcWithSignerIndex := QuorumCertificateWithSignerIDsFixture() 2061 qcWithSignerIndex.SignerIDs = assignment 2062 qcs = append(qcs, qcWithSignerIndex) 2063 } 2064 return func(commit *flow.EpochCommit) { 2065 commit.ClusterQCs = flow.ClusterQCVoteDatasFromQCs(qcs) 2066 } 2067 } 2068 2069 func DKGParticipantLookup(participants flow.IdentityList) map[flow.Identifier]flow.DKGParticipant { 2070 lookup := make(map[flow.Identifier]flow.DKGParticipant) 2071 for i, node := range participants.Filter(filter.HasRole(flow.RoleConsensus)) { 2072 lookup[node.NodeID] = flow.DKGParticipant{ 2073 Index: uint(i), 2074 KeyShare: KeyFixture(crypto.BLSBLS12381).PublicKey(), 2075 } 2076 } 2077 return lookup 2078 } 2079 2080 func CommitWithCounter(counter uint64) func(*flow.EpochCommit) { 2081 return func(commit *flow.EpochCommit) { 2082 commit.Counter = counter 2083 } 2084 } 2085 2086 func EpochCommitFixture(opts ...func(*flow.EpochCommit)) *flow.EpochCommit { 2087 commit := &flow.EpochCommit{ 2088 Counter: uint64(rand.Uint32()), 2089 ClusterQCs: flow.ClusterQCVoteDatasFromQCs(QuorumCertificatesWithSignerIDsFixtures(1)), 2090 DKGGroupKey: KeyFixture(crypto.BLSBLS12381).PublicKey(), 2091 DKGParticipantKeys: PublicKeysFixture(2, crypto.BLSBLS12381), 2092 } 2093 for _, apply := range opts { 2094 apply(commit) 2095 } 2096 return commit 2097 } 2098 2099 func WithBoundaries(boundaries ...flow.VersionBoundary) func(*flow.VersionBeacon) { 2100 return func(b *flow.VersionBeacon) { 2101 b.VersionBoundaries = append(b.VersionBoundaries, boundaries...) 2102 } 2103 } 2104 2105 func VersionBeaconFixture(options ...func(*flow.VersionBeacon)) *flow.VersionBeacon { 2106 2107 versionTable := &flow.VersionBeacon{ 2108 VersionBoundaries: []flow.VersionBoundary{}, 2109 Sequence: uint64(0), 2110 } 2111 opts := options 2112 2113 if len(opts) == 0 { 2114 opts = []func(*flow.VersionBeacon){ 2115 WithBoundaries(flow.VersionBoundary{ 2116 Version: "0.0.0", 2117 BlockHeight: 0, 2118 }), 2119 } 2120 } 2121 2122 for _, apply := range opts { 2123 apply(versionTable) 2124 } 2125 2126 return versionTable 2127 } 2128 2129 // BootstrapFixture generates all the artifacts necessary to bootstrap the 2130 // protocol state. 2131 func BootstrapFixture( 2132 participants flow.IdentityList, 2133 opts ...func(*flow.Block), 2134 ) (*flow.Block, *flow.ExecutionResult, *flow.Seal) { 2135 return BootstrapFixtureWithChainID(participants, flow.Emulator, opts...) 2136 } 2137 2138 func BootstrapFixtureWithChainID( 2139 participants flow.IdentityList, 2140 chainID flow.ChainID, 2141 opts ...func(*flow.Block), 2142 ) (*flow.Block, *flow.ExecutionResult, *flow.Seal) { 2143 2144 root := flow.Genesis(chainID) 2145 for _, apply := range opts { 2146 apply(root) 2147 } 2148 2149 counter := uint64(1) 2150 setup := EpochSetupFixture( 2151 WithParticipants(participants), 2152 SetupWithCounter(counter), 2153 WithFirstView(root.Header.View), 2154 WithFinalView(root.Header.View+1000), 2155 ) 2156 commit := EpochCommitFixture( 2157 CommitWithCounter(counter), 2158 WithClusterQCsFromAssignments(setup.Assignments), 2159 WithDKGFromParticipants(participants), 2160 ) 2161 2162 stateCommit := GenesisStateCommitmentByChainID(chainID) 2163 result := BootstrapExecutionResultFixture(root, stateCommit) 2164 result.ServiceEvents = []flow.ServiceEvent{ 2165 setup.ServiceEvent(), 2166 commit.ServiceEvent(), 2167 } 2168 2169 seal := Seal.Fixture(Seal.WithResult(result)) 2170 2171 return root, result, seal 2172 } 2173 2174 // RootSnapshotFixture returns a snapshot representing a root chain state, for 2175 // example one as returned from BootstrapFixture. 2176 func RootSnapshotFixture( 2177 participants flow.IdentityList, 2178 opts ...func(*flow.Block), 2179 ) *inmem.Snapshot { 2180 return RootSnapshotFixtureWithChainID(participants, flow.Emulator, opts...) 2181 } 2182 2183 func RootSnapshotFixtureWithChainID( 2184 participants flow.IdentityList, 2185 chainID flow.ChainID, 2186 opts ...func(*flow.Block), 2187 ) *inmem.Snapshot { 2188 block, result, seal := BootstrapFixtureWithChainID(participants.Sort(flow.Canonical), chainID, opts...) 2189 qc := QuorumCertificateFixture(QCWithRootBlockID(block.ID())) 2190 root, err := inmem.SnapshotFromBootstrapState(block, result, seal, qc) 2191 if err != nil { 2192 panic(err) 2193 } 2194 return root 2195 } 2196 2197 func SnapshotClusterByIndex( 2198 snapshot *inmem.Snapshot, 2199 clusterIndex uint, 2200 ) (protocol.Cluster, error) { 2201 epochs := snapshot.Epochs() 2202 epoch := epochs.Current() 2203 cluster, err := epoch.Cluster(clusterIndex) 2204 if err != nil { 2205 return nil, err 2206 } 2207 return cluster, nil 2208 } 2209 2210 // ChainFixture creates a list of blocks that forms a chain 2211 func ChainFixture(nonGenesisCount int) ( 2212 []*flow.Block, 2213 *flow.ExecutionResult, 2214 *flow.Seal, 2215 ) { 2216 chain := make([]*flow.Block, 0, nonGenesisCount+1) 2217 2218 participants := IdentityListFixture(5, WithAllRoles()) 2219 genesis, result, seal := BootstrapFixture(participants) 2220 chain = append(chain, genesis) 2221 2222 children := ChainFixtureFrom(nonGenesisCount, genesis.Header) 2223 chain = append(chain, children...) 2224 return chain, result, seal 2225 } 2226 2227 // ChainFixtureFrom creates a chain of blocks starting from a given parent block, 2228 // the total number of blocks in the chain is specified by the given count 2229 func ChainFixtureFrom(count int, parent *flow.Header) []*flow.Block { 2230 blocks := make([]*flow.Block, 0, count) 2231 2232 for i := 0; i < count; i++ { 2233 block := BlockWithParentFixture(parent) 2234 blocks = append(blocks, block) 2235 parent = block.Header 2236 } 2237 2238 return blocks 2239 } 2240 2241 func ReceiptChainFor( 2242 blocks []*flow.Block, 2243 result0 *flow.ExecutionResult, 2244 ) []*flow.ExecutionReceipt { 2245 receipts := make([]*flow.ExecutionReceipt, len(blocks)) 2246 receipts[0] = ExecutionReceiptFixture(WithResult(result0)) 2247 receipts[0].ExecutionResult.BlockID = blocks[0].ID() 2248 2249 for i := 1; i < len(blocks); i++ { 2250 b := blocks[i] 2251 prevReceipt := receipts[i-1] 2252 receipt := ReceiptForBlockFixture(b) 2253 receipt.ExecutionResult.PreviousResultID = prevReceipt.ExecutionResult.ID() 2254 prevLastChunk := prevReceipt.ExecutionResult.Chunks[len(prevReceipt.ExecutionResult.Chunks)-1] 2255 receipt.ExecutionResult.Chunks[0].StartState = prevLastChunk.EndState 2256 receipts[i] = receipt 2257 } 2258 2259 return receipts 2260 } 2261 2262 // ReconnectBlocksAndReceipts re-computes each block's PayloadHash and ParentID 2263 // so that all the blocks are connected. 2264 // blocks' height have to be in strict increasing order. 2265 func ReconnectBlocksAndReceipts(blocks []*flow.Block, receipts []*flow.ExecutionReceipt) { 2266 for i := 1; i < len(blocks); i++ { 2267 b := blocks[i] 2268 p := i - 1 2269 prev := blocks[p] 2270 if prev.Header.Height+1 != b.Header.Height { 2271 panic(fmt.Sprintf("height has gap when connecting blocks: expect %v, but got %v", prev.Header.Height+1, b.Header.Height)) 2272 } 2273 b.Header.ParentID = prev.ID() 2274 b.Header.PayloadHash = b.Payload.Hash() 2275 receipts[i].ExecutionResult.BlockID = b.ID() 2276 prevReceipt := receipts[p] 2277 receipts[i].ExecutionResult.PreviousResultID = prevReceipt.ExecutionResult.ID() 2278 for _, c := range receipts[i].ExecutionResult.Chunks { 2279 c.BlockID = b.ID() 2280 } 2281 } 2282 2283 // after changing results we need to update IDs of results in receipt 2284 for _, block := range blocks { 2285 if len(block.Payload.Results) > 0 { 2286 for i := range block.Payload.Receipts { 2287 block.Payload.Receipts[i].ResultID = block.Payload.Results[i].ID() 2288 } 2289 } 2290 } 2291 } 2292 2293 // DKGMessageFixture creates a single DKG message with random fields 2294 func DKGMessageFixture() *messages.DKGMessage { 2295 return &messages.DKGMessage{ 2296 Data: RandomBytes(10), 2297 DKGInstanceID: fmt.Sprintf("test-dkg-instance-%d", uint64(rand.Int())), 2298 } 2299 } 2300 2301 // DKGBroadcastMessageFixture creates a single DKG broadcast message with random fields 2302 func DKGBroadcastMessageFixture() *messages.BroadcastDKGMessage { 2303 return &messages.BroadcastDKGMessage{ 2304 DKGMessage: *DKGMessageFixture(), 2305 CommitteeMemberIndex: uint64(rand.Int()), 2306 NodeID: IdentifierFixture(), 2307 Signature: SignatureFixture(), 2308 } 2309 } 2310 2311 // PrivateKeyFixture returns a random private key with specified signature algorithm and seed length 2312 func PrivateKeyFixture(algo crypto.SigningAlgorithm, seedLength int) crypto.PrivateKey { 2313 sk, err := crypto.GeneratePrivateKey(algo, SeedFixture(seedLength)) 2314 if err != nil { 2315 panic(err) 2316 } 2317 return sk 2318 } 2319 2320 // PrivateKeyFixtureByIdentifier returns a private key for a given node. 2321 // given the same identifier, it will always return the same private key 2322 func PrivateKeyFixtureByIdentifier( 2323 algo crypto.SigningAlgorithm, 2324 seedLength int, 2325 id flow.Identifier, 2326 ) crypto.PrivateKey { 2327 seed := append(id[:], id[:]...) 2328 sk, err := crypto.GeneratePrivateKey(algo, seed[:seedLength]) 2329 if err != nil { 2330 panic(err) 2331 } 2332 return sk 2333 } 2334 2335 func StakingPrivKeyByIdentifier(id flow.Identifier) crypto.PrivateKey { 2336 return PrivateKeyFixtureByIdentifier(crypto.BLSBLS12381, crypto.KeyGenSeedMinLen, id) 2337 } 2338 2339 // NetworkingPrivKeyFixture returns random ECDSAP256 private key 2340 func NetworkingPrivKeyFixture() crypto.PrivateKey { 2341 return PrivateKeyFixture(crypto.ECDSAP256, crypto.KeyGenSeedMinLen) 2342 } 2343 2344 // StakingPrivKeyFixture returns a random BLS12381 private keyf 2345 func StakingPrivKeyFixture() crypto.PrivateKey { 2346 return PrivateKeyFixture(crypto.BLSBLS12381, crypto.KeyGenSeedMinLen) 2347 } 2348 2349 func NodeMachineAccountInfoFixture() bootstrap.NodeMachineAccountInfo { 2350 return bootstrap.NodeMachineAccountInfo{ 2351 Address: RandomAddressFixture().String(), 2352 EncodedPrivateKey: PrivateKeyFixture(crypto.ECDSAP256, DefaultSeedFixtureLength).Encode(), 2353 HashAlgorithm: bootstrap.DefaultMachineAccountHashAlgo, 2354 SigningAlgorithm: bootstrap.DefaultMachineAccountSignAlgo, 2355 KeyIndex: bootstrap.DefaultMachineAccountKeyIndex, 2356 } 2357 } 2358 2359 func MachineAccountFixture(t *testing.T) ( 2360 bootstrap.NodeMachineAccountInfo, 2361 *sdk.Account, 2362 ) { 2363 info := NodeMachineAccountInfoFixture() 2364 2365 bal, err := cadence.NewUFix64("0.5") 2366 require.NoError(t, err) 2367 2368 acct := &sdk.Account{ 2369 Address: sdk.HexToAddress(info.Address), 2370 Balance: uint64(bal), 2371 Keys: []*sdk.AccountKey{ 2372 { 2373 Index: int(info.KeyIndex), 2374 PublicKey: info.MustPrivateKey().PublicKey(), 2375 SigAlgo: info.SigningAlgorithm, 2376 HashAlgo: info.HashAlgorithm, 2377 Weight: 1000, 2378 }, 2379 }, 2380 } 2381 return info, acct 2382 } 2383 2384 func TransactionResultsFixture(n int) []flow.TransactionResult { 2385 results := make([]flow.TransactionResult, 0, n) 2386 for i := 0; i < n; i++ { 2387 results = append(results, flow.TransactionResult{ 2388 TransactionID: IdentifierFixture(), 2389 ErrorMessage: "whatever", 2390 ComputationUsed: uint64(rand.Uint32()), 2391 }) 2392 } 2393 return results 2394 } 2395 2396 func LightTransactionResultsFixture(n int) []flow.LightTransactionResult { 2397 results := make([]flow.LightTransactionResult, 0, n) 2398 for i := 0; i < n; i++ { 2399 results = append(results, flow.LightTransactionResult{ 2400 TransactionID: IdentifierFixture(), 2401 Failed: i%2 == 0, 2402 ComputationUsed: Uint64InRange(1, 10_000), 2403 }) 2404 } 2405 return results 2406 } 2407 2408 func AllowAllPeerFilter() func(peer.ID) error { 2409 return func(_ peer.ID) error { 2410 return nil 2411 } 2412 } 2413 2414 func NewSealingConfigs(val uint) module.SealingConfigsSetter { 2415 instance, err := updatable_configs.NewSealingConfigs( 2416 flow.DefaultRequiredApprovalsForSealConstruction, 2417 flow.DefaultRequiredApprovalsForSealValidation, 2418 flow.DefaultChunkAssignmentAlpha, 2419 flow.DefaultEmergencySealingActive, 2420 ) 2421 if err != nil { 2422 panic(err) 2423 } 2424 err = instance.SetRequiredApprovalsForSealingConstruction(val) 2425 if err != nil { 2426 panic(err) 2427 } 2428 return instance 2429 } 2430 2431 func PeerIDFromFlowID(identity *flow.Identity) (peer.ID, error) { 2432 networkKey := identity.NetworkPubKey 2433 peerPK, err := keyutils.LibP2PPublicKeyFromFlow(networkKey) 2434 if err != nil { 2435 return "", err 2436 } 2437 2438 peerID, err := peer.IDFromPublicKey(peerPK) 2439 if err != nil { 2440 return "", err 2441 } 2442 2443 return peerID, nil 2444 } 2445 2446 func EngineMessageFixture() *engine.Message { 2447 return &engine.Message{ 2448 OriginID: IdentifierFixture(), 2449 Payload: RandomBytes(10), 2450 } 2451 } 2452 2453 func EngineMessageFixtures(count int) []*engine.Message { 2454 messages := make([]*engine.Message, 0, count) 2455 for i := 0; i < count; i++ { 2456 messages = append(messages, EngineMessageFixture()) 2457 } 2458 return messages 2459 } 2460 2461 // GetFlowProtocolEventID returns the event ID for the event provided. 2462 func GetFlowProtocolEventID( 2463 t *testing.T, 2464 channel channels.Channel, 2465 event interface{}, 2466 ) flow.Identifier { 2467 payload, err := NetworkCodec().Encode(event) 2468 require.NoError(t, err) 2469 eventIDHash, err := message.EventId(channel, payload) 2470 require.NoError(t, err) 2471 return flow.HashToID(eventIDHash) 2472 } 2473 2474 func WithBlockExecutionDataBlockID(blockID flow.Identifier) func(*execution_data.BlockExecutionData) { 2475 return func(bed *execution_data.BlockExecutionData) { 2476 bed.BlockID = blockID 2477 } 2478 } 2479 2480 func WithChunkExecutionDatas(chunks ...*execution_data.ChunkExecutionData) func(*execution_data.BlockExecutionData) { 2481 return func(bed *execution_data.BlockExecutionData) { 2482 bed.ChunkExecutionDatas = chunks 2483 } 2484 } 2485 2486 func BlockExecutionDataFixture(opts ...func(*execution_data.BlockExecutionData)) *execution_data.BlockExecutionData { 2487 bed := &execution_data.BlockExecutionData{ 2488 BlockID: IdentifierFixture(), 2489 ChunkExecutionDatas: []*execution_data.ChunkExecutionData{}, 2490 } 2491 2492 for _, opt := range opts { 2493 opt(bed) 2494 } 2495 2496 return bed 2497 } 2498 2499 func BlockExecutionDatEntityFixture(opts ...func(*execution_data.BlockExecutionData)) *execution_data.BlockExecutionDataEntity { 2500 execData := BlockExecutionDataFixture(opts...) 2501 return execution_data.NewBlockExecutionDataEntity(IdentifierFixture(), execData) 2502 } 2503 2504 func BlockExecutionDatEntityListFixture(n int) []*execution_data.BlockExecutionDataEntity { 2505 l := make([]*execution_data.BlockExecutionDataEntity, n) 2506 for i := 0; i < n; i++ { 2507 l[i] = BlockExecutionDatEntityFixture() 2508 } 2509 2510 return l 2511 } 2512 2513 func WithChunkEvents(events flow.EventsList) func(*execution_data.ChunkExecutionData) { 2514 return func(conf *execution_data.ChunkExecutionData) { 2515 conf.Events = events 2516 } 2517 } 2518 2519 func WithTrieUpdate(trieUpdate *ledger.TrieUpdate) func(*execution_data.ChunkExecutionData) { 2520 return func(conf *execution_data.ChunkExecutionData) { 2521 conf.TrieUpdate = trieUpdate 2522 } 2523 } 2524 2525 func ChunkExecutionDataFixture(t *testing.T, minSize int, opts ...func(*execution_data.ChunkExecutionData)) *execution_data.ChunkExecutionData { 2526 collection := CollectionFixture(5) 2527 results := make([]flow.LightTransactionResult, len(collection.Transactions)) 2528 for i, tx := range collection.Transactions { 2529 results[i] = flow.LightTransactionResult{ 2530 TransactionID: tx.ID(), 2531 Failed: false, 2532 ComputationUsed: uint64(i * 100), 2533 } 2534 } 2535 2536 ced := &execution_data.ChunkExecutionData{ 2537 Collection: &collection, 2538 Events: nil, 2539 TrieUpdate: testutils.TrieUpdateFixture(2, 1, 8), 2540 TransactionResults: results, 2541 } 2542 2543 for _, opt := range opts { 2544 opt(ced) 2545 } 2546 2547 if minSize <= 1 || ced.TrieUpdate == nil { 2548 return ced 2549 } 2550 2551 size := 1 2552 for { 2553 buf := &bytes.Buffer{} 2554 require.NoError(t, execution_data.DefaultSerializer.Serialize(buf, ced)) 2555 if buf.Len() >= minSize { 2556 return ced 2557 } 2558 2559 v := make([]byte, size) 2560 _, err := crand.Read(v) 2561 require.NoError(t, err) 2562 2563 k, err := ced.TrieUpdate.Payloads[0].Key() 2564 require.NoError(t, err) 2565 2566 ced.TrieUpdate.Payloads[0] = ledger.NewPayload(k, v) 2567 size *= 2 2568 } 2569 } 2570 2571 func CreateSendTxHttpPayload(tx flow.TransactionBody) map[string]interface{} { 2572 tx.Arguments = [][]uint8{} // fix how fixture creates nil values 2573 auth := make([]string, len(tx.Authorizers)) 2574 for i, a := range tx.Authorizers { 2575 auth[i] = a.String() 2576 } 2577 2578 return map[string]interface{}{ 2579 "script": util.ToBase64(tx.Script), 2580 "arguments": tx.Arguments, 2581 "reference_block_id": tx.ReferenceBlockID.String(), 2582 "gas_limit": fmt.Sprintf("%d", tx.GasLimit), 2583 "payer": tx.Payer.String(), 2584 "proposal_key": map[string]interface{}{ 2585 "address": tx.ProposalKey.Address.String(), 2586 "key_index": fmt.Sprintf("%d", tx.ProposalKey.KeyIndex), 2587 "sequence_number": fmt.Sprintf("%d", tx.ProposalKey.SequenceNumber), 2588 }, 2589 "authorizers": auth, 2590 "payload_signatures": []map[string]interface{}{{ 2591 "address": tx.PayloadSignatures[0].Address.String(), 2592 "key_index": fmt.Sprintf("%d", tx.PayloadSignatures[0].KeyIndex), 2593 "signature": util.ToBase64(tx.PayloadSignatures[0].Signature), 2594 }}, 2595 "envelope_signatures": []map[string]interface{}{{ 2596 "address": tx.EnvelopeSignatures[0].Address.String(), 2597 "key_index": fmt.Sprintf("%d", tx.EnvelopeSignatures[0].KeyIndex), 2598 "signature": util.ToBase64(tx.EnvelopeSignatures[0].Signature), 2599 }}, 2600 } 2601 } 2602 2603 // P2PRPCGraftFixtures returns n number of control message rpc Graft fixtures. 2604 func P2PRPCGraftFixtures(topics ...string) []*pubsub_pb.ControlGraft { 2605 n := len(topics) 2606 grafts := make([]*pubsub_pb.ControlGraft, n) 2607 for i := 0; i < n; i++ { 2608 grafts[i] = P2PRPCGraftFixture(&topics[i]) 2609 } 2610 return grafts 2611 } 2612 2613 // P2PRPCGraftFixture returns a control message rpc Graft fixture. 2614 func P2PRPCGraftFixture(topic *string) *pubsub_pb.ControlGraft { 2615 return &pubsub_pb.ControlGraft{ 2616 TopicID: topic, 2617 } 2618 } 2619 2620 // P2PRPCPruneFixtures returns n number of control message rpc Prune fixtures. 2621 func P2PRPCPruneFixtures(topics ...string) []*pubsub_pb.ControlPrune { 2622 n := len(topics) 2623 prunes := make([]*pubsub_pb.ControlPrune, n) 2624 for i := 0; i < n; i++ { 2625 prunes[i] = P2PRPCPruneFixture(&topics[i]) 2626 } 2627 return prunes 2628 } 2629 2630 // P2PRPCPruneFixture returns a control message rpc Prune fixture. 2631 func P2PRPCPruneFixture(topic *string) *pubsub_pb.ControlPrune { 2632 return &pubsub_pb.ControlPrune{ 2633 TopicID: topic, 2634 } 2635 } 2636 2637 // P2PRPCIHaveFixtures returns n number of control message where n = len(topics) rpc iHave fixtures with m number of message ids each. 2638 func P2PRPCIHaveFixtures(m int, topics ...string) []*pubsub_pb.ControlIHave { 2639 n := len(topics) 2640 ihaves := make([]*pubsub_pb.ControlIHave, n) 2641 for i := 0; i < n; i++ { 2642 ihaves[i] = P2PRPCIHaveFixture(&topics[i], IdentifierListFixture(m).Strings()...) 2643 } 2644 return ihaves 2645 } 2646 2647 // P2PRPCIHaveFixture returns a control message rpc iHave fixture. 2648 func P2PRPCIHaveFixture(topic *string, messageIds ...string) *pubsub_pb.ControlIHave { 2649 return &pubsub_pb.ControlIHave{ 2650 TopicID: topic, 2651 MessageIDs: messageIds, 2652 } 2653 } 2654 2655 // P2PRPCIWantFixtures returns n number of control message rpc iWant fixtures with m number of message ids each. 2656 func P2PRPCIWantFixtures(n, m int) []*pubsub_pb.ControlIWant { 2657 iwants := make([]*pubsub_pb.ControlIWant, n) 2658 for i := 0; i < n; i++ { 2659 iwants[i] = P2PRPCIWantFixture(IdentifierListFixture(m).Strings()...) 2660 } 2661 return iwants 2662 } 2663 2664 // P2PRPCIWantFixture returns a control message rpc iWant fixture. 2665 func P2PRPCIWantFixture(messageIds ...string) *pubsub_pb.ControlIWant { 2666 return &pubsub_pb.ControlIWant{ 2667 MessageIDs: messageIds, 2668 } 2669 } 2670 2671 type RPCFixtureOpt func(rpc *pubsub.RPC) 2672 2673 // WithGrafts sets the grafts on the rpc control message. 2674 func WithGrafts(grafts ...*pubsub_pb.ControlGraft) RPCFixtureOpt { 2675 return func(rpc *pubsub.RPC) { 2676 rpc.Control.Graft = grafts 2677 } 2678 } 2679 2680 // WithPrunes sets the prunes on the rpc control message. 2681 func WithPrunes(prunes ...*pubsub_pb.ControlPrune) RPCFixtureOpt { 2682 return func(rpc *pubsub.RPC) { 2683 rpc.Control.Prune = prunes 2684 } 2685 } 2686 2687 // WithIHaves sets the iHaves on the rpc control message. 2688 func WithIHaves(iHaves ...*pubsub_pb.ControlIHave) RPCFixtureOpt { 2689 return func(rpc *pubsub.RPC) { 2690 rpc.Control.Ihave = iHaves 2691 } 2692 } 2693 2694 // WithIWants sets the iWants on the rpc control message. 2695 func WithIWants(iWants ...*pubsub_pb.ControlIWant) RPCFixtureOpt { 2696 return func(rpc *pubsub.RPC) { 2697 rpc.Control.Iwant = iWants 2698 } 2699 } 2700 2701 func WithPubsubMessages(msgs ...*pubsub_pb.Message) RPCFixtureOpt { 2702 return func(rpc *pubsub.RPC) { 2703 rpc.Publish = msgs 2704 } 2705 } 2706 2707 // P2PRPCFixture returns a pubsub RPC fixture. Currently, this fixture only sets the ControlMessage field. 2708 func P2PRPCFixture(opts ...RPCFixtureOpt) *pubsub.RPC { 2709 rpc := &pubsub.RPC{ 2710 RPC: pubsub_pb.RPC{ 2711 Control: &pubsub_pb.ControlMessage{}, 2712 }, 2713 } 2714 2715 for _, opt := range opts { 2716 opt(rpc) 2717 } 2718 2719 return rpc 2720 } 2721 2722 func WithFrom(pid peer.ID) func(*pubsub_pb.Message) { 2723 return func(msg *pubsub_pb.Message) { 2724 msg.From = []byte(pid) 2725 } 2726 } 2727 2728 // GossipSubMessageFixture returns a gossip sub message fixture for the specified topic. 2729 func GossipSubMessageFixture(s string, opts ...func(*pubsub_pb.Message)) *pubsub_pb.Message { 2730 pb := &pubsub_pb.Message{ 2731 From: RandomBytes(32), 2732 Data: RandomBytes(32), 2733 Seqno: RandomBytes(10), 2734 Topic: &s, 2735 Signature: RandomBytes(100), 2736 Key: RandomBytes(32), 2737 } 2738 2739 for _, opt := range opts { 2740 opt(pb) 2741 } 2742 2743 return pb 2744 } 2745 2746 // GossipSubMessageFixtures returns a list of gossipsub message fixtures. 2747 func GossipSubMessageFixtures(n int, topic string, opts ...func(*pubsub_pb.Message)) []*pubsub_pb.Message { 2748 msgs := make([]*pubsub_pb.Message, n) 2749 for i := 0; i < n; i++ { 2750 msgs[i] = GossipSubMessageFixture(topic, opts...) 2751 } 2752 return msgs 2753 } 2754 2755 // LibP2PResourceLimitOverrideFixture returns a random resource limit override for testing. 2756 // The values are not guaranteed to be valid between 0 and 1000. 2757 // Returns: 2758 // - p2pconf.ResourceManagerOverrideLimit: a random resource limit override. 2759 func LibP2PResourceLimitOverrideFixture() p2pconfig.ResourceManagerOverrideLimit { 2760 return p2pconfig.ResourceManagerOverrideLimit{ 2761 StreamsInbound: rand.Intn(1000), 2762 StreamsOutbound: rand.Intn(1000), 2763 ConnectionsInbound: rand.Intn(1000), 2764 ConnectionsOutbound: rand.Intn(1000), 2765 FD: rand.Intn(1000), 2766 Memory: rand.Intn(1000), 2767 } 2768 } 2769 2770 func RegisterEntryFixture() flow.RegisterEntry { 2771 val := make([]byte, 4) 2772 _, _ = crand.Read(val) 2773 return flow.RegisterEntry{ 2774 Key: flow.RegisterID{ 2775 Owner: "owner", 2776 Key: "key1", 2777 }, 2778 Value: val, 2779 } 2780 } 2781 2782 func MakeOwnerReg(key string, value string) flow.RegisterEntry { 2783 return flow.RegisterEntry{ 2784 Key: flow.RegisterID{ 2785 Owner: "owner", 2786 Key: key, 2787 }, 2788 Value: []byte(value), 2789 } 2790 }