diff --git a/contracts/FlowtyRaffles.cdc b/contracts/FlowtyRaffles.cdc index a94dbc3..3cc978c 100644 --- a/contracts/FlowtyRaffles.cdc +++ b/contracts/FlowtyRaffles.cdc @@ -1,6 +1,6 @@ import "MetadataViews" import "RandomBeaconHistory" -// import "Xorshift128plus" +import "Xorshift128plus" pub contract FlowtyRaffles { pub let ManagerStoragePath: StoragePath @@ -343,22 +343,20 @@ pub contract FlowtyRaffles { // taken from // https://github.com/onflow/random-coin-toss/blob/4271cd571b7761af36b0f1037767171aeca18387/contracts/CoinToss.cdc#L95 pub fun randUInt64(atBlockHeight: UInt64, salt: UInt64): UInt64 { - // // query the Random Beacon history core-contract - if `blockHeight` <= current block height, panic & revert - // let sourceOfRandomness = RandomBeaconHistory.sourceOfRandomness(atBlockHeight: atBlockHeight) - // assert(sourceOfRandomness.blockHeight == atBlockHeight, message: "RandomSource block height mismatch") - - // // instantiate a PRG object, seeding a source of randomness with `salt` and returns a pseudo-random - // // generator object. - // let prg = Xorshift128plus.PRG( - // sourceOfRandomness: sourceOfRandomness.value, - // salt: salt.toBigEndianBytes() - // ) - - // return prg.nextUInt64() - // TODO: use commented-out implementation once we can test using the randomness beacon in the cadence testing framework - return revertibleRandom() + // query the Random Beacon history core-contract - if `blockHeight` <= current block height, panic & revert + let sourceOfRandomness = RandomBeaconHistory.sourceOfRandomnessAtBlockHeight(blockHeight: atBlockHeight) + assert(sourceOfRandomness.blockHeight == atBlockHeight, message: "RandomSource block height mismatch") + + // instantiate a PRG object, seeding a source of randomness with `salt` and returns a pseudo-random + // generator object. + let prg = Xorshift128plus.PRG( + sourceOfRandomness: sourceOfRandomness.value, + salt: salt.toBigEndianBytes() + ) + + return prg.nextUInt64() } - + pub fun extractString(_ value: AnyStruct?): String? { if value == nil { return nil diff --git a/contracts/standard/RandomBeaconHistory.cdc b/contracts/standard/RandomBeaconHistory.cdc index 28d20ab..de2d272 100644 --- a/contracts/standard/RandomBeaconHistory.cdc +++ b/contracts/standard/RandomBeaconHistory.cdc @@ -85,22 +85,22 @@ access(all) contract RandomBeaconHistory { /// precedes or exceeds the recorded history. Note that a source of randomness for block n will not be accessible /// until block n+1. /// - /// @param atBlockHeight The block height at which to retrieve the source of randomness + /// @param blockHeight The block height at which to retrieve the source of randomness /// /// @return The source of randomness at the given block height as RandomSource struct /// - access(all) fun sourceOfRandomness(atBlockHeight: UInt64): RandomSource { + access(all) fun sourceOfRandomnessAtBlockHeight(blockHeight: UInt64): RandomSource { pre { self.lowestHeight != nil: "History has not yet been initialized" - atBlockHeight >= self.lowestHeight!: "Requested block height precedes recorded history" - atBlockHeight < getCurrentBlock().height: "Source of randomness not yet recorded" + blockHeight >= self.lowestHeight!: "Requested block height precedes recorded history" + blockHeight < getCurrentBlock().height: "Source of randomness not yet recorded" } - let index: UInt64 = atBlockHeight - self.lowestHeight! + let index = blockHeight - self.lowestHeight! assert( index >= 0 && index < UInt64(self.randomSourceHistory.length), message: "Problem finding random source history index" ) - return RandomSource(blockHeight: atBlockHeight, value: self.randomSourceHistory[index]) + return RandomSource(blockHeight: blockHeight, value: self.randomSourceHistory[index]) } /// Retrieves a page from the history of random sources, ordered chronologically @@ -111,7 +111,7 @@ access(all) contract RandomBeaconHistory { /// @return A RandomSourceHistoryPage containing RandomSource values in choronological order according to /// associated block height /// - access(all) view fun getRandomSourceHistoryPage(page: UInt64, perPage: UInt64): RandomSourceHistoryPage { + access(all) view fun getRandomSourceHistoryPage(_ page: UInt64, perPage: UInt64): RandomSourceHistoryPage { pre { self.lowestHeight != nil: "History has not yet been initialized" } @@ -132,10 +132,11 @@ access(all) contract RandomBeaconHistory { } // Iterate over history and construct page RandomSource values + let lowestHeight = self.lowestHeight! for i, block in self.randomSourceHistory.slice(from: Int(startIndex), upTo: Int(endIndex)) { values.append( RandomSource( - blockHeight: self.lowestHeight! + startIndex + UInt64(i), + blockHeight: lowestHeight + startIndex + UInt64(i), value: self.randomSourceHistory[startIndex + UInt64(i)] ) ) diff --git a/test/FlowtyRaffles_tests.cdc b/test/FlowtyRaffles_tests.cdc index d743019..79962ec 100644 --- a/test/FlowtyRaffles_tests.cdc +++ b/test/FlowtyRaffles_tests.cdc @@ -12,14 +12,15 @@ pub let Xorshift128plusContractAddress = Address(0x0000000000000008) pub let GenericRaffleSourceIdentifier = "A.0000000000000008.FlowtyRaffleSource.AnyStructRaffleSource" pub fun setup() { - var err = Test.deployContract(name: "FlowtyRaffles", path: "../contracts/FlowtyRaffles.cdc", arguments: []) + var err = Test.deployContract(name: "Xorshift128plus", path: "../contracts/standard/Xorshift128plus.cdc", arguments: []) + Test.expect(err, Test.beNil()) + + err = Test.deployContract(name: "FlowtyRaffles", path: "../contracts/FlowtyRaffles.cdc", arguments: []) Test.expect(err, Test.beNil()) err = Test.deployContract(name: "FlowtyRaffleSource", path: "../contracts/FlowtyRaffleSource.cdc", arguments: []) Test.expect(err, Test.beNil()) - // err = Test.deployContract(name: "Xorshift128plus", path: "../contracts/standard/Xorshift128plus.cdc", arguments: []) - // Test.expect(err, Test.beNil()) } pub fun testSetupManager() {