github.com/koko1123/flow-go-1@v0.29.6/utils/unittest/fixtures.go (about) 1 package unittest 2 3 import ( 4 crand "crypto/rand" 5 "fmt" 6 "math/rand" 7 "net" 8 "testing" 9 "time" 10 11 blocks "github.com/ipfs/go-block-format" 12 "github.com/ipfs/go-cid" 13 "github.com/libp2p/go-libp2p/core/peer" 14 "github.com/stretchr/testify/require" 15 16 "github.com/onflow/cadence" 17 18 sdk "github.com/onflow/flow-go-sdk" 19 hotstuff "github.com/koko1123/flow-go-1/consensus/hotstuff/model" 20 "github.com/onflow/flow-go/crypto" 21 "github.com/onflow/flow-go/crypto/hash" 22 "github.com/koko1123/flow-go-1/engine" 23 "github.com/koko1123/flow-go-1/engine/execution/state/delta" 24 "github.com/koko1123/flow-go-1/ledger/common/bitutils" 25 "github.com/koko1123/flow-go-1/model/bootstrap" 26 "github.com/koko1123/flow-go-1/model/chainsync" 27 "github.com/koko1123/flow-go-1/model/chunks" 28 "github.com/koko1123/flow-go-1/model/cluster" 29 "github.com/koko1123/flow-go-1/model/encoding" 30 "github.com/koko1123/flow-go-1/model/flow" 31 "github.com/koko1123/flow-go-1/model/flow/filter" 32 "github.com/koko1123/flow-go-1/model/flow/order" 33 "github.com/koko1123/flow-go-1/model/messages" 34 "github.com/koko1123/flow-go-1/model/verification" 35 "github.com/koko1123/flow-go-1/module" 36 "github.com/koko1123/flow-go-1/module/mempool/entity" 37 "github.com/koko1123/flow-go-1/module/updatable_configs" 38 "github.com/koko1123/flow-go-1/network" 39 "github.com/koko1123/flow-go-1/network/channels" 40 "github.com/koko1123/flow-go-1/network/p2p/keyutils" 41 "github.com/koko1123/flow-go-1/state/protocol" 42 "github.com/koko1123/flow-go-1/state/protocol/inmem" 43 "github.com/koko1123/flow-go-1/utils/dsl" 44 ) 45 46 const ( 47 DefaultSeedFixtureLength = 64 48 DefaultAddress = "localhost:0" 49 ) 50 51 func IPPort(port string) string { 52 return net.JoinHostPort("localhost", port) 53 } 54 55 func AddressFixture() flow.Address { 56 return flow.Testnet.Chain().ServiceAddress() 57 } 58 59 func RandomAddressFixture() flow.Address { 60 // we use a 32-bit index - since the linear address generator uses 45 bits, 61 // this won't error 62 addr, err := flow.Testnet.Chain().AddressAtIndex(uint64(rand.Uint32())) 63 if err != nil { 64 panic(err) 65 } 66 return addr 67 } 68 69 func RandomSDKAddressFixture() sdk.Address { 70 addr := RandomAddressFixture() 71 var sdkAddr sdk.Address 72 copy(sdkAddr[:], addr[:]) 73 return sdkAddr 74 } 75 76 func InvalidAddressFixture() flow.Address { 77 addr := AddressFixture() 78 addr[0] ^= 1 // alter one bit to obtain an invalid address 79 if flow.Testnet.Chain().IsValid(addr) { 80 panic("invalid address fixture generated valid address") 81 } 82 return addr 83 } 84 85 func InvalidFormatSignature() flow.TransactionSignature { 86 return flow.TransactionSignature{ 87 Address: AddressFixture(), 88 SignerIndex: 0, 89 Signature: make([]byte, crypto.SignatureLenECDSAP256), // zero signature is invalid 90 KeyIndex: 1, 91 } 92 } 93 94 func TransactionSignatureFixture() flow.TransactionSignature { 95 sigLen := crypto.SignatureLenECDSAP256 96 s := flow.TransactionSignature{ 97 Address: AddressFixture(), 98 SignerIndex: 0, 99 Signature: SeedFixture(sigLen), 100 KeyIndex: 1, 101 } 102 // make sure the ECDSA signature passes the format check 103 s.Signature[sigLen/2] = 0 104 s.Signature[0] = 0 105 s.Signature[sigLen/2-1] |= 1 106 s.Signature[sigLen-1] |= 1 107 return s 108 } 109 110 func ProposalKeyFixture() flow.ProposalKey { 111 return flow.ProposalKey{ 112 Address: AddressFixture(), 113 KeyIndex: 1, 114 SequenceNumber: 0, 115 } 116 } 117 118 // AccountKeyDefaultFixture returns a randomly generated ECDSA/SHA3 account key. 119 func AccountKeyDefaultFixture() (*flow.AccountPrivateKey, error) { 120 return AccountKeyFixture(crypto.KeyGenSeedMinLenECDSAP256, crypto.ECDSAP256, hash.SHA3_256) 121 } 122 123 // AccountKeyFixture returns a randomly generated account key. 124 func AccountKeyFixture( 125 seedLength int, 126 signingAlgo crypto.SigningAlgorithm, 127 hashAlgo hash.HashingAlgorithm, 128 ) (*flow.AccountPrivateKey, error) { 129 seed := make([]byte, seedLength) 130 131 _, err := crand.Read(seed) 132 if err != nil { 133 return nil, err 134 } 135 136 key, err := crypto.GeneratePrivateKey(signingAlgo, seed) 137 if err != nil { 138 return nil, err 139 } 140 141 return &flow.AccountPrivateKey{ 142 PrivateKey: key, 143 SignAlgo: key.Algorithm(), 144 HashAlgo: hashAlgo, 145 }, nil 146 } 147 148 // AccountFixture returns a randomly generated account. 149 func AccountFixture() (*flow.Account, error) { 150 key, err := AccountKeyFixture(128, crypto.ECDSAP256, hash.SHA3_256) 151 if err != nil { 152 return nil, err 153 } 154 155 contracts := make(map[string][]byte, 2) 156 contracts["contract1"] = []byte("contract1") 157 contracts["contract2"] = []byte("contract2") 158 159 return &flow.Account{ 160 Address: RandomAddressFixture(), 161 Balance: 100, 162 Keys: []flow.AccountPublicKey{key.PublicKey(1000)}, 163 Contracts: contracts, 164 }, nil 165 } 166 167 func BlockFixture() flow.Block { 168 header := BlockHeaderFixture() 169 return *BlockWithParentFixture(header) 170 } 171 172 func FullBlockFixture() flow.Block { 173 block := BlockFixture() 174 payload := block.Payload 175 payload.Seals = Seal.Fixtures(10) 176 payload.Results = []*flow.ExecutionResult{ 177 ExecutionResultFixture(), 178 ExecutionResultFixture(), 179 } 180 payload.Receipts = []*flow.ExecutionReceiptMeta{ 181 ExecutionReceiptFixture(WithResult(payload.Results[0])).Meta(), 182 ExecutionReceiptFixture(WithResult(payload.Results[1])).Meta(), 183 } 184 185 header := block.Header 186 header.PayloadHash = payload.Hash() 187 188 return flow.Block{ 189 Header: header, 190 Payload: payload, 191 } 192 } 193 194 func BlockFixtures(number int) []*flow.Block { 195 blocks := make([]*flow.Block, 0, number) 196 for ; number > 0; number-- { 197 block := BlockFixture() 198 blocks = append(blocks, &block) 199 } 200 return blocks 201 } 202 203 func ProposalFixture() *messages.BlockProposal { 204 block := BlockFixture() 205 return ProposalFromBlock(&block) 206 } 207 208 func ProposalFromBlock(block *flow.Block) *messages.BlockProposal { 209 return messages.NewBlockProposal(block) 210 } 211 212 func ClusterProposalFromBlock(block *cluster.Block) *messages.ClusterBlockProposal { 213 return messages.NewClusterBlockProposal(block) 214 } 215 216 // AsSlashable returns the input message T, wrapped as a flow.Slashable instance with a random origin ID. 217 func AsSlashable[T any](msg *T) flow.Slashable[T] { 218 slashable := flow.Slashable[T]{ 219 OriginID: IdentifierFixture(), 220 Message: msg, 221 } 222 return slashable 223 } 224 225 func StateDeltaFixture() *messages.ExecutionStateDelta { 226 header := BlockHeaderFixture() 227 block := BlockWithParentFixture(header) 228 return &messages.ExecutionStateDelta{ 229 ExecutableBlock: entity.ExecutableBlock{ 230 Block: block, 231 }, 232 } 233 } 234 235 func ReceiptAndSealForBlock(block *flow.Block) (*flow.ExecutionReceipt, *flow.Seal) { 236 receipt := ReceiptForBlockFixture(block) 237 seal := Seal.Fixture(Seal.WithBlock(block.Header), Seal.WithResult(&receipt.ExecutionResult)) 238 return receipt, seal 239 } 240 241 func PayloadFixture(options ...func(*flow.Payload)) flow.Payload { 242 payload := flow.EmptyPayload() 243 for _, option := range options { 244 option(&payload) 245 } 246 return payload 247 } 248 249 // WithAllTheFixins ensures a payload contains no empty slice fields. When 250 // encoding and decoding, nil vs empty slices are not preserved, which can 251 // result in two models that are semantically equal being considered non-equal 252 // by our testing framework. 253 func WithAllTheFixins(payload *flow.Payload) { 254 payload.Seals = Seal.Fixtures(3) 255 payload.Guarantees = CollectionGuaranteesFixture(4) 256 for i := 0; i < 10; i++ { 257 receipt := ExecutionReceiptFixture() 258 payload.Receipts = flow.ExecutionReceiptMetaList{receipt.Meta()} 259 payload.Results = flow.ExecutionResultList{&receipt.ExecutionResult} 260 } 261 } 262 263 func WithSeals(seals ...*flow.Seal) func(*flow.Payload) { 264 return func(payload *flow.Payload) { 265 payload.Seals = append(payload.Seals, seals...) 266 } 267 } 268 269 func WithGuarantees(guarantees ...*flow.CollectionGuarantee) func(*flow.Payload) { 270 return func(payload *flow.Payload) { 271 payload.Guarantees = append(payload.Guarantees, guarantees...) 272 } 273 } 274 275 func WithReceipts(receipts ...*flow.ExecutionReceipt) func(*flow.Payload) { 276 return func(payload *flow.Payload) { 277 for _, receipt := range receipts { 278 payload.Receipts = append(payload.Receipts, receipt.Meta()) 279 payload.Results = append(payload.Results, &receipt.ExecutionResult) 280 } 281 } 282 } 283 284 // WithReceiptsAndNoResults will add receipt to payload only 285 func WithReceiptsAndNoResults(receipts ...*flow.ExecutionReceipt) func(*flow.Payload) { 286 return func(payload *flow.Payload) { 287 for _, receipt := range receipts { 288 payload.Receipts = append(payload.Receipts, receipt.Meta()) 289 } 290 } 291 } 292 293 // WithExecutionResults will add execution results to payload 294 func WithExecutionResults(results ...*flow.ExecutionResult) func(*flow.Payload) { 295 return func(payload *flow.Payload) { 296 for _, result := range results { 297 payload.Results = append(payload.Results, result) 298 } 299 } 300 } 301 302 func BlockWithParentFixture(parent *flow.Header) *flow.Block { 303 payload := PayloadFixture() 304 header := BlockHeaderWithParentFixture(parent) 305 header.PayloadHash = payload.Hash() 306 return &flow.Block{ 307 Header: header, 308 Payload: &payload, 309 } 310 } 311 312 func BlockWithGuaranteesFixture(guarantees []*flow.CollectionGuarantee) *flow.Block { 313 payload := PayloadFixture(WithGuarantees(guarantees...)) 314 header := BlockHeaderFixture() 315 header.PayloadHash = payload.Hash() 316 return &flow.Block{ 317 Header: header, 318 Payload: &payload, 319 } 320 321 } 322 323 func WithoutGuarantee(payload *flow.Payload) { 324 payload.Guarantees = nil 325 } 326 327 func StateInteractionsFixture() *delta.Snapshot { 328 return &delta.NewView(nil).Interactions().Snapshot 329 } 330 331 func BlockWithParentAndProposerFixture(parent *flow.Header, proposer flow.Identifier, participantCount int) flow.Block { 332 block := BlockWithParentFixture(parent) 333 334 block.Header.ProposerID = proposer 335 indices := bitutils.MakeBitVector(10) 336 bitutils.SetBit(indices, 1) 337 block.Header.ParentVoterIndices = indices 338 339 return *block 340 } 341 342 func BlockWithParentAndSeals(parent *flow.Header, seals []*flow.Header) *flow.Block { 343 block := BlockWithParentFixture(parent) 344 payload := flow.Payload{ 345 Guarantees: nil, 346 } 347 348 if len(seals) > 0 { 349 payload.Seals = make([]*flow.Seal, len(seals)) 350 for i, seal := range seals { 351 payload.Seals[i] = Seal.Fixture( 352 Seal.WithBlockID(seal.ID()), 353 ) 354 } 355 } 356 357 block.SetPayload(payload) 358 return block 359 } 360 361 func StateDeltaWithParentFixture(parent *flow.Header) *messages.ExecutionStateDelta { 362 payload := PayloadFixture() 363 header := BlockHeaderWithParentFixture(parent) 364 header.PayloadHash = payload.Hash() 365 block := flow.Block{ 366 Header: header, 367 Payload: &payload, 368 } 369 370 var stateInteractions []*delta.Snapshot 371 stateInteractions = append(stateInteractions, StateInteractionsFixture()) 372 373 return &messages.ExecutionStateDelta{ 374 ExecutableBlock: entity.ExecutableBlock{ 375 Block: &block, 376 }, 377 StateInteractions: stateInteractions, 378 } 379 } 380 381 func GenesisFixture() *flow.Block { 382 genesis := flow.Genesis(flow.Emulator) 383 return genesis 384 } 385 386 func WithHeaderHeight(height uint64) func(header *flow.Header) { 387 return func(header *flow.Header) { 388 header.Height = height 389 } 390 } 391 392 func HeaderWithView(view uint64) func(*flow.Header) { 393 return func(header *flow.Header) { 394 header.View = view 395 } 396 } 397 398 func BlockHeaderFixture(opts ...func(header *flow.Header)) *flow.Header { 399 height := 1 + uint64(rand.Uint32()) // avoiding edge case of height = 0 (genesis block) 400 view := height + uint64(rand.Intn(1000)) 401 header := BlockHeaderWithParentFixture(&flow.Header{ 402 ChainID: flow.Emulator, 403 ParentID: IdentifierFixture(), 404 Height: height, 405 View: view, 406 }) 407 408 for _, opt := range opts { 409 opt(header) 410 } 411 412 return header 413 } 414 415 func CidFixture() cid.Cid { 416 data := make([]byte, 1024) 417 rand.Read(data) 418 return blocks.NewBlock(data).Cid() 419 } 420 421 func BlockHeaderFixtureOnChain(chainID flow.ChainID, opts ...func(header *flow.Header)) *flow.Header { 422 height := 1 + uint64(rand.Uint32()) // avoiding edge case of height = 0 (genesis block) 423 view := height + uint64(rand.Intn(1000)) 424 header := BlockHeaderWithParentFixture(&flow.Header{ 425 ChainID: chainID, 426 ParentID: IdentifierFixture(), 427 Height: height, 428 View: view, 429 }) 430 431 for _, opt := range opts { 432 opt(header) 433 } 434 435 return header 436 } 437 438 func BlockHeaderWithParentFixture(parent *flow.Header) *flow.Header { 439 height := parent.Height + 1 440 view := parent.View + 1 + uint64(rand.Intn(10)) // Intn returns [0, n) 441 return &flow.Header{ 442 ChainID: parent.ChainID, 443 ParentID: parent.ID(), 444 Height: height, 445 PayloadHash: IdentifierFixture(), 446 Timestamp: time.Now().UTC(), 447 View: view, 448 ParentVoterIndices: SignerIndicesFixture(4), 449 ParentVoterSigData: QCSigDataFixture(), 450 ProposerID: IdentifierFixture(), 451 ProposerSigData: SignatureFixture(), 452 } 453 } 454 455 func ClusterPayloadFixture(n int) *cluster.Payload { 456 transactions := make([]*flow.TransactionBody, n) 457 for i := 0; i < n; i++ { 458 tx := TransactionBodyFixture() 459 transactions[i] = &tx 460 } 461 payload := cluster.PayloadFromTransactions(flow.ZeroID, transactions...) 462 return &payload 463 } 464 465 func ClusterBlockFixture() cluster.Block { 466 467 payload := ClusterPayloadFixture(3) 468 header := BlockHeaderFixture() 469 header.PayloadHash = payload.Hash() 470 471 return cluster.Block{ 472 Header: header, 473 Payload: payload, 474 } 475 } 476 477 // ClusterBlockWithParent creates a new cluster consensus block that is valid 478 // with respect to the given parent block. 479 func ClusterBlockWithParent(parent *cluster.Block) cluster.Block { 480 481 payload := ClusterPayloadFixture(3) 482 483 header := BlockHeaderFixture() 484 header.Height = parent.Header.Height + 1 485 header.View = parent.Header.View + 1 486 header.ChainID = parent.Header.ChainID 487 header.Timestamp = time.Now() 488 header.ParentID = parent.ID() 489 header.PayloadHash = payload.Hash() 490 491 block := cluster.Block{ 492 Header: header, 493 Payload: payload, 494 } 495 496 return block 497 } 498 499 func WithCollRef(refID flow.Identifier) func(*flow.CollectionGuarantee) { 500 return func(guarantee *flow.CollectionGuarantee) { 501 guarantee.ReferenceBlockID = refID 502 } 503 } 504 505 func WithCollection(collection *flow.Collection) func(guarantee *flow.CollectionGuarantee) { 506 return func(guarantee *flow.CollectionGuarantee) { 507 guarantee.CollectionID = collection.ID() 508 } 509 } 510 511 func CollectionGuaranteeFixture(options ...func(*flow.CollectionGuarantee)) *flow.CollectionGuarantee { 512 guarantee := &flow.CollectionGuarantee{ 513 CollectionID: IdentifierFixture(), 514 SignerIndices: RandomBytes(16), 515 Signature: SignatureFixture(), 516 } 517 for _, option := range options { 518 option(guarantee) 519 } 520 return guarantee 521 } 522 523 func CollectionGuaranteesWithCollectionIDFixture(collections []*flow.Collection) []*flow.CollectionGuarantee { 524 guarantees := make([]*flow.CollectionGuarantee, 0, len(collections)) 525 for i := 0; i < len(collections); i++ { 526 guarantee := CollectionGuaranteeFixture(WithCollection(collections[i])) 527 guarantees = append(guarantees, guarantee) 528 } 529 return guarantees 530 } 531 532 func CollectionGuaranteesFixture(n int, options ...func(*flow.CollectionGuarantee)) []*flow.CollectionGuarantee { 533 guarantees := make([]*flow.CollectionGuarantee, 0, n) 534 for i := 1; i <= n; i++ { 535 guarantee := CollectionGuaranteeFixture(options...) 536 guarantees = append(guarantees, guarantee) 537 } 538 return guarantees 539 } 540 541 func BlockSealsFixture(n int) []*flow.Seal { 542 seals := make([]*flow.Seal, 0, n) 543 for i := 0; i < n; i++ { 544 seal := Seal.Fixture() 545 seals = append(seals, seal) 546 } 547 return seals 548 } 549 550 func CollectionListFixture(n int, options ...func(*flow.Collection)) []*flow.Collection { 551 collections := make([]*flow.Collection, n) 552 for i := 0; i < n; i++ { 553 collection := CollectionFixture(1, options...) 554 collections[i] = &collection 555 } 556 557 return collections 558 } 559 560 func CollectionFixture(n int, options ...func(*flow.Collection)) flow.Collection { 561 transactions := make([]*flow.TransactionBody, 0, n) 562 563 for i := 0; i < n; i++ { 564 tx := TransactionFixture() 565 transactions = append(transactions, &tx.TransactionBody) 566 } 567 568 col := flow.Collection{Transactions: transactions} 569 for _, opt := range options { 570 opt(&col) 571 } 572 return col 573 } 574 575 func FixedReferenceBlockID() flow.Identifier { 576 blockID := flow.Identifier{} 577 blockID[0] = byte(1) 578 return blockID 579 } 580 581 func CompleteCollectionFixture() *entity.CompleteCollection { 582 txBody := TransactionBodyFixture() 583 return &entity.CompleteCollection{ 584 Guarantee: &flow.CollectionGuarantee{ 585 CollectionID: flow.Collection{Transactions: []*flow.TransactionBody{&txBody}}.ID(), 586 Signature: SignatureFixture(), 587 ReferenceBlockID: FixedReferenceBlockID(), 588 SignerIndices: SignerIndicesFixture(1), 589 }, 590 Transactions: []*flow.TransactionBody{&txBody}, 591 } 592 } 593 594 func CompleteCollectionFromTransactions(txs []*flow.TransactionBody) *entity.CompleteCollection { 595 return &entity.CompleteCollection{ 596 Guarantee: &flow.CollectionGuarantee{ 597 CollectionID: flow.Collection{Transactions: txs}.ID(), 598 Signature: SignatureFixture(), 599 ReferenceBlockID: IdentifierFixture(), 600 SignerIndices: SignerIndicesFixture(3), 601 }, 602 Transactions: txs, 603 } 604 } 605 606 func ExecutableBlockFixture(collectionsSignerIDs [][]flow.Identifier) *entity.ExecutableBlock { 607 608 header := BlockHeaderFixture() 609 return ExecutableBlockFixtureWithParent(collectionsSignerIDs, header) 610 } 611 612 func ExecutableBlockFixtureWithParent(collectionsSignerIDs [][]flow.Identifier, parent *flow.Header) *entity.ExecutableBlock { 613 614 completeCollections := make(map[flow.Identifier]*entity.CompleteCollection, len(collectionsSignerIDs)) 615 block := BlockWithParentFixture(parent) 616 block.Payload.Guarantees = nil 617 618 for range collectionsSignerIDs { 619 completeCollection := CompleteCollectionFixture() 620 block.Payload.Guarantees = append(block.Payload.Guarantees, completeCollection.Guarantee) 621 completeCollections[completeCollection.Guarantee.CollectionID] = completeCollection 622 } 623 624 block.Header.PayloadHash = block.Payload.Hash() 625 626 executableBlock := &entity.ExecutableBlock{ 627 Block: block, 628 CompleteCollections: completeCollections, 629 } 630 return executableBlock 631 } 632 633 func ExecutableBlockFromTransactions(chain flow.ChainID, txss [][]*flow.TransactionBody) *entity.ExecutableBlock { 634 635 completeCollections := make(map[flow.Identifier]*entity.CompleteCollection, len(txss)) 636 blockHeader := BlockHeaderFixtureOnChain(chain) 637 block := *BlockWithParentFixture(blockHeader) 638 block.Payload.Guarantees = nil 639 640 for _, txs := range txss { 641 cc := CompleteCollectionFromTransactions(txs) 642 block.Payload.Guarantees = append(block.Payload.Guarantees, cc.Guarantee) 643 completeCollections[cc.Guarantee.CollectionID] = cc 644 } 645 646 block.Header.PayloadHash = block.Payload.Hash() 647 648 executableBlock := &entity.ExecutableBlock{ 649 Block: &block, 650 CompleteCollections: completeCollections, 651 } 652 // Preload the id 653 executableBlock.ID() 654 return executableBlock 655 } 656 657 func WithExecutorID(executorID flow.Identifier) func(*flow.ExecutionReceipt) { 658 return func(er *flow.ExecutionReceipt) { 659 er.ExecutorID = executorID 660 } 661 } 662 663 func WithResult(result *flow.ExecutionResult) func(*flow.ExecutionReceipt) { 664 return func(receipt *flow.ExecutionReceipt) { 665 receipt.ExecutionResult = *result 666 } 667 } 668 669 func ExecutionReceiptFixture(opts ...func(*flow.ExecutionReceipt)) *flow.ExecutionReceipt { 670 receipt := &flow.ExecutionReceipt{ 671 ExecutorID: IdentifierFixture(), 672 ExecutionResult: *ExecutionResultFixture(), 673 Spocks: nil, 674 ExecutorSignature: SignatureFixture(), 675 } 676 677 for _, apply := range opts { 678 apply(receipt) 679 } 680 681 return receipt 682 } 683 684 func ReceiptForBlockFixture(block *flow.Block) *flow.ExecutionReceipt { 685 return ReceiptForBlockExecutorFixture(block, IdentifierFixture()) 686 } 687 688 func ReceiptForBlockExecutorFixture(block *flow.Block, executor flow.Identifier) *flow.ExecutionReceipt { 689 result := ExecutionResultFixture(WithBlock(block)) 690 receipt := ExecutionReceiptFixture(WithResult(result), WithExecutorID(executor)) 691 return receipt 692 } 693 694 func ReceiptsForBlockFixture(block *flow.Block, ids []flow.Identifier) []*flow.ExecutionReceipt { 695 result := ExecutionResultFixture(WithBlock(block)) 696 var ers []*flow.ExecutionReceipt 697 for _, id := range ids { 698 ers = append(ers, ExecutionReceiptFixture(WithResult(result), WithExecutorID(id))) 699 } 700 return ers 701 } 702 703 func WithPreviousResult(prevResult flow.ExecutionResult) func(*flow.ExecutionResult) { 704 return func(result *flow.ExecutionResult) { 705 result.PreviousResultID = prevResult.ID() 706 finalState, err := prevResult.FinalStateCommitment() 707 if err != nil { 708 panic("missing final state commitment") 709 } 710 result.Chunks[0].StartState = finalState 711 } 712 } 713 714 func WithBlock(block *flow.Block) func(*flow.ExecutionResult) { 715 chunks := 1 // tailing chunk is always system chunk 716 var previousResultID flow.Identifier 717 if block.Payload != nil { 718 chunks += len(block.Payload.Guarantees) 719 } 720 blockID := block.ID() 721 722 return func(result *flow.ExecutionResult) { 723 startState := result.Chunks[0].StartState // retain previous start state in case it was user-defined 724 result.BlockID = blockID 725 result.Chunks = ChunkListFixture(uint(chunks), blockID) 726 result.Chunks[0].StartState = startState // set start state to value before update 727 result.PreviousResultID = previousResultID 728 } 729 } 730 731 func WithChunks(n uint) func(*flow.ExecutionResult) { 732 return func(result *flow.ExecutionResult) { 733 result.Chunks = ChunkListFixture(n, result.BlockID) 734 } 735 } 736 737 func ExecutionResultListFixture(n int, opts ...func(*flow.ExecutionResult)) []*flow.ExecutionResult { 738 results := make([]*flow.ExecutionResult, 0, n) 739 for i := 0; i < n; i++ { 740 results = append(results, ExecutionResultFixture(opts...)) 741 } 742 743 return results 744 } 745 746 func WithExecutionResultBlockID(blockID flow.Identifier) func(*flow.ExecutionResult) { 747 return func(result *flow.ExecutionResult) { 748 result.BlockID = blockID 749 for _, chunk := range result.Chunks { 750 chunk.BlockID = blockID 751 } 752 } 753 } 754 755 func WithServiceEvents(n int) func(result *flow.ExecutionResult) { 756 return func(result *flow.ExecutionResult) { 757 result.ServiceEvents = ServiceEventsFixture(n) 758 } 759 } 760 761 func WithExecutionDataID(id flow.Identifier) func(result *flow.ExecutionResult) { 762 return func(result *flow.ExecutionResult) { 763 result.ExecutionDataID = id 764 } 765 } 766 767 func ServiceEventsFixture(n int) flow.ServiceEventList { 768 sel := make(flow.ServiceEventList, n) 769 770 for ; n > 0; n-- { 771 switch rand.Intn(2) { 772 case 0: 773 sel[n-1] = EpochCommitFixture().ServiceEvent() 774 case 1: 775 sel[n-1] = EpochSetupFixture().ServiceEvent() 776 } 777 } 778 779 return sel 780 } 781 782 func ExecutionResultFixture(opts ...func(*flow.ExecutionResult)) *flow.ExecutionResult { 783 blockID := IdentifierFixture() 784 result := &flow.ExecutionResult{ 785 PreviousResultID: IdentifierFixture(), 786 BlockID: IdentifierFixture(), 787 Chunks: ChunkListFixture(2, blockID), 788 ExecutionDataID: IdentifierFixture(), 789 } 790 791 for _, apply := range opts { 792 apply(result) 793 } 794 795 return result 796 } 797 798 func WithApproverID(approverID flow.Identifier) func(*flow.ResultApproval) { 799 return func(ra *flow.ResultApproval) { 800 ra.Body.ApproverID = approverID 801 } 802 } 803 804 func WithAttestationBlock(block *flow.Block) func(*flow.ResultApproval) { 805 return func(ra *flow.ResultApproval) { 806 ra.Body.Attestation.BlockID = block.ID() 807 } 808 } 809 810 func WithExecutionResultID(id flow.Identifier) func(*flow.ResultApproval) { 811 return func(ra *flow.ResultApproval) { 812 ra.Body.ExecutionResultID = id 813 } 814 } 815 816 func WithBlockID(id flow.Identifier) func(*flow.ResultApproval) { 817 return func(ra *flow.ResultApproval) { 818 ra.Body.BlockID = id 819 } 820 } 821 822 func WithChunk(chunkIdx uint64) func(*flow.ResultApproval) { 823 return func(approval *flow.ResultApproval) { 824 approval.Body.ChunkIndex = chunkIdx 825 } 826 } 827 828 func ResultApprovalFixture(opts ...func(*flow.ResultApproval)) *flow.ResultApproval { 829 attestation := flow.Attestation{ 830 BlockID: IdentifierFixture(), 831 ExecutionResultID: IdentifierFixture(), 832 ChunkIndex: uint64(0), 833 } 834 835 approval := flow.ResultApproval{ 836 Body: flow.ResultApprovalBody{ 837 Attestation: attestation, 838 ApproverID: IdentifierFixture(), 839 AttestationSignature: SignatureFixture(), 840 Spock: nil, 841 }, 842 VerifierSignature: SignatureFixture(), 843 } 844 845 for _, apply := range opts { 846 apply(&approval) 847 } 848 849 return &approval 850 } 851 852 func AttestationFixture() *flow.Attestation { 853 return &flow.Attestation{ 854 BlockID: IdentifierFixture(), 855 ExecutionResultID: IdentifierFixture(), 856 ChunkIndex: uint64(0), 857 } 858 } 859 860 func StateCommitmentFixture() flow.StateCommitment { 861 var state flow.StateCommitment 862 _, _ = crand.Read(state[:]) 863 return state 864 } 865 866 func StateCommitmentPointerFixture() *flow.StateCommitment { 867 state := StateCommitmentFixture() 868 return &state 869 } 870 871 func HashFixture(size int) hash.Hash { 872 hash := make(hash.Hash, size) 873 for i := 0; i < size; i++ { 874 hash[i] = byte(i) 875 } 876 return hash 877 } 878 879 func IdentifierListFixture(n int) flow.IdentifierList { 880 list := make([]flow.Identifier, n) 881 for i := 0; i < n; i++ { 882 list[i] = IdentifierFixture() 883 } 884 return list 885 } 886 887 func IdentifierFixture() flow.Identifier { 888 var id flow.Identifier 889 _, _ = crand.Read(id[:]) 890 return id 891 } 892 893 func SignerIndicesFixture(n int) []byte { 894 indices := bitutils.MakeBitVector(10) 895 for i := 0; i < n; i++ { 896 bitutils.SetBit(indices, 1) 897 } 898 return indices 899 } 900 901 func SignerIndicesByIndices(n int, indices []int) []byte { 902 signers := bitutils.MakeBitVector(n) 903 for _, i := range indices { 904 bitutils.SetBit(signers, i) 905 } 906 return signers 907 } 908 909 // WithRole adds a role to an identity fixture. 910 func WithRole(role flow.Role) func(*flow.Identity) { 911 return func(identity *flow.Identity) { 912 identity.Role = role 913 } 914 } 915 916 // WithWeight sets the weight on an identity fixture. 917 func WithWeight(weight uint64) func(*flow.Identity) { 918 return func(identity *flow.Identity) { 919 identity.Weight = weight 920 } 921 } 922 923 func WithEjected(ejected bool) func(*flow.Identity) { 924 return func(identity *flow.Identity) { 925 identity.Ejected = ejected 926 } 927 } 928 929 // WithAddress sets the network address of identity fixture. 930 func WithAddress(address string) func(*flow.Identity) { 931 return func(identity *flow.Identity) { 932 identity.Address = address 933 } 934 } 935 936 // WithNetworkingKey sets the networking public key of identity fixture. 937 func WithNetworkingKey(key crypto.PublicKey) func(*flow.Identity) { 938 return func(identity *flow.Identity) { 939 identity.NetworkPubKey = key 940 } 941 } 942 943 func RandomBytes(n int) []byte { 944 b := make([]byte, n) 945 read, err := crand.Read(b) 946 if err != nil { 947 panic("cannot read random bytes") 948 } 949 if read != n { 950 panic(fmt.Errorf("cannot read enough random bytes (got %d of %d)", read, n)) 951 } 952 return b 953 } 954 955 func NodeConfigFixture(opts ...func(*flow.Identity)) bootstrap.NodeConfig { 956 identity := IdentityFixture(opts...) 957 return bootstrap.NodeConfig{ 958 Role: identity.Role, 959 Address: identity.Address, 960 Weight: identity.Weight, 961 } 962 } 963 964 func NodeInfoFixture(opts ...func(*flow.Identity)) bootstrap.NodeInfo { 965 opts = append(opts, WithKeys) 966 return bootstrap.NodeInfoFromIdentity(IdentityFixture(opts...)) 967 } 968 969 func NodeInfosFixture(n int, opts ...func(*flow.Identity)) []bootstrap.NodeInfo { 970 opts = append(opts, WithKeys) 971 il := IdentityListFixture(n, opts...) 972 nodeInfos := make([]bootstrap.NodeInfo, 0, n) 973 for _, identity := range il { 974 nodeInfos = append(nodeInfos, bootstrap.NodeInfoFromIdentity(identity)) 975 } 976 return nodeInfos 977 } 978 979 func PrivateNodeInfosFixture(n int, opts ...func(*flow.Identity)) []bootstrap.NodeInfo { 980 il := IdentityListFixture(n, opts...) 981 nodeInfos := make([]bootstrap.NodeInfo, 0, n) 982 for _, identity := range il { 983 nodeInfo := bootstrap.PrivateNodeInfoFromIdentity(identity, KeyFixture(crypto.ECDSAP256), KeyFixture(crypto.BLSBLS12381)) 984 nodeInfos = append(nodeInfos, nodeInfo) 985 } 986 return nodeInfos 987 } 988 989 // IdentityFixture returns a node identity. 990 func IdentityFixture(opts ...func(*flow.Identity)) *flow.Identity { 991 nodeID := IdentifierFixture() 992 stakingKey := StakingPrivKeyByIdentifier(nodeID) 993 identity := flow.Identity{ 994 NodeID: nodeID, 995 Address: fmt.Sprintf("address-%x:0", nodeID[0:7]), 996 Role: flow.RoleConsensus, 997 Weight: 1000, 998 StakingPubKey: stakingKey.PublicKey(), 999 } 1000 for _, apply := range opts { 1001 apply(&identity) 1002 } 1003 return &identity 1004 } 1005 1006 // IdentityWithNetworkingKeyFixture returns a node identity and networking private key 1007 func IdentityWithNetworkingKeyFixture(opts ...func(*flow.Identity)) (*flow.Identity, crypto.PrivateKey) { 1008 networkKey := NetworkingPrivKeyFixture() 1009 opts = append(opts, WithNetworkingKey(networkKey.PublicKey())) 1010 id := IdentityFixture(opts...) 1011 return id, networkKey 1012 } 1013 1014 func WithKeys(identity *flow.Identity) { 1015 staking := StakingPrivKeyFixture() 1016 networking := NetworkingPrivKeyFixture() 1017 identity.StakingPubKey = staking.PublicKey() 1018 identity.NetworkPubKey = networking.PublicKey() 1019 } 1020 1021 // WithNodeID adds a node ID with the given first byte to an identity. 1022 func WithNodeID(id flow.Identifier) func(*flow.Identity) { 1023 return func(identity *flow.Identity) { 1024 identity.NodeID = id 1025 } 1026 } 1027 1028 // WithStakingPubKey adds a staking public key to the identity 1029 func WithStakingPubKey(pubKey crypto.PublicKey) func(*flow.Identity) { 1030 return func(identity *flow.Identity) { 1031 identity.StakingPubKey = pubKey 1032 } 1033 } 1034 1035 // WithRandomPublicKeys adds random public keys to an identity. 1036 func WithRandomPublicKeys() func(*flow.Identity) { 1037 return func(identity *flow.Identity) { 1038 identity.StakingPubKey = KeyFixture(crypto.BLSBLS12381).PublicKey() 1039 identity.NetworkPubKey = KeyFixture(crypto.ECDSAP256).PublicKey() 1040 } 1041 } 1042 1043 // WithAllRoles can be used used to ensure an IdentityList fixtures contains 1044 // all the roles required for a valid genesis block. 1045 func WithAllRoles() func(*flow.Identity) { 1046 return WithAllRolesExcept() 1047 } 1048 1049 // Same as above, but omitting a certain role for cases where we are manually 1050 // setting up nodes or a particular role. 1051 func WithAllRolesExcept(except ...flow.Role) func(*flow.Identity) { 1052 i := 0 1053 roles := flow.Roles() 1054 1055 // remove omitted roles 1056 for _, omitRole := range except { 1057 for i, role := range roles { 1058 if role == omitRole { 1059 roles = append(roles[:i], roles[i+1:]...) 1060 } 1061 } 1062 } 1063 1064 return func(id *flow.Identity) { 1065 id.Role = roles[i%len(roles)] 1066 i++ 1067 } 1068 } 1069 1070 // CompleteIdentitySet takes a number of identities and completes the missing roles. 1071 func CompleteIdentitySet(identities ...*flow.Identity) flow.IdentityList { 1072 required := map[flow.Role]struct{}{ 1073 flow.RoleCollection: {}, 1074 flow.RoleConsensus: {}, 1075 flow.RoleExecution: {}, 1076 flow.RoleVerification: {}, 1077 } 1078 // don't add identities for roles that already exist 1079 for _, identity := range identities { 1080 delete(required, identity.Role) 1081 } 1082 // add identities for missing roles 1083 for role := range required { 1084 identities = append(identities, IdentityFixture(WithRole(role))) 1085 } 1086 return identities 1087 } 1088 1089 // IdentityListFixture returns a list of node identity objects. The identities 1090 // can be customized (ie. set their role) by passing in a function that modifies 1091 // the input identities as required. 1092 func IdentityListFixture(n int, opts ...func(*flow.Identity)) flow.IdentityList { 1093 identities := make(flow.IdentityList, 0, n) 1094 1095 for i := 0; i < n; i++ { 1096 identity := IdentityFixture() 1097 identity.Address = fmt.Sprintf("%x@flow.com:1234", identity.NodeID) 1098 for _, opt := range opts { 1099 opt(identity) 1100 } 1101 identities = append(identities, identity) 1102 } 1103 1104 return identities 1105 } 1106 1107 func WithChunkStartState(startState flow.StateCommitment) func(chunk *flow.Chunk) { 1108 return func(chunk *flow.Chunk) { 1109 chunk.StartState = startState 1110 } 1111 } 1112 1113 func ChunkFixture(blockID flow.Identifier, collectionIndex uint, opts ...func(*flow.Chunk)) *flow.Chunk { 1114 chunk := &flow.Chunk{ 1115 ChunkBody: flow.ChunkBody{ 1116 CollectionIndex: collectionIndex, 1117 StartState: StateCommitmentFixture(), 1118 EventCollection: IdentifierFixture(), 1119 TotalComputationUsed: 4200, 1120 NumberOfTransactions: 42, 1121 BlockID: blockID, 1122 }, 1123 Index: 0, 1124 EndState: StateCommitmentFixture(), 1125 } 1126 1127 for _, opt := range opts { 1128 opt(chunk) 1129 } 1130 1131 return chunk 1132 } 1133 1134 func ChunkListFixture(n uint, blockID flow.Identifier) flow.ChunkList { 1135 chunks := make([]*flow.Chunk, 0, n) 1136 for i := uint64(0); i < uint64(n); i++ { 1137 chunk := ChunkFixture(blockID, uint(i)) 1138 chunk.Index = i 1139 chunks = append(chunks, chunk) 1140 } 1141 return chunks 1142 } 1143 1144 func ChunkLocatorListFixture(n uint) chunks.LocatorList { 1145 locators := chunks.LocatorList{} 1146 resultID := IdentifierFixture() 1147 for i := uint64(0); i < uint64(n); i++ { 1148 locator := ChunkLocatorFixture(resultID, i) 1149 locators = append(locators, locator) 1150 } 1151 return locators 1152 } 1153 1154 func ChunkLocatorFixture(resultID flow.Identifier, index uint64) *chunks.Locator { 1155 return &chunks.Locator{ 1156 ResultID: resultID, 1157 Index: index, 1158 } 1159 } 1160 1161 // ChunkStatusListToChunkLocatorFixture extracts chunk locators from a list of chunk statuses. 1162 func ChunkStatusListToChunkLocatorFixture(statuses []*verification.ChunkStatus) chunks.LocatorMap { 1163 locators := chunks.LocatorMap{} 1164 for _, status := range statuses { 1165 locator := ChunkLocatorFixture(status.ExecutionResult.ID(), status.ChunkIndex) 1166 locators[locator.ID()] = locator 1167 } 1168 1169 return locators 1170 } 1171 1172 // ChunkStatusListFixture receives an execution result, samples `n` chunks out of it and 1173 // creates a chunk status for them. 1174 // It returns the list of sampled chunk statuses for the result. 1175 func ChunkStatusListFixture(t *testing.T, blockHeight uint64, result *flow.ExecutionResult, n int) verification.ChunkStatusList { 1176 statuses := verification.ChunkStatusList{} 1177 1178 // result should have enough chunk to sample 1179 require.GreaterOrEqual(t, len(result.Chunks), n) 1180 1181 chunkList := make(flow.ChunkList, n) 1182 copy(chunkList, result.Chunks) 1183 rand.Shuffle(len(chunkList), func(i, j int) { chunkList[i], chunkList[j] = chunkList[j], chunkList[i] }) 1184 1185 for _, chunk := range chunkList[:n] { 1186 status := &verification.ChunkStatus{ 1187 ChunkIndex: chunk.Index, 1188 BlockHeight: blockHeight, 1189 ExecutionResult: result, 1190 } 1191 statuses = append(statuses, status) 1192 } 1193 1194 return statuses 1195 } 1196 1197 func QCSigDataFixture() []byte { 1198 packer := hotstuff.SigDataPacker{} 1199 sigType := RandomBytes(5) 1200 for i := range sigType { 1201 sigType[i] = sigType[i] % 2 1202 } 1203 sigData := hotstuff.SignatureData{ 1204 SigType: sigType, 1205 AggregatedStakingSig: SignatureFixture(), 1206 AggregatedRandomBeaconSig: SignatureFixture(), 1207 ReconstructedRandomBeaconSig: SignatureFixture(), 1208 } 1209 encoded, _ := packer.Encode(&sigData) 1210 return encoded 1211 } 1212 1213 func SignatureFixture() crypto.Signature { 1214 sig := make([]byte, crypto.SignatureLenBLSBLS12381) 1215 _, _ = crand.Read(sig) 1216 return sig 1217 } 1218 1219 func SignaturesFixture(n int) []crypto.Signature { 1220 var sigs []crypto.Signature 1221 for i := 0; i < n; i++ { 1222 sigs = append(sigs, SignatureFixture()) 1223 } 1224 return sigs 1225 } 1226 1227 func TransactionFixture(n ...func(t *flow.Transaction)) flow.Transaction { 1228 tx := flow.Transaction{TransactionBody: TransactionBodyFixture()} 1229 if len(n) > 0 { 1230 n[0](&tx) 1231 } 1232 return tx 1233 } 1234 1235 func TransactionBodyFixture(opts ...func(*flow.TransactionBody)) flow.TransactionBody { 1236 tb := flow.TransactionBody{ 1237 Script: []byte("pub fun main() {}"), 1238 ReferenceBlockID: IdentifierFixture(), 1239 GasLimit: 10, 1240 ProposalKey: ProposalKeyFixture(), 1241 Payer: AddressFixture(), 1242 Authorizers: []flow.Address{AddressFixture()}, 1243 EnvelopeSignatures: []flow.TransactionSignature{TransactionSignatureFixture()}, 1244 } 1245 1246 for _, apply := range opts { 1247 apply(&tb) 1248 } 1249 1250 return tb 1251 } 1252 1253 func TransactionBodyListFixture(n int) []flow.TransactionBody { 1254 l := make([]flow.TransactionBody, n) 1255 for i := 0; i < n; i++ { 1256 l[i] = TransactionBodyFixture() 1257 } 1258 1259 return l 1260 } 1261 1262 func WithTransactionDSL(txDSL dsl.Transaction) func(tx *flow.TransactionBody) { 1263 return func(tx *flow.TransactionBody) { 1264 tx.Script = []byte(txDSL.ToCadence()) 1265 } 1266 } 1267 1268 func WithReferenceBlock(id flow.Identifier) func(tx *flow.TransactionBody) { 1269 return func(tx *flow.TransactionBody) { 1270 tx.ReferenceBlockID = id 1271 } 1272 } 1273 1274 func TransactionDSLFixture(chain flow.Chain) dsl.Transaction { 1275 return dsl.Transaction{ 1276 Import: dsl.Import{Address: sdk.Address(chain.ServiceAddress())}, 1277 Content: dsl.Prepare{ 1278 Content: dsl.Code(` 1279 pub fun main() {} 1280 `), 1281 }, 1282 } 1283 } 1284 1285 // VerifiableChunkDataFixture returns a complete verifiable chunk with an 1286 // execution receipt referencing the block/collections. 1287 func VerifiableChunkDataFixture(chunkIndex uint64) *verification.VerifiableChunkData { 1288 1289 guarantees := make([]*flow.CollectionGuarantee, 0) 1290 1291 var col flow.Collection 1292 1293 for i := 0; i <= int(chunkIndex); i++ { 1294 col = CollectionFixture(1) 1295 guarantee := col.Guarantee() 1296 guarantees = append(guarantees, &guarantee) 1297 } 1298 1299 payload := flow.Payload{ 1300 Guarantees: guarantees, 1301 Seals: nil, 1302 } 1303 header := BlockHeaderFixture() 1304 header.PayloadHash = payload.Hash() 1305 1306 block := flow.Block{ 1307 Header: header, 1308 Payload: &payload, 1309 } 1310 1311 chunks := make([]*flow.Chunk, 0) 1312 1313 var chunk flow.Chunk 1314 1315 for i := 0; i <= int(chunkIndex); i++ { 1316 chunk = flow.Chunk{ 1317 ChunkBody: flow.ChunkBody{ 1318 CollectionIndex: uint(i), 1319 StartState: StateCommitmentFixture(), 1320 BlockID: block.ID(), 1321 }, 1322 Index: uint64(i), 1323 } 1324 chunks = append(chunks, &chunk) 1325 } 1326 1327 result := flow.ExecutionResult{ 1328 BlockID: block.ID(), 1329 Chunks: chunks, 1330 } 1331 1332 // computes chunk end state 1333 index := chunk.Index 1334 var endState flow.StateCommitment 1335 if int(index) == len(result.Chunks)-1 { 1336 // last chunk in receipt takes final state commitment 1337 endState = StateCommitmentFixture() 1338 } else { 1339 // any chunk except last takes the subsequent chunk's start state 1340 endState = result.Chunks[index+1].StartState 1341 } 1342 1343 return &verification.VerifiableChunkData{ 1344 Chunk: &chunk, 1345 Header: block.Header, 1346 Result: &result, 1347 ChunkDataPack: ChunkDataPackFixture(result.ID()), 1348 EndState: endState, 1349 } 1350 } 1351 1352 // ChunkDataResponseMsgFixture creates a chunk data response message with a single-transaction collection, and random chunk ID. 1353 // Use options to customize the response. 1354 func ChunkDataResponseMsgFixture(chunkID flow.Identifier, opts ...func(*messages.ChunkDataResponse)) *messages.ChunkDataResponse { 1355 cdp := &messages.ChunkDataResponse{ 1356 ChunkDataPack: *ChunkDataPackFixture(chunkID), 1357 Nonce: rand.Uint64(), 1358 } 1359 1360 for _, opt := range opts { 1361 opt(cdp) 1362 } 1363 1364 return cdp 1365 } 1366 1367 // WithApproximateSize sets the ChunkDataResponse to be approximately bytes in size. 1368 func WithApproximateSize(bytes uint64) func(*messages.ChunkDataResponse) { 1369 return func(request *messages.ChunkDataResponse) { 1370 // 1 tx fixture is approximately 350 bytes 1371 txCount := bytes / 350 1372 collection := CollectionFixture(int(txCount) + 1) 1373 pack := ChunkDataPackFixture(request.ChunkDataPack.ChunkID, WithChunkDataPackCollection(&collection)) 1374 request.ChunkDataPack = *pack 1375 } 1376 } 1377 1378 // ChunkDataResponseMessageListFixture creates a list of chunk data response messages each with a single-transaction collection, and random chunk ID. 1379 func ChunkDataResponseMessageListFixture(chunkIDs flow.IdentifierList) []*messages.ChunkDataResponse { 1380 lst := make([]*messages.ChunkDataResponse, 0, len(chunkIDs)) 1381 for _, chunkID := range chunkIDs { 1382 lst = append(lst, ChunkDataResponseMsgFixture(chunkID)) 1383 } 1384 return lst 1385 } 1386 1387 // ChunkDataPackRequestListFixture creates and returns a list of chunk data pack requests fixtures. 1388 func ChunkDataPackRequestListFixture(n int, opts ...func(*verification.ChunkDataPackRequest)) verification.ChunkDataPackRequestList { 1389 lst := make([]*verification.ChunkDataPackRequest, 0, n) 1390 for i := 0; i < n; i++ { 1391 lst = append(lst, ChunkDataPackRequestFixture(opts...)) 1392 } 1393 return lst 1394 } 1395 1396 func WithHeight(height uint64) func(*verification.ChunkDataPackRequest) { 1397 return func(request *verification.ChunkDataPackRequest) { 1398 request.Height = height 1399 } 1400 } 1401 1402 func WithHeightGreaterThan(height uint64) func(*verification.ChunkDataPackRequest) { 1403 return func(request *verification.ChunkDataPackRequest) { 1404 request.Height = height + 1 1405 } 1406 } 1407 1408 func WithAgrees(list flow.IdentifierList) func(*verification.ChunkDataPackRequest) { 1409 return func(request *verification.ChunkDataPackRequest) { 1410 request.Agrees = list 1411 } 1412 } 1413 1414 func WithDisagrees(list flow.IdentifierList) func(*verification.ChunkDataPackRequest) { 1415 return func(request *verification.ChunkDataPackRequest) { 1416 request.Disagrees = list 1417 } 1418 } 1419 1420 func WithChunkID(chunkID flow.Identifier) func(*verification.ChunkDataPackRequest) { 1421 return func(request *verification.ChunkDataPackRequest) { 1422 request.ChunkID = chunkID 1423 } 1424 } 1425 1426 // ChunkDataPackRequestFixture creates a chunk data request with some default values, i.e., one agree execution node, one disagree execution node, 1427 // and height of zero. 1428 // Use options to customize the request. 1429 func ChunkDataPackRequestFixture(opts ...func(*verification.ChunkDataPackRequest)) *verification. 1430 ChunkDataPackRequest { 1431 1432 req := &verification.ChunkDataPackRequest{ 1433 Locator: chunks.Locator{ 1434 ResultID: IdentifierFixture(), 1435 Index: 0, 1436 }, 1437 ChunkDataPackRequestInfo: verification.ChunkDataPackRequestInfo{ 1438 ChunkID: IdentifierFixture(), 1439 Height: 0, 1440 Agrees: IdentifierListFixture(1), 1441 Disagrees: IdentifierListFixture(1), 1442 }, 1443 } 1444 1445 for _, opt := range opts { 1446 opt(req) 1447 } 1448 1449 // creates identity fixtures for target ids as union of agrees and disagrees 1450 // TODO: remove this inner fixture once we have filter for identifier list. 1451 targets := flow.IdentityList{} 1452 for _, id := range req.Agrees { 1453 targets = append(targets, IdentityFixture(WithNodeID(id), WithRole(flow.RoleExecution))) 1454 } 1455 for _, id := range req.Disagrees { 1456 targets = append(targets, IdentityFixture(WithNodeID(id), WithRole(flow.RoleExecution))) 1457 } 1458 1459 req.Targets = targets 1460 1461 return req 1462 } 1463 1464 func WithChunkDataPackCollection(collection *flow.Collection) func(*flow.ChunkDataPack) { 1465 return func(cdp *flow.ChunkDataPack) { 1466 cdp.Collection = collection 1467 } 1468 } 1469 1470 func WithStartState(startState flow.StateCommitment) func(*flow.ChunkDataPack) { 1471 return func(cdp *flow.ChunkDataPack) { 1472 cdp.StartState = startState 1473 } 1474 } 1475 1476 func ChunkDataPackFixture(chunkID flow.Identifier, opts ...func(*flow.ChunkDataPack)) *flow.ChunkDataPack { 1477 coll := CollectionFixture(1) 1478 cdp := &flow.ChunkDataPack{ 1479 ChunkID: chunkID, 1480 StartState: StateCommitmentFixture(), 1481 Proof: []byte{'p'}, 1482 Collection: &coll, 1483 } 1484 1485 for _, opt := range opts { 1486 opt(cdp) 1487 } 1488 1489 return cdp 1490 } 1491 1492 func ChunkDataPacksFixture(count int, opts ...func(*flow.ChunkDataPack)) []*flow.ChunkDataPack { 1493 chunkDataPacks := make([]*flow.ChunkDataPack, count) 1494 for i := 0; i < count; i++ { 1495 chunkDataPacks[i] = ChunkDataPackFixture(IdentifierFixture()) 1496 } 1497 1498 return chunkDataPacks 1499 } 1500 1501 // SeedFixture returns a random []byte with length n 1502 func SeedFixture(n int) []byte { 1503 var seed = make([]byte, n) 1504 _, _ = crand.Read(seed) 1505 return seed 1506 } 1507 1508 // SeedFixtures returns a list of m random []byte, each having length n 1509 func SeedFixtures(m int, n int) [][]byte { 1510 var seeds = make([][]byte, m, n) 1511 for i := range seeds { 1512 seeds[i] = SeedFixture(n) 1513 } 1514 return seeds 1515 } 1516 1517 // BlockEventsFixture returns a block events model populated with random events of length n. 1518 func BlockEventsFixture(header *flow.Header, n int) flow.BlockEvents { 1519 types := []flow.EventType{"A.0x1.Foo.Bar", "A.0x2.Zoo.Moo", "A.0x3.Goo.Hoo"} 1520 1521 events := make([]flow.Event, n) 1522 for i := 0; i < n; i++ { 1523 events[i] = EventFixture(types[i%len(types)], 0, uint32(i), IdentifierFixture(), 0) 1524 } 1525 1526 return flow.BlockEvents{ 1527 BlockID: header.ID(), 1528 BlockHeight: header.Height, 1529 BlockTimestamp: header.Timestamp, 1530 Events: events, 1531 } 1532 } 1533 1534 // EventFixture returns an event 1535 func EventFixture(eType flow.EventType, transactionIndex uint32, eventIndex uint32, txID flow.Identifier, _ int) flow.Event { 1536 return flow.Event{ 1537 Type: eType, 1538 TransactionIndex: transactionIndex, 1539 EventIndex: eventIndex, 1540 Payload: []byte{}, 1541 TransactionID: txID, 1542 } 1543 } 1544 1545 func EmulatorRootKey() (*flow.AccountPrivateKey, error) { 1546 1547 // TODO seems this key literal doesn't decode anymore 1548 emulatorRootKey, err := crypto.DecodePrivateKey(crypto.ECDSAP256, []byte("f87db87930770201010420ae2cc975dcbdd0ebc56f268b1d8a95834c2955970aea27042d35ec9f298b9e5aa00a06082a8648ce3d030107a1440342000417f5a527137785d2d773fee84b4c7ee40266a1dd1f36ddd46ecf25db6df6a499459629174de83256f2a44ebd4325b9def67d523b755a8926218c4efb7904f8ce0203")) 1549 if err != nil { 1550 return nil, err 1551 } 1552 1553 return &flow.AccountPrivateKey{ 1554 PrivateKey: emulatorRootKey, 1555 SignAlgo: emulatorRootKey.Algorithm(), 1556 HashAlgo: hash.SHA3_256, 1557 }, nil 1558 } 1559 1560 // NoopTxScript returns a Cadence script for a no-op transaction. 1561 func NoopTxScript() []byte { 1562 return []byte("transaction {}") 1563 } 1564 1565 func RangeFixture() chainsync.Range { 1566 return chainsync.Range{ 1567 From: rand.Uint64(), 1568 To: rand.Uint64(), 1569 } 1570 } 1571 1572 func BatchFixture() chainsync.Batch { 1573 return chainsync.Batch{ 1574 BlockIDs: IdentifierListFixture(10), 1575 } 1576 } 1577 1578 func RangeListFixture(n int) []chainsync.Range { 1579 if n <= 0 { 1580 return nil 1581 } 1582 ranges := make([]chainsync.Range, n) 1583 for i := range ranges { 1584 ranges[i] = RangeFixture() 1585 } 1586 return ranges 1587 } 1588 1589 func BatchListFixture(n int) []chainsync.Batch { 1590 if n <= 0 { 1591 return nil 1592 } 1593 batches := make([]chainsync.Batch, n) 1594 for i := range batches { 1595 batches[i] = BatchFixture() 1596 } 1597 return batches 1598 } 1599 1600 func BootstrapExecutionResultFixture(block *flow.Block, commit flow.StateCommitment) *flow.ExecutionResult { 1601 result := &flow.ExecutionResult{ 1602 BlockID: block.ID(), 1603 PreviousResultID: flow.ZeroID, 1604 Chunks: chunks.ChunkListFromCommit(commit), 1605 } 1606 return result 1607 } 1608 1609 func KeyFixture(algo crypto.SigningAlgorithm) crypto.PrivateKey { 1610 key, err := crypto.GeneratePrivateKey(algo, SeedFixture(128)) 1611 if err != nil { 1612 panic(err) 1613 } 1614 return key 1615 } 1616 1617 func KeysFixture(n int, algo crypto.SigningAlgorithm) []crypto.PrivateKey { 1618 keys := make([]crypto.PrivateKey, 0, n) 1619 for i := 0; i < n; i++ { 1620 keys = append(keys, KeyFixture(algo)) 1621 } 1622 return keys 1623 } 1624 1625 func PublicKeysFixture(n int, algo crypto.SigningAlgorithm) []crypto.PublicKey { 1626 pks := make([]crypto.PublicKey, 0, n) 1627 sks := KeysFixture(n, algo) 1628 for _, sk := range sks { 1629 pks = append(pks, sk.PublicKey()) 1630 } 1631 return pks 1632 } 1633 1634 func QuorumCertificateWithSignerIDsFixture(opts ...func(*flow.QuorumCertificateWithSignerIDs)) *flow.QuorumCertificateWithSignerIDs { 1635 qc := flow.QuorumCertificateWithSignerIDs{ 1636 View: uint64(rand.Uint32()), 1637 BlockID: IdentifierFixture(), 1638 SignerIDs: IdentifierListFixture(3), 1639 SigData: QCSigDataFixture(), 1640 } 1641 for _, apply := range opts { 1642 apply(&qc) 1643 } 1644 return &qc 1645 } 1646 1647 func QuorumCertificatesWithSignerIDsFixtures(n uint, opts ...func(*flow.QuorumCertificateWithSignerIDs)) []*flow.QuorumCertificateWithSignerIDs { 1648 qcs := make([]*flow.QuorumCertificateWithSignerIDs, 0, n) 1649 for i := 0; i < int(n); i++ { 1650 qcs = append(qcs, QuorumCertificateWithSignerIDsFixture(opts...)) 1651 } 1652 return qcs 1653 } 1654 1655 func QuorumCertificatesFromAssignments(assignment flow.AssignmentList) []*flow.QuorumCertificateWithSignerIDs { 1656 qcs := make([]*flow.QuorumCertificateWithSignerIDs, 0, len(assignment)) 1657 for _, nodes := range assignment { 1658 qc := QuorumCertificateWithSignerIDsFixture() 1659 qc.SignerIDs = nodes 1660 qcs = append(qcs, qc) 1661 } 1662 return qcs 1663 } 1664 1665 func QuorumCertificateFixture(opts ...func(*flow.QuorumCertificate)) *flow.QuorumCertificate { 1666 qc := flow.QuorumCertificate{ 1667 View: uint64(rand.Uint32()), 1668 BlockID: IdentifierFixture(), 1669 SignerIndices: SignerIndicesFixture(3), 1670 SigData: QCSigDataFixture(), 1671 } 1672 for _, apply := range opts { 1673 apply(&qc) 1674 } 1675 return &qc 1676 } 1677 1678 func QuorumCertificatesFixtures(n uint, opts ...func(*flow.QuorumCertificate)) []*flow.QuorumCertificate { 1679 qcs := make([]*flow.QuorumCertificate, 0, n) 1680 for i := 0; i < int(n); i++ { 1681 qcs = append(qcs, QuorumCertificateFixture(opts...)) 1682 } 1683 return qcs 1684 } 1685 1686 func QCWithBlockID(blockID flow.Identifier) func(*flow.QuorumCertificate) { 1687 return func(qc *flow.QuorumCertificate) { 1688 qc.BlockID = blockID 1689 } 1690 } 1691 1692 func QCWithSignerIndices(signerIndices []byte) func(*flow.QuorumCertificate) { 1693 return func(qc *flow.QuorumCertificate) { 1694 qc.SignerIndices = signerIndices 1695 } 1696 } 1697 1698 func VoteFixture(opts ...func(vote *hotstuff.Vote)) *hotstuff.Vote { 1699 vote := &hotstuff.Vote{ 1700 View: uint64(rand.Uint32()), 1701 BlockID: IdentifierFixture(), 1702 SignerID: IdentifierFixture(), 1703 SigData: RandomBytes(128), 1704 } 1705 1706 for _, opt := range opts { 1707 opt(vote) 1708 } 1709 1710 return vote 1711 } 1712 1713 func WithVoteSignerID(signerID flow.Identifier) func(*hotstuff.Vote) { 1714 return func(vote *hotstuff.Vote) { 1715 vote.SignerID = signerID 1716 } 1717 } 1718 1719 func WithVoteView(view uint64) func(*hotstuff.Vote) { 1720 return func(vote *hotstuff.Vote) { 1721 vote.View = view 1722 } 1723 } 1724 1725 func WithVoteBlockID(blockID flow.Identifier) func(*hotstuff.Vote) { 1726 return func(vote *hotstuff.Vote) { 1727 vote.BlockID = blockID 1728 } 1729 } 1730 1731 func VoteForBlockFixture(block *hotstuff.Block, opts ...func(vote *hotstuff.Vote)) *hotstuff.Vote { 1732 vote := VoteFixture(WithVoteView(block.View), 1733 WithVoteBlockID(block.BlockID)) 1734 1735 for _, opt := range opts { 1736 opt(vote) 1737 } 1738 1739 return vote 1740 } 1741 1742 func VoteWithStakingSig() func(*hotstuff.Vote) { 1743 return func(vote *hotstuff.Vote) { 1744 vote.SigData = append([]byte{byte(encoding.SigTypeStaking)}, vote.SigData...) 1745 } 1746 } 1747 1748 func VoteWithBeaconSig() func(*hotstuff.Vote) { 1749 return func(vote *hotstuff.Vote) { 1750 vote.SigData = append([]byte{byte(encoding.SigTypeRandomBeacon)}, vote.SigData...) 1751 } 1752 } 1753 1754 func WithParticipants(participants flow.IdentityList) func(*flow.EpochSetup) { 1755 return func(setup *flow.EpochSetup) { 1756 setup.Participants = participants.Sort(order.Canonical) 1757 setup.Assignments = ClusterAssignment(1, participants) 1758 } 1759 } 1760 1761 func SetupWithCounter(counter uint64) func(*flow.EpochSetup) { 1762 return func(setup *flow.EpochSetup) { 1763 setup.Counter = counter 1764 } 1765 } 1766 1767 func WithFinalView(view uint64) func(*flow.EpochSetup) { 1768 return func(setup *flow.EpochSetup) { 1769 setup.FinalView = view 1770 } 1771 } 1772 1773 func WithFirstView(view uint64) func(*flow.EpochSetup) { 1774 return func(setup *flow.EpochSetup) { 1775 setup.FirstView = view 1776 } 1777 } 1778 1779 // EpochSetupFixture creates a valid EpochSetup with default properties for 1780 // testing. The default properties can be overwritten with optional parameter 1781 // functions. 1782 func EpochSetupFixture(opts ...func(setup *flow.EpochSetup)) *flow.EpochSetup { 1783 participants := IdentityListFixture(5, WithAllRoles()) 1784 setup := &flow.EpochSetup{ 1785 Counter: uint64(rand.Uint32()), 1786 FirstView: uint64(0), 1787 FinalView: uint64(rand.Uint32() + 1000), 1788 Participants: participants.Sort(order.Canonical), 1789 RandomSource: SeedFixture(flow.EpochSetupRandomSourceLength), 1790 DKGPhase1FinalView: 100, 1791 DKGPhase2FinalView: 200, 1792 DKGPhase3FinalView: 300, 1793 } 1794 for _, apply := range opts { 1795 apply(setup) 1796 } 1797 if setup.Assignments == nil { 1798 setup.Assignments = ClusterAssignment(1, setup.Participants) 1799 } 1800 return setup 1801 } 1802 1803 func EpochStatusFixture() *flow.EpochStatus { 1804 return &flow.EpochStatus{ 1805 PreviousEpoch: flow.EventIDs{ 1806 SetupID: IdentifierFixture(), 1807 CommitID: IdentifierFixture(), 1808 }, 1809 CurrentEpoch: flow.EventIDs{ 1810 SetupID: IdentifierFixture(), 1811 CommitID: IdentifierFixture(), 1812 }, 1813 NextEpoch: flow.EventIDs{ 1814 SetupID: IdentifierFixture(), 1815 CommitID: IdentifierFixture(), 1816 }, 1817 } 1818 } 1819 1820 func IndexFixture() *flow.Index { 1821 return &flow.Index{ 1822 CollectionIDs: IdentifierListFixture(5), 1823 SealIDs: IdentifierListFixture(5), 1824 ReceiptIDs: IdentifierListFixture(5), 1825 } 1826 } 1827 1828 func WithDKGFromParticipants(participants flow.IdentityList) func(*flow.EpochCommit) { 1829 count := len(participants.Filter(filter.IsValidDKGParticipant)) 1830 return func(commit *flow.EpochCommit) { 1831 commit.DKGParticipantKeys = PublicKeysFixture(count, crypto.BLSBLS12381) 1832 } 1833 } 1834 1835 func WithClusterQCsFromAssignments(assignments flow.AssignmentList) func(*flow.EpochCommit) { 1836 qcs := make([]*flow.QuorumCertificateWithSignerIDs, 0, len(assignments)) 1837 for _, assignment := range assignments { 1838 qcWithSignerIndex := QuorumCertificateWithSignerIDsFixture() 1839 qcWithSignerIndex.SignerIDs = assignment 1840 qcs = append(qcs, qcWithSignerIndex) 1841 } 1842 return func(commit *flow.EpochCommit) { 1843 commit.ClusterQCs = flow.ClusterQCVoteDatasFromQCs(qcs) 1844 } 1845 } 1846 1847 func DKGParticipantLookup(participants flow.IdentityList) map[flow.Identifier]flow.DKGParticipant { 1848 lookup := make(map[flow.Identifier]flow.DKGParticipant) 1849 for i, node := range participants.Filter(filter.HasRole(flow.RoleConsensus)) { 1850 lookup[node.NodeID] = flow.DKGParticipant{ 1851 Index: uint(i), 1852 KeyShare: KeyFixture(crypto.BLSBLS12381).PublicKey(), 1853 } 1854 } 1855 return lookup 1856 } 1857 1858 func CommitWithCounter(counter uint64) func(*flow.EpochCommit) { 1859 return func(commit *flow.EpochCommit) { 1860 commit.Counter = counter 1861 } 1862 } 1863 1864 func EpochCommitFixture(opts ...func(*flow.EpochCommit)) *flow.EpochCommit { 1865 commit := &flow.EpochCommit{ 1866 Counter: uint64(rand.Uint32()), 1867 ClusterQCs: flow.ClusterQCVoteDatasFromQCs(QuorumCertificatesWithSignerIDsFixtures(1)), 1868 DKGGroupKey: KeyFixture(crypto.BLSBLS12381).PublicKey(), 1869 DKGParticipantKeys: PublicKeysFixture(2, crypto.BLSBLS12381), 1870 } 1871 for _, apply := range opts { 1872 apply(commit) 1873 } 1874 return commit 1875 } 1876 1877 // BootstrapFixture generates all the artifacts necessary to bootstrap the 1878 // protocol state. 1879 func BootstrapFixture(participants flow.IdentityList, opts ...func(*flow.Block)) (*flow.Block, *flow.ExecutionResult, *flow.Seal) { 1880 1881 root := GenesisFixture() 1882 for _, apply := range opts { 1883 apply(root) 1884 } 1885 1886 counter := uint64(1) 1887 setup := EpochSetupFixture( 1888 WithParticipants(participants), 1889 SetupWithCounter(counter), 1890 WithFirstView(root.Header.View), 1891 WithFinalView(root.Header.View+1000), 1892 ) 1893 commit := EpochCommitFixture( 1894 CommitWithCounter(counter), 1895 WithClusterQCsFromAssignments(setup.Assignments), 1896 WithDKGFromParticipants(participants), 1897 ) 1898 1899 result := BootstrapExecutionResultFixture(root, GenesisStateCommitment) 1900 result.ServiceEvents = []flow.ServiceEvent{setup.ServiceEvent(), commit.ServiceEvent()} 1901 1902 seal := Seal.Fixture(Seal.WithResult(result)) 1903 1904 return root, result, seal 1905 } 1906 1907 // RootSnapshotFixture returns a snapshot representing a root chain state, for 1908 // example one as returned from BootstrapFixture. 1909 func RootSnapshotFixture(participants flow.IdentityList, opts ...func(*flow.Block)) *inmem.Snapshot { 1910 block, result, seal := BootstrapFixture(participants.Sort(order.Canonical), opts...) 1911 qc := QuorumCertificateFixture(QCWithBlockID(block.ID())) 1912 root, err := inmem.SnapshotFromBootstrapState(block, result, seal, qc) 1913 if err != nil { 1914 panic(err) 1915 } 1916 return root 1917 } 1918 1919 func SnapshotClusterByIndex(snapshot *inmem.Snapshot, clusterIndex uint) (protocol.Cluster, error) { 1920 epochs := snapshot.Epochs() 1921 epoch := epochs.Current() 1922 cluster, err := epoch.Cluster(clusterIndex) 1923 if err != nil { 1924 return nil, err 1925 } 1926 return cluster, nil 1927 } 1928 1929 // ChainFixture creates a list of blocks that forms a chain 1930 func ChainFixture(nonGenesisCount int) ([]*flow.Block, *flow.ExecutionResult, *flow.Seal) { 1931 chain := make([]*flow.Block, 0, nonGenesisCount+1) 1932 1933 participants := IdentityListFixture(5, WithAllRoles()) 1934 genesis, result, seal := BootstrapFixture(participants) 1935 chain = append(chain, genesis) 1936 1937 children := ChainFixtureFrom(nonGenesisCount, genesis.Header) 1938 chain = append(chain, children...) 1939 return chain, result, seal 1940 } 1941 1942 // ChainFixtureFrom creates a chain of blocks starting from a given parent block, 1943 // the total number of blocks in the chain is specified by the given count 1944 func ChainFixtureFrom(count int, parent *flow.Header) []*flow.Block { 1945 blocks := make([]*flow.Block, 0, count) 1946 1947 for i := 0; i < count; i++ { 1948 block := BlockWithParentFixture(parent) 1949 blocks = append(blocks, block) 1950 parent = block.Header 1951 } 1952 1953 return blocks 1954 } 1955 1956 func ReceiptChainFor(blocks []*flow.Block, result0 *flow.ExecutionResult) []*flow.ExecutionReceipt { 1957 receipts := make([]*flow.ExecutionReceipt, len(blocks)) 1958 receipts[0] = ExecutionReceiptFixture(WithResult(result0)) 1959 receipts[0].ExecutionResult.BlockID = blocks[0].ID() 1960 1961 for i := 1; i < len(blocks); i++ { 1962 b := blocks[i] 1963 prevReceipt := receipts[i-1] 1964 receipt := ReceiptForBlockFixture(b) 1965 receipt.ExecutionResult.PreviousResultID = prevReceipt.ExecutionResult.ID() 1966 prevLastChunk := prevReceipt.ExecutionResult.Chunks[len(prevReceipt.ExecutionResult.Chunks)-1] 1967 receipt.ExecutionResult.Chunks[0].StartState = prevLastChunk.EndState 1968 receipts[i] = receipt 1969 } 1970 1971 return receipts 1972 } 1973 1974 // ReconnectBlocksAndReceipts re-computes each block's PayloadHash and ParentID 1975 // so that all the blocks are connected. 1976 // blocks' height have to be in strict increasing order. 1977 func ReconnectBlocksAndReceipts(blocks []*flow.Block, receipts []*flow.ExecutionReceipt) { 1978 for i := 1; i < len(blocks); i++ { 1979 b := blocks[i] 1980 p := i - 1 1981 prev := blocks[p] 1982 if prev.Header.Height+1 != b.Header.Height { 1983 panic(fmt.Sprintf("height has gap when connecting blocks: expect %v, but got %v", prev.Header.Height+1, b.Header.Height)) 1984 } 1985 b.Header.ParentID = prev.ID() 1986 b.Header.PayloadHash = b.Payload.Hash() 1987 receipts[i].ExecutionResult.BlockID = b.ID() 1988 prevReceipt := receipts[p] 1989 receipts[i].ExecutionResult.PreviousResultID = prevReceipt.ExecutionResult.ID() 1990 for _, c := range receipts[i].ExecutionResult.Chunks { 1991 c.BlockID = b.ID() 1992 } 1993 } 1994 1995 // after changing results we need to update IDs of results in receipt 1996 for _, block := range blocks { 1997 if len(block.Payload.Results) > 0 { 1998 for i := range block.Payload.Receipts { 1999 block.Payload.Receipts[i].ResultID = block.Payload.Results[i].ID() 2000 } 2001 } 2002 } 2003 } 2004 2005 // DKGMessageFixture creates a single DKG message with random fields 2006 func DKGMessageFixture() *messages.DKGMessage { 2007 return &messages.DKGMessage{ 2008 Data: RandomBytes(10), 2009 DKGInstanceID: fmt.Sprintf("test-dkg-instance-%d", uint64(rand.Int())), 2010 } 2011 } 2012 2013 // DKGBroadcastMessageFixture creates a single DKG broadcast message with random fields 2014 func DKGBroadcastMessageFixture() *messages.BroadcastDKGMessage { 2015 return &messages.BroadcastDKGMessage{ 2016 DKGMessage: *DKGMessageFixture(), 2017 CommitteeMemberIndex: uint64(rand.Int()), 2018 NodeID: IdentifierFixture(), 2019 Signature: SignatureFixture(), 2020 } 2021 } 2022 2023 // PrivateKeyFixture returns a random private key with specified signature algorithm and seed length 2024 func PrivateKeyFixture(algo crypto.SigningAlgorithm, seedLength int) crypto.PrivateKey { 2025 sk, err := crypto.GeneratePrivateKey(algo, SeedFixture(seedLength)) 2026 if err != nil { 2027 panic(err) 2028 } 2029 return sk 2030 } 2031 2032 // PrivateKeyFixtureByIdentifier returns a private key for a given node. 2033 // given the same identifier, it will always return the same private key 2034 func PrivateKeyFixtureByIdentifier(algo crypto.SigningAlgorithm, seedLength int, id flow.Identifier) crypto.PrivateKey { 2035 seed := append(id[:], id[:]...) 2036 sk, err := crypto.GeneratePrivateKey(algo, seed[:seedLength]) 2037 if err != nil { 2038 panic(err) 2039 } 2040 return sk 2041 } 2042 2043 func StakingPrivKeyByIdentifier(id flow.Identifier) crypto.PrivateKey { 2044 return PrivateKeyFixtureByIdentifier(crypto.BLSBLS12381, crypto.KeyGenSeedMinLenBLSBLS12381, id) 2045 } 2046 2047 // NetworkingPrivKeyFixture returns random ECDSAP256 private key 2048 func NetworkingPrivKeyFixture() crypto.PrivateKey { 2049 return PrivateKeyFixture(crypto.ECDSAP256, crypto.KeyGenSeedMinLenECDSAP256) 2050 } 2051 2052 // StakingPrivKeyFixture returns a random BLS12381 private keyf 2053 func StakingPrivKeyFixture() crypto.PrivateKey { 2054 return PrivateKeyFixture(crypto.BLSBLS12381, crypto.KeyGenSeedMinLenBLSBLS12381) 2055 } 2056 2057 func NodeMachineAccountInfoFixture() bootstrap.NodeMachineAccountInfo { 2058 return bootstrap.NodeMachineAccountInfo{ 2059 Address: RandomAddressFixture().String(), 2060 EncodedPrivateKey: PrivateKeyFixture(crypto.ECDSAP256, DefaultSeedFixtureLength).Encode(), 2061 HashAlgorithm: bootstrap.DefaultMachineAccountHashAlgo, 2062 SigningAlgorithm: bootstrap.DefaultMachineAccountSignAlgo, 2063 KeyIndex: bootstrap.DefaultMachineAccountKeyIndex, 2064 } 2065 } 2066 2067 func MachineAccountFixture(t *testing.T) (bootstrap.NodeMachineAccountInfo, *sdk.Account) { 2068 info := NodeMachineAccountInfoFixture() 2069 2070 bal, err := cadence.NewUFix64("0.5") 2071 require.NoError(t, err) 2072 2073 acct := &sdk.Account{ 2074 Address: sdk.HexToAddress(info.Address), 2075 Balance: uint64(bal), 2076 Keys: []*sdk.AccountKey{ 2077 { 2078 Index: int(info.KeyIndex), 2079 PublicKey: info.MustPrivateKey().PublicKey(), 2080 SigAlgo: info.SigningAlgorithm, 2081 HashAlgo: info.HashAlgorithm, 2082 Weight: 1000, 2083 }, 2084 }, 2085 } 2086 return info, acct 2087 } 2088 2089 func TransactionResultsFixture(n int) []flow.TransactionResult { 2090 results := make([]flow.TransactionResult, 0, n) 2091 for i := 0; i < n; i++ { 2092 results = append(results, flow.TransactionResult{ 2093 TransactionID: IdentifierFixture(), 2094 ErrorMessage: "whatever", 2095 ComputationUsed: uint64(rand.Uint32()), 2096 }) 2097 } 2098 return results 2099 } 2100 2101 func AllowAllPeerFilter() func(peer.ID) error { 2102 return func(_ peer.ID) error { 2103 return nil 2104 } 2105 } 2106 2107 func NewSealingConfigs(val uint) module.SealingConfigsSetter { 2108 instance, err := updatable_configs.NewSealingConfigs( 2109 flow.DefaultRequiredApprovalsForSealConstruction, 2110 flow.DefaultRequiredApprovalsForSealValidation, 2111 flow.DefaultChunkAssignmentAlpha, 2112 flow.DefaultEmergencySealingActive, 2113 ) 2114 if err != nil { 2115 panic(err) 2116 } 2117 err = instance.SetRequiredApprovalsForSealingConstruction(val) 2118 if err != nil { 2119 panic(err) 2120 } 2121 return instance 2122 } 2123 2124 func PeerIDFromFlowID(identity *flow.Identity) (peer.ID, error) { 2125 networkKey := identity.NetworkPubKey 2126 peerPK, err := keyutils.LibP2PPublicKeyFromFlow(networkKey) 2127 if err != nil { 2128 return "", err 2129 } 2130 2131 peerID, err := peer.IDFromPublicKey(peerPK) 2132 if err != nil { 2133 return "", err 2134 } 2135 2136 return peerID, nil 2137 } 2138 2139 func EngineMessageFixture() *engine.Message { 2140 return &engine.Message{ 2141 OriginID: IdentifierFixture(), 2142 Payload: RandomBytes(10), 2143 } 2144 } 2145 2146 func EngineMessageFixtures(count int) []*engine.Message { 2147 messages := make([]*engine.Message, 0, count) 2148 for i := 0; i < count; i++ { 2149 messages = append(messages, EngineMessageFixture()) 2150 } 2151 return messages 2152 } 2153 2154 // GetFlowProtocolEventID returns the event ID for the event provided. 2155 func GetFlowProtocolEventID(t *testing.T, channel channels.Channel, event interface{}) flow.Identifier { 2156 payload, err := NetworkCodec().Encode(event) 2157 require.NoError(t, err) 2158 eventIDHash, err := network.EventId(channel, payload) 2159 require.NoError(t, err) 2160 return flow.HashToID(eventIDHash) 2161 }