11
.gitignore
vendored
11
.gitignore
vendored
@@ -132,6 +132,11 @@ src/cc/rogue/rogue
|
||||
src/cc/rogue/rogue.so
|
||||
|
||||
src/cc/rogue/test.zip
|
||||
src/checkfile
|
||||
|
||||
src/foo.zip
|
||||
|
||||
src/log
|
||||
|
||||
src/rogue.530623577502174316.0
|
||||
|
||||
@@ -139,11 +144,6 @@ src/rogue.530623577502174316.pack
|
||||
|
||||
src/rogue.530623577502174316.player
|
||||
|
||||
src/checkfile
|
||||
|
||||
src/log
|
||||
|
||||
src/foo.zip
|
||||
|
||||
src/cc/rogue/config.h
|
||||
|
||||
@@ -154,3 +154,4 @@ src/ROGUE.conf
|
||||
src/rogue.scr
|
||||
|
||||
src/cc/rogue/confdefs.h
|
||||
src/cc/rogue/x64
|
||||
|
||||
@@ -71,6 +71,10 @@ build:windows:
|
||||
- cp src/komodod.exe
|
||||
src/komodo-cli.exe
|
||||
src/komodo-tx.exe
|
||||
src/cc/rogue/rogue.exe
|
||||
zcutil/fetch-params.bat
|
||||
src/cc/rogue/x86_64-w64-mingw32/bin/libcurl-4.dll
|
||||
src/cc/rogue/x86_64-w64-mingw32/bin/libncursesw6.dll
|
||||
${PACKAGE_DIR_WINDOWS}
|
||||
- zip -r ${PACKAGE_DIR_WINDOWS}.zip ${PACKAGE_DIR_WINDOWS}
|
||||
- md5sum ${AGAMA_ARTIFACTS_WINDOWS} > ${AGAMA_ARTIFACTS_WINDOWS_CHECKSUM}
|
||||
@@ -91,6 +95,7 @@ build:macos:
|
||||
key: "${CI_JOB_NAME}${CI_COMMIT_REF_NAME}"
|
||||
paths:
|
||||
- depends/built
|
||||
allow_failure: true
|
||||
script:
|
||||
- zcutil/build-mac.sh -j$(sysctl -n hw.physicalcpu)
|
||||
- ./makeRelease.sh ${PACKAGE_DIR_MACOS}
|
||||
|
||||
22
README.md
22
README.md
@@ -71,16 +71,32 @@ cd komodo
|
||||
#This can take some time.
|
||||
```
|
||||
|
||||
|
||||
#### OSX
|
||||
Ensure you have [brew](https://brew.sh) and the command line tools installed (comes automatically with XCode) and run:
|
||||
Ensure you have [brew](https://brew.sh) and Command Line Tools installed.
|
||||
```shell
|
||||
brew update && brew install gcc@6
|
||||
# Install brew
|
||||
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
|
||||
# Install Xcode, opens a pop-up window to install CLT without installing the entire Xcode package
|
||||
xcode-select --install
|
||||
# Update brew and install dependencies
|
||||
brew update
|
||||
brew upgrade
|
||||
brew tap discoteq/discoteq; brew install flock
|
||||
brew install autoconf autogen automake
|
||||
brew install gcc@6
|
||||
brew install binutils
|
||||
brew install protobuf
|
||||
brew install coreutils
|
||||
brew install wget
|
||||
# Clone the Komodo repo
|
||||
git clone https://github.com/komodoplatform/komodo --branch master --single-branch
|
||||
# Change master branch to other branch you wish to compile
|
||||
cd komodo
|
||||
./zcutil/fetch-params.sh
|
||||
# -j8 = using 8 threads for the compilation - replace 8 with number of threads you want to use
|
||||
./zcutil/build-mac.sh -j8
|
||||
#This can take some time.
|
||||
# This can take some time.
|
||||
```
|
||||
|
||||
#### Windows
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package=boost
|
||||
|
||||
$(package)_version=1_66_0
|
||||
$(package)_download_path=https://dl.bintray.com/boostorg/release/1.66.0/source
|
||||
$(package)_file_name=$(package)_$($(package)_version).tar.bz2
|
||||
$(package)_sha256_hash=5721818253e6a0989583192f96782c4a98eb6204965316df9f5ad75819225ca9
|
||||
$(package)_file_name=$(package)_$($(package)_version).tar.bz2
|
||||
|
||||
define $(package)_set_vars
|
||||
$(package)_config_opts_release=variant=release
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
ifeq ($(host_os),mingw32)
|
||||
$(package)_version=4.2.2-1
|
||||
$(package)_version=4.3.1
|
||||
$(package)_download_path=https://github.com/ca333/libzmq/archive
|
||||
$(package)_download_file=v$($(package)_version).tar.gz
|
||||
$(package)_file_name=libzmq-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=0e225b85ce11be23bf7eb7d3f25c6686728bf30d5c31f61c12d37bb646c69962
|
||||
$(package)_sha256_hash=cb8ebe5b60dadeb526745610d6237f05a98aba287114d8991dad1fa14f4be354
|
||||
|
||||
define $(package)_set_vars
|
||||
$(package)_build_env+=
|
||||
$(package)_config_opts=--enable-shared=false --enable-static --host=x86_64-w64-mingw32
|
||||
$(package)_config_opts_mingw32=--enable-shared=false --enable-static --host=x86_64-w64-mingw32
|
||||
$(package)_config_opts_mingw32=--enable-shared=false --enable-static --prefix=$(host_prefix) --host=x86_64-w64-mingw32 -disable-curve
|
||||
$(package)_cflags=-Wno-error -Wall -Wno-pedantic-ms-format -DLIBCZMQ_EXPORTS -DZMQ_DEFINED_STDINT -lws2_32 -liphlpapi -lrpcrt4
|
||||
$(package)_conf_tool=./configure
|
||||
endef
|
||||
else
|
||||
package=zeromq
|
||||
$(package)_version=4.3.1
|
||||
$(package)_download_path=https://github.com/zeromq/libzmq/releases/download/v$($(package)_version)/
|
||||
$(package)_download_path=https://github.com/zeromq/libzmq/releases/download/v$($(package)_version)
|
||||
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=bcbabe1e2c7d0eec4ed612e10b94b112dd5f06fcefa994a0c79a45d835cd21eb
|
||||
|
||||
|
||||
58
doc/release-notes/release-notes-0.3.0.md
Normal file
58
doc/release-notes/release-notes-0.3.0.md
Normal file
@@ -0,0 +1,58 @@
|
||||
|
||||
Komodo specific changelog:
|
||||
|
||||
- add CC functionality and bugfixes
|
||||
- set sapling activation
|
||||
- change z-addr prefix byte
|
||||
- blocksize increased from 2MB to 4 MB
|
||||
- transaction size increased from 100KB to 200KB
|
||||
|
||||
Sapling related changelog:
|
||||
|
||||
- Decoupled Spend Authority
|
||||
- Improved Performance for Shielded Transactions (using sapling instead of sprout)
|
||||
- transaction format changed
|
||||
|
||||
Alex Morcos (1): Output line to debug.log when IsInitialBlockDownload latches to false
|
||||
|
||||
Ariel Gabizon (1): Extend Joinsplit tests to Groth
|
||||
|
||||
Charlie OKeefe (1): Remove extra slash from lockfile path
|
||||
|
||||
Cory Fields (1): crypter: shuffle Makefile so that crypto can be used by the wallet
|
||||
|
||||
Daira Hopwood (1): Support testnet rollback.
|
||||
|
||||
Daniel Cousens (2): move rpc* to rpc/ rpc: update inline comments to refer to new file paths
|
||||
|
||||
Dimitris Apostolou (1): Fix typos
|
||||
|
||||
Duke Leto (3): Fix absurd fee bug reported in #3281, with tests Update comment as per @arielgabizon Improve error message
|
||||
|
||||
Eirik Ogilvie-Wigley (24): Add more options when asserting in RPC tests Add change indicator for notes Fix test broken by change indicator Rename note data to include sprout Remove redundant curly braces Consolidate for loops Add out point for sapling note data Add sapling note data and map Decrement sapling note witnesses Clear sapling witness cache Extract method for copying previous witnesses Extract methods for incrementing witnesses Extract method for incrementing witness heights Pass sapling merkle tree when incrementing witnesses Increment sapling note witnesses Rename sprout specific methods Remove extra indentation Add getter and setter for sapling note data and update tests Add parameter for version in GetValidReceive Rename Merkle Trees to include sprout or sapling Rename Witnesses to include sprout or sapling Rename test objects to include sprout or sapling Only include the change field if we have a spending key Fix assertion and comment
|
||||
|
||||
Gregory Maxwell (2): IBD check uses minimumchain work instead of checkpoints. IsInitialBlockDownload no longer uses header-only timestamps.
|
||||
|
||||
Jack Grigg (41): Add some more checkpoints, up to the 1.1.0 release Add Sapling support to z_validateaddress Update payment-api.md with type field of z_validateaddress Alter SaplingNote::nullifier() to take a SaplingFullViewingKey Expose note position in IncrementalMerkleWitness TransactionBuilder with support for creating Sapling-only transactions TransactionBuilder: Check that all anchors in a transaction are identical Formatting test: Move ECC_Start() call into src/gtest/main.cpp TransactionBuilder: Add support for transparent inputs and outputs TransactionBuilder: Add change output to transaction TransactionBuilder: Make fee configurable Rename xsk to expsk Implement CKeyStore::GetSaplingPaymentAddresses() Raise the 90-character limit on Bech32 encodings Add Sapling support to z_getnewaddress and z_listaddresses Fix block hash for checkpoint at height 270000 Formatting test: Deduplicate logic in wallet_addresses RPC test test: Another assert in wallet_zkeys_tests.store_and_load_sapling_zkeys test: Fix permissions of wallet_addresses test: Update rpc_wallet_z_importexport to account for Sapling changes Rename DecryptSpendingKey -> DecryptSproutSpendingKey Rename CryptedSpendingKeyMap -> CryptedSproutSpendingKeyMap Add Sapling decryption check to CCryptoKeyStore::Unlock() Check for unencrypted Sapling keys in CCryptoKeyStore::SetCrypted() Remove outdated comment Add CWallet::AddCryptedSaplingSpendingKey() hook Pass SaplingPaymentAddress to store through the CKeyStore Rename SpendingKeyMap -> SproutSpendingKeyMap Rename SerializedSize -> SerializedSproutSize Rename ViewingKey -> SproutViewingKey Formatting nits Rename *SpendingKey -> *SproutSpendingKey chainparams: Add BIP 44 coin type (as registered in SLIP 44) Upgrade Rust to 1.28.0 stable Adjust Makefile so that common can be used by the wallet Move RewindBlockIndex log message inside rewindLength check test: gtest for Sapling encoding and decoding test: Use regtest in key_tests/zs_address_test Disable Sapling features on mainnet
|
||||
|
||||
Jay Graber (13): Add Sapling Add/Have/Get to keystore Add SaplingIncomingViewingKeys map, SaplingFullViewingKey methods Add StoreAndRetrieveSaplingSpendingKey test Change default_address to return SaplingPaymentAddr and not boost::optional Add crypted keystore sapling add key Discard sk if ivk == 0 Add Sapling support to z_exportkey Add Sapling support to z_importkey Add Sapling to rpc_wallet_z_importexport test Refactor into visitors and throw errors for invalid key or address. Take expiryheight as param to createrawtransaction Add Sapling have/get sk crypter overrides Add Sapling keys to CCryptoKeyStore::EncryptKeys
|
||||
|
||||
Jonas Schnelli (2): [RPC, Wallet] Move RPC dispatch table registration to wallet/ code Fix test_bitcoin circular dependency issue
|
||||
|
||||
Kaz Wesley (1): IsInitialBlockDownload: usually avoid locking
|
||||
|
||||
Larry Ruane (4): Disable libsnark debug logging in Boost tests add extra help how to enable experimental features Add call to sync_all() after (z_sendmany, wait) don't ban peers when loading pre-overwinter blocks
|
||||
|
||||
Pejvan (2): Update README.md Update README.md
|
||||
|
||||
Richard Littauer (1): docs(LICENSE): update license year to 2018
|
||||
|
||||
Sean Bowe (21): Update librustzcash Implementation of Sapling in-band secret distribution. Swap types in OutputDescription to use new NoteEncryption interfaces. Prevent nonce reuse in Sapling note encryption API. Add get_esk() function to Sapling note encryption. Minor edits Decryption and tests of note/outgoing encryption. Update librustzcash and sapling-crypto. Fix bug in return value. Ensure sum of valueBalance and all vpub_new's does not exceed MAX_MONEY inside of CheckTransactionWithoutProofVerification. Move extern params to beginning of test_checktransaction. Relocate ECC_Start() to avoid test failures. Don't call ECC_Start/ECC_Stop outside the test harness. Make changes to gtest ECC behavior suggested by @str4d. Check the hash of the (Sapling+) zk-SNARK parameters during initialization. Switch to use the official Sapling parameters. make-release.py: Versioning changes for 2.0.0-rc1. make-release.py: Updated manpages for 2.0.0-rc1. make-release.py: Updated release notes and changelog for 2.0.0-rc1. Always write the empty root down as the best root, since we may roll back. Sapling mainnet activation height
|
||||
|
||||
Simon Liu (11): Add encryption of SaplingNotePlaintext and SaplingOutgoingPlaintext classes. Update and fix per review comments, the test for absurd fee. Minor update to address nits in review. Implement Sapling note decryption using full viewing key. Rename AttemptSaplingEncDecryptionUsingFullViewingKey and use function overloading. Only check for a valid Sapling anchor after Sapling activation. Clean up for rebase: rename mapNoteData to mapSproutNoteData. Clean up help messages for RPC createrawtransaction. Add tests for expiryheight parameter of RPC createrawtransaction. make-release.py: Versioning changes for 2.0.0. make-release.py: Updated manpages for 2.0.0.
|
||||
|
||||
Wladimir J. van der Laan (2): Make max tip age an option instead of chainparam rpc: Register calls where they are defined
|
||||
|
||||
kozyilmaz (1): Add -Wl,-pie linker option for macOS and use it instead of -pie
|
||||
|
||||
mdr0id (1): Fix minor references to auto-senescence in code
|
||||
@@ -11,6 +11,8 @@ export BITCOIND=${REAL_BITCOIND}
|
||||
#Run the tests
|
||||
|
||||
testScripts=(
|
||||
'dpow.py'
|
||||
'dpowconfs.py'
|
||||
'ac_private.py'
|
||||
'verushash.py'
|
||||
'paymentdisclosure.py'
|
||||
|
||||
@@ -31,7 +31,8 @@ class CryptoconditionsChannelsTest(CryptoconditionsTestFramework):
|
||||
result = rpc.channelsaddress(self.pubkey)
|
||||
assert_success(result)
|
||||
# test that additional CCaddress key is returned
|
||||
for x in ['myCCaddress', 'ChannelsCCaddress', 'Channelsmarker', 'myaddress', 'CCaddress']:
|
||||
for x in ['ChannelsCC1of2TokensAddress', 'myCCAddress(Channels)', 'ChannelsCC1of2Address', 'myAddress', \
|
||||
'myCCaddress', 'ChannelsNormalAddress', 'PubkeyCCaddress(Channels)', 'ChannelsCCAddress']:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
# getting empty channels list
|
||||
|
||||
@@ -24,15 +24,19 @@ class CryptoconditionsDiceTest(CryptoconditionsTestFramework):
|
||||
result = rpc1.getbalance()
|
||||
assert_greater_than(result, 100000)
|
||||
|
||||
dice = rpc.diceaddress()
|
||||
assert_equal(dice['result'], 'success')
|
||||
for x in ['myCCaddress', 'DiceCCaddress', 'Dicemarker', 'myaddress']:
|
||||
assert_equal(dice[x][0], 'R')
|
||||
result = rpc.diceaddress()
|
||||
for x in result.keys():
|
||||
print(x+": "+str(result[x]))
|
||||
assert_equal(result['result'], 'success')
|
||||
for x in ['myCCaddress', 'DiceCCAddress', 'myaddress']:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
dice = rpc.diceaddress(self.pubkey)
|
||||
assert_equal(dice['result'], 'success')
|
||||
for x in ['myCCaddress', 'DiceCCaddress', 'Dicemarker', 'myaddress', 'CCaddress']:
|
||||
assert_equal(dice[x][0], 'R')
|
||||
result = rpc.diceaddress(self.pubkey)
|
||||
for x in result.keys():
|
||||
print(x+": "+str(result[x]))
|
||||
assert_equal(result['result'], 'success')
|
||||
for x in ['myCCaddress', 'DiceCCAddress', 'myaddress', 'DiceCCTokensAddress', 'DiceNormalAddress']:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
# no dice created yet
|
||||
result = rpc.dicelist()
|
||||
|
||||
@@ -24,16 +24,20 @@ class CryptoconditionsFaucetTest(CryptoconditionsTestFramework):
|
||||
assert_greater_than(result['balance'], 0.0)
|
||||
balance = result['balance']
|
||||
|
||||
faucet = rpc.faucetaddress()
|
||||
assert_equal(faucet['result'], 'success')
|
||||
result = rpc.faucetaddress()
|
||||
assert_equal(result['result'], 'success')
|
||||
for x in result.keys():
|
||||
print(x+": "+str(result[x]))
|
||||
# verify all keys look like valid AC addrs, could be better
|
||||
for x in ['myCCaddress', 'FaucetCCaddress', 'Faucetmarker', 'myaddress']:
|
||||
assert_equal(faucet[x][0], 'R')
|
||||
for x in ['myCCaddress', 'FaucetCCTokensAddress', 'FaucetNormalAddress', 'myaddress']:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
result = rpc.faucetaddress(self.pubkey)
|
||||
assert_success(result)
|
||||
for x in result.keys():
|
||||
print(x+": "+str(result[x]))
|
||||
# test that additional CCaddress key is returned
|
||||
for x in ['myCCaddress', 'FaucetCCaddress', 'Faucetmarker', 'myaddress', 'CCaddress']:
|
||||
for x in ['myCCaddress', 'FaucetCCTokensAddress', 'FaucetNormalAddress', 'myaddress']:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
# no funds in the faucet yet
|
||||
|
||||
@@ -20,16 +20,16 @@ class CryptoconditionsHeirTest(CryptoconditionsTestFramework):
|
||||
rpc = self.nodes[0]
|
||||
rpc1 = self.nodes[1]
|
||||
|
||||
result = rpc.heiraddress()
|
||||
result = rpc.heiraddress('')
|
||||
assert_success(result)
|
||||
# verify all keys look like valid AC addrs, could be better
|
||||
for x in ['myCCaddress', 'HeirCCaddress', 'Heirmarker', 'myaddress']:
|
||||
for x in ['HeirNormalAddress', 'HeirCCTokensAddress', 'myaddress', 'myCCaddress', 'HeirCCAddress']:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
result = rpc.heiraddress(self.pubkey)
|
||||
assert_success(result)
|
||||
# test that additional CCaddress key is returned
|
||||
for x in ['myCCaddress', 'HeirCCaddress', 'Heirmarker', 'myaddress', 'CCaddress']:
|
||||
for x in ['HeirNormalAddress', 'myCCaddress', 'myaddress', 'HeirCC1of2Address', 'HeirCCAddress', 'HeirCC1of2TokensAddress']:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
# getting empty heir list
|
||||
|
||||
@@ -22,12 +22,12 @@ class CryptoconditionsOraclesTest(CryptoconditionsTestFramework):
|
||||
|
||||
result = rpc.oraclesaddress()
|
||||
assert_success(result)
|
||||
for x in ['OraclesCCaddress', 'Oraclesmarker', 'myCCaddress', 'myaddress']:
|
||||
for x in ['myCCaddress', 'OraclesCCAddress', 'OraclesNormalAddress', 'myaddress', 'OraclesCCTokensAddress']:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
result = rpc.oraclesaddress(self.pubkey)
|
||||
assert_success(result)
|
||||
for x in ['OraclesCCaddress', 'Oraclesmarker', 'myCCaddress', 'myaddress']:
|
||||
for x in ['myCCaddress', 'OraclesCCAddress', 'OraclesNormalAddress', 'myaddress', 'OraclesCCTokensAddress']:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
# there are no oracles created yet
|
||||
|
||||
@@ -15,13 +15,15 @@ from cryptoconditions import assert_success, assert_error, generate_random_strin
|
||||
class CryptoconditionsRewardsTest(CryptoconditionsTestFramework):
|
||||
|
||||
def run_rewards_tests(self):
|
||||
|
||||
rpc = self.nodes[0]
|
||||
|
||||
result = rpc.rewardsaddress()
|
||||
for x in ['RewardsCCaddress', 'myCCaddress', 'Rewardsmarker', 'myaddress']:
|
||||
for x in ['myCCaddress', 'myaddress', 'RewardsCCAddress', 'RewardsCCTokensAddress', 'RewardsNormalAddress']:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
result = rpc.rewardsaddress(self.pubkey)
|
||||
for x in ['RewardsCCaddress', 'myCCaddress', 'Rewardsmarker', 'myaddress', 'CCaddress']:
|
||||
for x in ['myCCaddress', 'myaddress', 'RewardsCCAddress', 'RewardsCCTokensAddress', 'RewardsNormalAddress']:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
# no rewards yet
|
||||
|
||||
@@ -21,22 +21,22 @@ class CryptoconditionsTokenTest(CryptoconditionsTestFramework):
|
||||
|
||||
result = rpc.tokenaddress()
|
||||
assert_success(result)
|
||||
for x in ['TokensCCaddress', 'myCCaddress', 'Tokensmarker', 'myaddress']:
|
||||
for x in ['TokensCCAddress', 'myCCaddress', 'myCCAddress(Tokens)', 'myaddress', 'TokensNormalAddress']:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
result = rpc.tokenaddress(self.pubkey)
|
||||
assert_success(result)
|
||||
for x in ['TokensCCaddress', 'myCCaddress', 'Tokensmarker', 'myaddress', 'CCaddress']:
|
||||
for x in ['TokensCCAddress', 'myCCaddress', 'myCCAddress(Tokens)', 'myaddress', 'TokensNormalAddress']:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
result = rpc.assetsaddress()
|
||||
assert_success(result)
|
||||
for x in ['AssetsCCaddress', 'myCCaddress', 'Assetsmarker', 'myaddress']:
|
||||
for x in ['AssetsCCAddress', 'myCCaddress', 'myCCAddress(Assets)', 'myaddress', 'AssetsNormalAddress']:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
result = rpc.assetsaddress(self.pubkey)
|
||||
assert_success(result)
|
||||
for x in ['AssetsCCaddress', 'myCCaddress', 'Assetsmarker', 'myaddress', 'CCaddress']:
|
||||
for x in ['AssetsCCAddress', 'myCCaddress', 'myCCAddress(Assets)', 'myaddress', 'AssetsNormalAddress']:
|
||||
assert_equal(result[x][0], 'R')
|
||||
|
||||
# there are no tokens created yet
|
||||
@@ -61,7 +61,7 @@ class CryptoconditionsTokenTest(CryptoconditionsTestFramework):
|
||||
assert_equal(result[0], tokenid)
|
||||
|
||||
# there are no token orders yet
|
||||
result = rpc.tokenorders()
|
||||
result = rpc.tokenorders(tokenid)
|
||||
assert_equal(result, [])
|
||||
|
||||
# getting token balance for non existing tokenid
|
||||
@@ -117,7 +117,7 @@ class CryptoconditionsTokenTest(CryptoconditionsTestFramework):
|
||||
tokenask = rpc.tokenask("100", tokenid, "7.77")
|
||||
tokenaskhex = tokenask['hex']
|
||||
tokenaskid = self.send_and_mine(tokenask['hex'], rpc)
|
||||
result = rpc.tokenorders()
|
||||
result = rpc.tokenorders(tokenid)
|
||||
order = result[0]
|
||||
assert order, "found order"
|
||||
|
||||
@@ -136,7 +136,7 @@ class CryptoconditionsTokenTest(CryptoconditionsTestFramework):
|
||||
assert txid, "found txid"
|
||||
|
||||
# should be no token orders
|
||||
result = rpc.tokenorders()
|
||||
result = rpc.tokenorders(tokenid)
|
||||
assert_equal(result, [])
|
||||
|
||||
# checking ask cancellation
|
||||
@@ -157,7 +157,7 @@ class CryptoconditionsTokenTest(CryptoconditionsTestFramework):
|
||||
# from valid node
|
||||
cancel = rpc.tokencancelask(tokenid, testorderid)
|
||||
self.send_and_mine(cancel["hex"], rpc)
|
||||
result = rpc.tokenorders()
|
||||
result = rpc.tokenorders(tokenid)
|
||||
assert_equal(result, [])
|
||||
|
||||
|
||||
@@ -184,7 +184,7 @@ class CryptoconditionsTokenTest(CryptoconditionsTestFramework):
|
||||
tokenbid = rpc.tokenbid("100", tokenid, "10")
|
||||
tokenbidhex = tokenbid['hex']
|
||||
tokenbidid = self.send_and_mine(tokenbid['hex'], rpc)
|
||||
result = rpc.tokenorders()
|
||||
result = rpc.tokenorders(tokenid)
|
||||
order = result[0]
|
||||
assert order, "found order"
|
||||
|
||||
@@ -203,7 +203,7 @@ class CryptoconditionsTokenTest(CryptoconditionsTestFramework):
|
||||
assert txid, "found txid"
|
||||
|
||||
# should be no token orders
|
||||
result = rpc.tokenorders()
|
||||
result = rpc.tokenorders(tokenid)
|
||||
assert_equal(result, [])
|
||||
|
||||
# checking bid cancellation
|
||||
@@ -220,7 +220,7 @@ class CryptoconditionsTokenTest(CryptoconditionsTestFramework):
|
||||
# from valid node
|
||||
cancel = rpc.tokencancelbid(tokenid, testorderid)
|
||||
self.send_and_mine(cancel["hex"], rpc)
|
||||
result = rpc.tokenorders()
|
||||
result = rpc.tokenorders(tokenid)
|
||||
assert_equal(result, [])
|
||||
|
||||
# invalid token transfer amount (have to add status to CC code!)
|
||||
|
||||
151
qa/rpc-tests/dpowconfs.py
Executable file
151
qa/rpc-tests/dpowconfs.py
Executable file
@@ -0,0 +1,151 @@
|
||||
#!/usr/bin/env python2
|
||||
# Copyright (c) 2018 The Hush developers
|
||||
# Copyright (c) 2019 The SuperNET developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import *
|
||||
import time
|
||||
|
||||
class DPoWConfsTest(BitcoinTestFramework):
|
||||
def debug_info(self):
|
||||
rpc = self.nodes[0]
|
||||
print "-- DEBUG --"
|
||||
getinfo = rpc.getinfo()
|
||||
getwalletinfo = rpc.getwalletinfo()
|
||||
listreceivedbyaddress = rpc.listreceivedbyaddress()
|
||||
print "notarized=", getinfo['notarized'], " blocks=", getinfo['blocks']
|
||||
#print "getinfo=", getinfo
|
||||
print "balance=", getwalletinfo['balance']
|
||||
#print "getwalletinfo=", getwalletinfo
|
||||
print "listreceivedbyaddress=", listreceivedbyaddress
|
||||
print "-- DEBUG --"
|
||||
|
||||
def setup_chain(self):
|
||||
self.num_nodes = 1
|
||||
print("Initializing DPoWconfs test directory "+self.options.tmpdir)
|
||||
initialize_chain_clean(self.options.tmpdir, self.num_nodes)
|
||||
|
||||
def setup_network(self):
|
||||
print("Setting up network...")
|
||||
self.nodes = []
|
||||
self.is_network_split = False
|
||||
self.addr = "RWPg8B91kfK5UtUN7z6s6TeV9cHSGtVY8D"
|
||||
self.pubkey = "02676d00110c2cd14ae24f95969e8598f7ccfaa675498b82654a5b5bd57fc1d8cf"
|
||||
self.nodes = start_nodes( self.num_nodes, self.options.tmpdir,
|
||||
extra_args=[[
|
||||
'-ac_name=REGTEST',
|
||||
'-conf='+self.options.tmpdir+'/node0/REGTEST.conf',
|
||||
'-port=64367',
|
||||
'-rpcport=64368',
|
||||
'-regtest',
|
||||
'-addressindex=1',
|
||||
'-spentindex=1',
|
||||
'-ac_supply=5555555',
|
||||
'-ac_reward=10000000000000',
|
||||
#'-pubkey=' + self.pubkey,
|
||||
'-ac_cc=2',
|
||||
'-whitelist=127.0.0.1',
|
||||
'-debug',
|
||||
'--daemon',
|
||||
'-rpcuser=rt',
|
||||
'-rpcpassword=rt'
|
||||
]]
|
||||
)
|
||||
self.sync_all()
|
||||
|
||||
def run_test(self):
|
||||
rpc = self.nodes[0]
|
||||
# 98 is notarized, next will be 105. Must mine at least 101
|
||||
# blocks for 100 block maturity rule
|
||||
blockhashes = rpc.generate(101)
|
||||
# block 98, this is 0 indexed
|
||||
notarizedhash = blockhashes[97]
|
||||
self.debug_info()
|
||||
|
||||
taddr = rpc.getnewaddress()
|
||||
txid = rpc.sendtoaddress(taddr, 5.55)
|
||||
# blocks 102,103
|
||||
rpc.generate(2)
|
||||
self.debug_info()
|
||||
|
||||
info = rpc.getinfo()
|
||||
print "notarizedhash=", notarizedhash, "\n"
|
||||
print "info[notarizedhash]", info['notarizedhash'], "\n"
|
||||
assert_equal( info['notarizedhash'], notarizedhash)
|
||||
|
||||
result = rpc.listunspent()
|
||||
|
||||
# this xtn has 2 raw confs, but not in a notarized block,
|
||||
# so dpowconfs holds it at 1
|
||||
for res in result:
|
||||
if (res['address'] == taddr and res['generated'] == 'false'):
|
||||
assert_equal( result[0]['confirmations'], 1 )
|
||||
assert_equal( result[0]['rawconfirmations'], 2 )
|
||||
|
||||
# we will now have 3 rawconfs but confirmations=1 because not notarized
|
||||
# block 104
|
||||
rpc.generate(1)
|
||||
self.debug_info()
|
||||
minconf = 2
|
||||
result = rpc.listreceivedbyaddress(minconf)
|
||||
print "listreceivedbyaddress(2)=", result, "\n"
|
||||
|
||||
# nothing is notarized, so we should see no results for minconf=2
|
||||
assert len(result) == 0
|
||||
|
||||
print "getreceivedaddress"
|
||||
received = rpc.getreceivedbyaddress(taddr, minconf)
|
||||
assert_equal( received, 0.00000000)
|
||||
|
||||
#received = rpc.getreceivedbyaddress(taddr)
|
||||
#assert_equal( received, "5.55000000")
|
||||
taddr = rpc.getnewaddress()
|
||||
zaddr = rpc.z_getnewaddress()
|
||||
# should get insufficient funds error
|
||||
recipients = [ { "amount" : Decimal('4.20'), "address" : zaddr } ]
|
||||
txid = rpc.z_sendmany( taddr, recipients, minconf)
|
||||
|
||||
# generate a notarized block, block 105 and block 106
|
||||
# only generating the notarized block seems to have
|
||||
# race conditions about whether the block is notarized
|
||||
txids = rpc.generate(2)
|
||||
self.debug_info()
|
||||
|
||||
getinfo = rpc.getinfo()
|
||||
# try to allow notarization data to update
|
||||
print "Sleeping"
|
||||
while (getinfo['blocks'] != 106) or (getinfo['notarized'] != 105):
|
||||
printf(".")
|
||||
time.sleep(1)
|
||||
getinfo = rpc.getinfo()
|
||||
|
||||
# make sure this block was notarized as we expect
|
||||
#assert_equal(getinfo['blocks'], getinfo['notarized'])
|
||||
#assert_equal(getinfo['notarizedhash'], txids[0])
|
||||
|
||||
result = rpc.listreceivedbyaddress(minconf)
|
||||
print "listreceivedbyaddress(2)=", result
|
||||
|
||||
assert_equal( len(result), 1, 'got one xtn with minconf=2' )
|
||||
|
||||
# verify we see the correct dpowconfs + rawconfs
|
||||
assert_greater_than( result[0]['confirmations'], 1)
|
||||
assert_greater_than( result[0]['rawconfirmations'], 1)
|
||||
|
||||
print "listtransactions"
|
||||
xtns = rpc.listtransactions()
|
||||
# verify this rpc agrees with listreceivedbyaddress
|
||||
assert_greater_than(xtns[0]['confirmations'], 1)
|
||||
assert_greater_than(xtns[0]['rawconfirmations'], 1)
|
||||
|
||||
print "getreceivedaddress"
|
||||
received = rpc.getreceivedbyaddress(taddr, minconf)
|
||||
assert_equal( "%.8f" % received, "5.55000000")
|
||||
|
||||
received = rpc.getreceivedbyaddress(taddr)
|
||||
assert_equal( "%.8f" % received, "5.55000000")
|
||||
|
||||
if __name__ == '__main__':
|
||||
DPoWConfsTest().main()
|
||||
@@ -1,9 +1,7 @@
|
||||
# Copyright (c) 2014 The Bitcoin Core developers
|
||||
# Copyright (c) 2018 The SuperNET developers
|
||||
# Copyright (c) 2018-2019 The SuperNET developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
|
||||
#
|
||||
# Helpful routines for regression testing
|
||||
#
|
||||
@@ -415,10 +413,16 @@ def assert_true(condition, message = ""):
|
||||
def assert_false(condition, message = ""):
|
||||
assert_true(not condition, message)
|
||||
|
||||
# assert thing2 > thing1
|
||||
def assert_greater_than(thing1, thing2):
|
||||
if thing1 <= thing2:
|
||||
raise AssertionError("%s <= %s"%(str(thing1),str(thing2)))
|
||||
|
||||
# assert thing2 >= thing1
|
||||
def assert_greater_than_or_equal(thing1, thing2):
|
||||
if thing1 < thing2:
|
||||
raise AssertionError("%s < %s"%(str(thing1),str(thing2)))
|
||||
|
||||
def assert_raises(exc, fun, *args, **kwds):
|
||||
try:
|
||||
fun(*args, **kwds)
|
||||
|
||||
@@ -204,6 +204,7 @@ BITCOIN_CORE_H = \
|
||||
mruset.h \
|
||||
net.h \
|
||||
netbase.h \
|
||||
notaries_staked.h \
|
||||
noui.h \
|
||||
paymentdisclosure.h \
|
||||
paymentdisclosuredb.h \
|
||||
@@ -311,6 +312,7 @@ libbitcoin_server_a_SOURCES = \
|
||||
chain.cpp \
|
||||
checkpoints.cpp \
|
||||
crosschain.cpp \
|
||||
crosschain_authority.cpp \
|
||||
crypto/haraka.h \
|
||||
crypto/haraka_portable.h \
|
||||
crypto/verus_hash.h \
|
||||
@@ -325,6 +327,7 @@ libbitcoin_server_a_SOURCES = \
|
||||
metrics.h \
|
||||
miner.cpp \
|
||||
net.cpp \
|
||||
notaries_staked.cpp \
|
||||
noui.cpp \
|
||||
notarisationdb.cpp \
|
||||
paymentdisclosure.cpp \
|
||||
@@ -487,6 +490,8 @@ libbitcoin_common_a_SOURCES = \
|
||||
script/sign.cpp \
|
||||
script/standard.cpp \
|
||||
transaction_builder.cpp \
|
||||
cc/CCtokensOpRet.cpp \
|
||||
cc/CCutilbits.cpp \
|
||||
$(BITCOIN_CORE_H) \
|
||||
$(LIBZCASH_H)
|
||||
|
||||
|
||||
3
src/ac/ilien
Executable file
3
src/ac/ilien
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
./komodo-cli -ac_name=ILN $1 $2 $3 $4 $5 $6
|
||||
|
||||
2
src/ac/iln
Executable file
2
src/ac/iln
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
./komodo-cli -ac_name=ILN $1 $2 $3 $4 $5 $6
|
||||
2
src/ac/our
Executable file
2
src/ac/our
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
./komodo-cli -ac_name=OUR $1 $2 $3 $4 $5 $6
|
||||
@@ -64,13 +64,10 @@
|
||||
"ac_name": "MESH",
|
||||
"ac_supply": "1000007"
|
||||
},
|
||||
{
|
||||
"ac_name": "MNZ",
|
||||
"ac_supply": "257142858"
|
||||
},
|
||||
{
|
||||
"ac_name": "AXO",
|
||||
"ac_supply": "200000000"
|
||||
"ac_supply": "200000000",
|
||||
"ac_ccactivate": "130000"
|
||||
},
|
||||
{
|
||||
"ac_name": "ETOMIC",
|
||||
@@ -182,7 +179,7 @@
|
||||
"190.114.254.104"
|
||||
]
|
||||
},
|
||||
{
|
||||
{
|
||||
"ac_name": "DION",
|
||||
"ac_supply": "3900000000",
|
||||
"ac_reward": "22260000000",
|
||||
@@ -238,7 +235,14 @@
|
||||
"addnode": [
|
||||
"51.255.195.65",
|
||||
"217.182.129.38",
|
||||
"95.216.150.177"
|
||||
]
|
||||
}
|
||||
"37.187.225.231"
|
||||
]
|
||||
},
|
||||
{
|
||||
"ac_name": "ILN",
|
||||
"ac_supply": "10000000000",
|
||||
"ac_cc": "2",
|
||||
"addnode": ["51.75.122.83"]
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
@@ -20,8 +20,7 @@ echo $pubkey
|
||||
./komodod -pubkey=$pubkey -ac_name=KV -ac_supply=1000000 -addnode=78.47.196.146 $1 &
|
||||
./komodod -pubkey=$pubkey -ac_name=CEAL -ac_supply=366666666 -addnode=78.47.196.146 $1 &
|
||||
./komodod -pubkey=$pubkey -ac_name=MESH -ac_supply=1000007 -addnode=78.47.196.146 $1 &
|
||||
./komodod -pubkey=$pubkey -ac_name=MNZ -ac_supply=257142858 -addnode=51.15.138.138 $1 &
|
||||
./komodod -pubkey=$pubkey -ac_name=AXO -ac_supply=200000000 -addnode=78.47.196.146 &
|
||||
./komodod -pubkey=$pubkey -ac_name=AXO -ac_supply=200000000 -ac_ccactivate=130000 -addnode=78.47.196.146 &
|
||||
./komodod -pubkey=$pubkey -ac_name=ETOMIC -ac_supply=100000000 -addnode=78.47.196.146 &
|
||||
./komodod -pubkey=$pubkey -ac_name=BTCH -ac_supply=20998641 -addnode=78.47.196.146 &
|
||||
./komodod -pubkey=$pubkey -ac_name=BEER -ac_supply=100000000 -addnode=78.47.196.146 &
|
||||
@@ -46,3 +45,6 @@ echo $pubkey
|
||||
./komodod -pubkey=$pubkey -ac_name=DION -ac_supply=3900000000 -ac_reward=22260000000 -ac_staked=100 -ac_cc=1 -ac_end=4300000000 -addnode=51.75.124.34 &
|
||||
./komodod -pubkey=$pubkey -ac_name=ZEX -ac_cc=2 -ac_founders=1 -ac_halving=525600 -ac_reward=13000000000 -ac_pubkey=039d4a50cc70d1184e462a22edb3b66385da97cc8059196f8305c184a3e21440af -addnode=5.9.102.210 &
|
||||
./komodod -pubkey=$pubkey -ac_name=KSB -ac_supply=1000000000 -ac_end=1 -ac_public=1 -addnode=37.187.225.231 &
|
||||
./komodod -pubkey=$pubkey -ac_name=OUR -ac_reward=1478310502 -ac_halving=525600 -ac_cc=42 -ac_supply=100000000 -ac_perc=77700 -ac_staked=93 -ac_pubkey=02652a3f3e00b3a1875a918314f0bac838d6dd189a346fa623f5efe9541ac0b98c -ac_public=1 -addnode=51.255.195.65 -addnode=217.182.129.38 -addnode=37.187.225.231 &
|
||||
./komodod -pubkey=$pubkey -ac_name=ILN -ac_supply=10000000000 -ac_cc=2 -addressindex=1 -spentindex=1 -addnode=51.75.122.83 &
|
||||
|
||||
|
||||
@@ -19,9 +19,16 @@
|
||||
|
||||
#include "CCinclude.h"
|
||||
|
||||
#define PAYMENTS_TXFEE 10000
|
||||
|
||||
bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn);
|
||||
|
||||
// CCcustom
|
||||
UniValue PaymentsInfo();
|
||||
UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr);
|
||||
UniValue PaymentsFund(struct CCcontract_info *cp,char *jsonstr);
|
||||
UniValue PaymentsTxidopret(struct CCcontract_info *cp,char *jsonstr);
|
||||
UniValue PaymentsCreate(struct CCcontract_info *cp,char *jsonstr);
|
||||
UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr);
|
||||
UniValue PaymentsList(struct CCcontract_info *cp,char *jsonstr);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
bool AssetsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn);
|
||||
|
||||
// CCassetsCore
|
||||
CScript EncodeAssetOpRet(uint8_t assetFuncId, uint256 assetid2, int64_t price, std::vector<uint8_t> origpubkey);
|
||||
vscript_t EncodeAssetOpRet(uint8_t assetFuncId, uint256 assetid2, int64_t price, std::vector<uint8_t> origpubkey);
|
||||
uint8_t DecodeAssetTokenOpRet(const CScript &scriptPubKey, uint8_t &assetsEvalCode, uint256 &tokenid, uint256 &assetid2, int64_t &price, std::vector<uint8_t> &origpubkey);
|
||||
bool SetAssetOrigpubkey(std::vector<uint8_t> &origpubkey,int64_t &price,const CTransaction &tx);
|
||||
int64_t IsAssetvout(struct CCcontract_info *cp, int64_t &price, std::vector<uint8_t> &origpubkey, const CTransaction& tx, int32_t v, uint256 refassetid);
|
||||
|
||||
@@ -239,30 +239,30 @@ CScript EncodeAssetCreateOpRet(uint8_t funcid,std::vector<uint8_t> origpubkey,st
|
||||
}
|
||||
*/
|
||||
|
||||
CScript EncodeAssetOpRet(uint8_t assetFuncId, uint256 assetid2, int64_t price, std::vector<uint8_t> origpubkey)
|
||||
vscript_t EncodeAssetOpRet(uint8_t assetFuncId, uint256 assetid2, int64_t price, std::vector<uint8_t> origpubkey)
|
||||
{
|
||||
CScript opret;
|
||||
vscript_t vopret;
|
||||
uint8_t evalcode = EVAL_ASSETS;
|
||||
|
||||
switch ( assetFuncId )
|
||||
{
|
||||
//case 't': this cannot be here
|
||||
case 'x': case 'o':
|
||||
opret << OP_RETURN << E_MARSHAL(ss << evalcode << assetFuncId);
|
||||
vopret = /*<< OP_RETURN <<*/ E_MARSHAL(ss << evalcode << assetFuncId);
|
||||
break;
|
||||
case 's': case 'b': case 'S': case 'B':
|
||||
opret << OP_RETURN << E_MARSHAL(ss << evalcode << assetFuncId << price << origpubkey);
|
||||
vopret = /*<< OP_RETURN <<*/ E_MARSHAL(ss << evalcode << assetFuncId << price << origpubkey);
|
||||
break;
|
||||
case 'E': case 'e':
|
||||
assetid2 = revuint256(assetid2);
|
||||
opret << OP_RETURN << E_MARSHAL(ss << evalcode << assetFuncId << assetid2 << price << origpubkey);
|
||||
vopret = /*<< OP_RETURN <<*/ E_MARSHAL(ss << evalcode << assetFuncId << assetid2 << price << origpubkey);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"EncodeAssetOpRet: illegal funcid.%02x\n", assetFuncId);
|
||||
opret << OP_RETURN;
|
||||
//opret << OP_RETURN;
|
||||
break;
|
||||
}
|
||||
return(opret);
|
||||
return(vopret);
|
||||
}
|
||||
|
||||
/* it is for compatibility, do not use this for new contracts (use DecodeTokenCreateOpRet)
|
||||
@@ -281,10 +281,11 @@ bool DecodeAssetCreateOpRet(const CScript &scriptPubKey, std::vector<uint8_t> &o
|
||||
|
||||
uint8_t DecodeAssetTokenOpRet(const CScript &scriptPubKey, uint8_t &assetsEvalCode, uint256 &tokenid, uint256 &assetid2, int64_t &price, std::vector<uint8_t> &origpubkey)
|
||||
{
|
||||
std::vector<uint8_t> vopretAssets; //, vopretAssetsStripped;
|
||||
vscript_t vopretAssets; //, vopretAssetsStripped;
|
||||
uint8_t *script, funcId = 0, assetsFuncId = 0, dummyEvalCode, dummyAssetFuncId;
|
||||
uint256 dummyTokenid;
|
||||
std::vector<CPubKey> voutPubkeysDummy;
|
||||
std::vector<std::pair<uint8_t, vscript_t>> oprets;
|
||||
|
||||
tokenid = zeroid;
|
||||
assetid2 = zeroid;
|
||||
@@ -293,7 +294,9 @@ uint8_t DecodeAssetTokenOpRet(const CScript &scriptPubKey, uint8_t &assetsEvalCo
|
||||
assetsFuncId = 0;
|
||||
|
||||
// First - decode token opret:
|
||||
funcId = DecodeTokenOpRet(scriptPubKey, dummyEvalCode, tokenid, voutPubkeysDummy, vopretAssets);
|
||||
funcId = DecodeTokenOpRet(scriptPubKey, dummyEvalCode, tokenid, voutPubkeysDummy, oprets);
|
||||
GetOpretBlob(oprets, OPRETID_ASSETSDATA, vopretAssets);
|
||||
|
||||
LOGSTREAM((char *)"ccassets", CCLOG_DEBUG2, stream << "DecodeAssetTokenOpRet() from DecodeTokenOpRet returned funcId=" << (int)funcId << std::endl);
|
||||
|
||||
if (funcId == 0 || vopretAssets.size() < 2) {
|
||||
|
||||
@@ -353,9 +353,9 @@ std::string CreateBuyOffer(int64_t txfee, int64_t bidamount, uint256 assetid, in
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_ASSETS, txfee, mypk));
|
||||
std::vector<CPubKey> voutTokenPubkeys; // should be empty - no token vouts
|
||||
|
||||
return(FinalizeCCTx(0, cpAssets, mtx, mypk, txfee,
|
||||
return FinalizeCCTx(0, cpAssets, mtx, mypk, txfee,
|
||||
EncodeTokenOpRet(assetid, voutTokenPubkeys, // TODO: actually this tx is not 'tokens', maybe it is better not to have token opret here but only asset opret.
|
||||
EncodeAssetOpRet('b', zeroid, pricetotal, Mypubkey())))); // But still such token opret should not make problems because no token eval in these vouts
|
||||
std::make_pair(OPRETID_ASSETSDATA, EncodeAssetOpRet('b', zeroid, pricetotal, Mypubkey())))); // But still such token opret should not make problems because no token eval in these vouts
|
||||
}
|
||||
CCerror = strprintf("no coins found to make buy offer");
|
||||
return("");
|
||||
@@ -419,7 +419,7 @@ std::string CreateSell(int64_t txfee,int64_t askamount,uint256 assetid,int64_t p
|
||||
|
||||
return FinalizeCCTx(mask, cpTokens, mtx, mypk, txfee,
|
||||
EncodeTokenOpRet(assetid, voutTokenPubkeys,
|
||||
EncodeAssetOpRet('s', zeroid, pricetotal, Mypubkey())));
|
||||
std::make_pair(OPRETID_ASSETSDATA, EncodeAssetOpRet('s', zeroid, pricetotal, Mypubkey()))));
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "need some tokens to place ask\n");
|
||||
@@ -540,7 +540,7 @@ std::string CancelBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid)
|
||||
|
||||
return(FinalizeCCTx(mask, cpAssets, mtx, mypk, txfee,
|
||||
EncodeTokenOpRet(assetid, voutTokenPubkeys,
|
||||
EncodeAssetOpRet('o', zeroid, 0, Mypubkey()))));
|
||||
std::make_pair(OPRETID_ASSETSDATA, EncodeAssetOpRet('o', zeroid, 0, Mypubkey())))));
|
||||
}
|
||||
}
|
||||
return("");
|
||||
@@ -608,7 +608,7 @@ std::string CancelSell(int64_t txfee,uint256 assetid,uint256 asktxid)
|
||||
|
||||
return(FinalizeCCTx(mask, cpAssets, mtx, mypk, txfee,
|
||||
EncodeTokenOpRet(assetid, voutTokenPubkeys,
|
||||
EncodeAssetOpRet('x', zeroid, 0, Mypubkey()))));
|
||||
std::make_pair(OPRETID_ASSETSDATA, EncodeAssetOpRet('x', zeroid, 0, Mypubkey())))));
|
||||
}
|
||||
}
|
||||
return("");
|
||||
@@ -695,7 +695,7 @@ std::string FillBuyOffer(int64_t txfee,uint256 assetid,uint256 bidtxid,int64_t f
|
||||
|
||||
return(FinalizeCCTx(mask, cpTokens, mtx, mypk, txfee,
|
||||
EncodeTokenOpRet(assetid, voutTokenPubkeys,
|
||||
EncodeAssetOpRet('B', zeroid, remaining_required, origpubkey))));
|
||||
std::make_pair(OPRETID_ASSETSDATA, EncodeAssetOpRet('B', zeroid, remaining_required, origpubkey)))));
|
||||
} else return("dont have any assets to fill bid");
|
||||
}
|
||||
}
|
||||
@@ -820,7 +820,7 @@ std::string FillSell(int64_t txfee, uint256 assetid, uint256 assetid2, uint256 a
|
||||
|
||||
return(FinalizeCCTx(mask, cpAssets, mtx, mypk, txfee,
|
||||
EncodeTokenOpRet(assetid, voutTokenPubkeys,
|
||||
EncodeAssetOpRet(assetid2 != zeroid ? 'E' : 'S', assetid2, remaining_nValue, origpubkey))));
|
||||
std::make_pair(OPRETID_ASSETSDATA, EncodeAssetOpRet(assetid2 != zeroid ? 'E' : 'S', assetid2, remaining_nValue, origpubkey)))));
|
||||
} else {
|
||||
CCerror = strprintf("filltx not enough utxos");
|
||||
fprintf(stderr,"%s\n", CCerror.c_str());
|
||||
|
||||
@@ -67,12 +67,29 @@ one other technical note is that komodod has the insight-explorer extensions bui
|
||||
|
||||
#include "../komodo_cJSON.h"
|
||||
|
||||
// opret data block ids:
|
||||
enum {
|
||||
OPRETID_NONFUNGIBLEDATA = 0x11
|
||||
// TODO: OPRETID_ASSETSDATA = 0x12
|
||||
// token opret additional data block ids:
|
||||
enum opretid : uint8_t {
|
||||
// cc contracts data:
|
||||
OPRETID_NONFUNGIBLEDATA = 0x11,
|
||||
OPRETID_ASSETSDATA = 0x12,
|
||||
OPRETID_GATEWAYSDATA = 0x13,
|
||||
OPRETID_CHANNELSDATA = 0x14,
|
||||
OPRETID_HEIRDATA = 0x15,
|
||||
OPRETID_ROGUEGAMEDATA = 0x16,
|
||||
|
||||
// non cc contract data:
|
||||
OPRETID_FIRSTNONCCDATA = 0x80,
|
||||
OPRETID_BURNDATA = 0x80,
|
||||
OPRETID_IMPORTDATA = 0x81
|
||||
};
|
||||
|
||||
// find opret blob by opretid
|
||||
inline bool GetOpretBlob(const std::vector<std::pair<uint8_t, std::vector<uint8_t>>> &oprets, uint8_t id, std::vector<uint8_t> &vopret) {
|
||||
vopret.clear();
|
||||
for(auto p : oprets) if (p.first == id) { vopret = p.second; return true; }
|
||||
return false;
|
||||
}
|
||||
|
||||
struct CC_utxo
|
||||
{
|
||||
uint256 txid;
|
||||
@@ -129,6 +146,8 @@ struct oracleprice_info
|
||||
int32_t height;
|
||||
};
|
||||
|
||||
typedef std::vector<uint8_t> vscript_t;
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
extern CWallet* pwalletMain;
|
||||
#endif
|
||||
@@ -151,7 +170,7 @@ static int32_t ignorevin;
|
||||
bool myGetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock);
|
||||
int32_t is_hexstr(char *str,int32_t n);
|
||||
bool myAddtomempool(CTransaction &tx, CValidationState *pstate = NULL, bool fSkipExpiry = false);
|
||||
int32_t CCgettxout(uint256 txid,int32_t vout,int32_t mempoolflag);
|
||||
int32_t CCgettxout(uint256 txid,int32_t vout,int32_t mempoolflag,int32_t lockflag);
|
||||
bool myIsutxo_spentinmempool(uint256 &spenttxid,int32_t &spentvini,uint256 txid,int32_t vout);
|
||||
bool mytxid_inmempool(uint256 txid);
|
||||
int32_t myIsutxo_spent(uint256 &spenttxid,uint256 txid,int32_t vout);
|
||||
@@ -172,18 +191,23 @@ uint256 OraclesBatontxid(uint256 oracletxid,CPubKey pk);
|
||||
|
||||
//int64_t AddAssetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint256 assetid,int64_t total,int32_t maxinputs);
|
||||
int64_t AddTokenCCInputs(struct CCcontract_info *cp, CMutableTransaction &mtx, CPubKey pk, uint256 tokenid, int64_t total, int32_t maxinputs);
|
||||
int64_t AddTokenCCInputs(struct CCcontract_info *cp, CMutableTransaction &mtx, CPubKey pk, uint256 tokenid, int64_t total, int32_t maxinputs, std::vector<uint8_t> &vopretNonfungible);
|
||||
int64_t AddTokenCCInputs(struct CCcontract_info *cp, CMutableTransaction &mtx, CPubKey pk, uint256 tokenid, int64_t total, int32_t maxinputs, vscript_t &vopretNonfungible);
|
||||
int64_t IsTokensvout(bool goDeeper, bool checkPubkeys, struct CCcontract_info *cp, Eval* eval, const CTransaction& tx, int32_t v, uint256 reftokenid);
|
||||
|
||||
bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx);
|
||||
|
||||
CScript EncodeTokenCreateOpRet(uint8_t funcid, std::vector<uint8_t> origpubkey, std::string name, std::string description, std::vector<uint8_t> vopretNonfungible);
|
||||
CScript EncodeTokenOpRet(uint8_t tokenFuncId, uint8_t evalCodeInOpret, uint256 tokenid, std::vector<CPubKey> voutPubkeys, CScript payload); //old version
|
||||
CScript EncodeTokenOpRet(uint256 tokenid, std::vector<CPubKey> voutPubkeys, CScript payload);
|
||||
CScript EncodeTokenCreateOpRet(uint8_t funcid, std::vector<uint8_t> origpubkey, std::string name, std::string description, vscript_t vopretNonfungible);
|
||||
CScript EncodeTokenCreateOpRet(uint8_t funcid, std::vector<uint8_t> origpubkey, std::string name, std::string description, std::vector<std::pair<uint8_t, vscript_t>> oprets);
|
||||
CScript EncodeTokenImportOpRet(std::vector<uint8_t> origpubkey, std::string name, std::string description, uint256 srctokenid, std::vector<std::pair<uint8_t, vscript_t>> oprets);
|
||||
CScript EncodeTokenOpRet(uint256 tokenid, std::vector<CPubKey> voutPubkeys, std::pair<uint8_t, vscript_t> opretWithId);
|
||||
CScript EncodeTokenOpRet(uint256 tokenid, std::vector<CPubKey> voutPubkeys, std::vector<std::pair<uint8_t, vscript_t>> oprets);
|
||||
int64_t AddCClibtxfee(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk);
|
||||
uint8_t DecodeTokenCreateOpRet(const CScript &scriptPubKey, std::vector<uint8_t> &origpubkey, std::string &name, std::string &description);
|
||||
uint8_t DecodeTokenCreateOpRet(const CScript &scriptPubKey, std::vector<uint8_t> &origpubkey, std::string &name, std::string &description, std::vector<uint8_t> &vopretNonfungible);
|
||||
uint8_t DecodeTokenOpRet(const CScript scriptPubKey, uint8_t &evalCodeTokens, uint256 &tokenid, std::vector<CPubKey> &voutPubkeys, std::vector<uint8_t> &vopretExtra);
|
||||
void GetNonfungibleData(uint256 tokenid, std::vector<uint8_t> &vopretNonfungible);
|
||||
uint8_t DecodeTokenCreateOpRet(const CScript &scriptPubKey, std::vector<uint8_t> &origpubkey, std::string &name, std::string &description, std::vector<std::pair<uint8_t, vscript_t>> &oprets);
|
||||
uint8_t DecodeTokenImportOpRet(const CScript &scriptPubKey, std::vector<uint8_t> &origpubkey, std::string &name, std::string &description, uint256 &srctokenid, std::vector<std::pair<uint8_t, vscript_t>> &oprets);
|
||||
uint8_t DecodeTokenOpRet(const CScript scriptPubKey, uint8_t &evalCodeTokens, uint256 &tokenid, std::vector<CPubKey> &voutPubkeys, std::vector<std::pair<uint8_t, vscript_t>> &oprets);
|
||||
void GetNonfungibleData(uint256 tokenid, vscript_t &vopretNonfungible);
|
||||
bool ExtractTokensCCVinPubkeys(const CTransaction &tx, std::vector<CPubKey> &vinPubkeys);
|
||||
|
||||
uint8_t DecodeOraclesData(const CScript &scriptPubKey,uint256 &oracletxid,uint256 &batontxid,CPubKey &pk,std::vector <uint8_t>&data);
|
||||
int32_t oracle_format(uint256 *hashp,int64_t *valp,char *str,uint8_t fmt,uint8_t *data,int32_t offset,int32_t datalen);
|
||||
@@ -227,7 +251,7 @@ uint256 revuint256(uint256 txid);
|
||||
bool pubkey2addr(char *destaddr,uint8_t *pubkey33);
|
||||
char *uint256_str(char *dest,uint256 txid);
|
||||
char *pubkey33_str(char *dest,uint8_t *pubkey33);
|
||||
uint256 Parseuint256(char *hexstr);
|
||||
uint256 Parseuint256(const char *hexstr);
|
||||
CPubKey pubkey2pk(std::vector<uint8_t> pubkey);
|
||||
int64_t CCfullsupply(uint256 tokenid);
|
||||
int64_t CCtoken_balance(char *destaddr,uint256 tokenid);
|
||||
|
||||
@@ -34,197 +34,13 @@
|
||||
|
||||
Yes, this is quite confusing...
|
||||
|
||||
In ValudateTokenRemainder the naming convention is nValue is the coin/token with the offer on the books and "units" is what it is being paid in. The high level check is to make sure we didnt lose any coins or tokens, the harder to validate is the actual price paid as the "orderbook" is in terms of the combined nValue for the combined totalunits.
|
||||
In ValidateTokenRemainder the naming convention is nValue is the coin/token with the offer on the books and "units" is what it is being paid in. The high level check is to make sure we didnt lose any coins or tokens, the harder to validate is the actual price paid as the "orderbook" is in terms of the combined nValue for the combined totalunits.
|
||||
|
||||
We assume that the effective unit cost in the orderbook is valid and that that amount was paid and also that any remainder will be close enough in effective unit cost to not matter. At the edge cases, this will probably be not true and maybe some orders wont be practically fillable when reduced to fractional state. However, the original pubkey that created the offer can always reclaim it.
|
||||
------------------------------
|
||||
*/
|
||||
|
||||
|
||||
// NOTE: this inital tx won't be used by other contract
|
||||
// for tokens to be used there should be at least one 't' tx with other contract's custom opret
|
||||
CScript EncodeTokenCreateOpRet(uint8_t funcid, std::vector<uint8_t> origpubkey, std::string name, std::string description, std::vector<uint8_t> vopretNonfungible )
|
||||
{
|
||||
CScript opret;
|
||||
uint8_t evalcode = EVAL_TOKENS;
|
||||
funcid = 'c'; // override the param
|
||||
|
||||
opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << origpubkey << name << description; \
|
||||
if (!vopretNonfungible.empty()) { \
|
||||
ss << (uint8_t)OPRETID_NONFUNGIBLEDATA; \
|
||||
ss << vopretNonfungible; \
|
||||
});
|
||||
return(opret);
|
||||
}
|
||||
|
||||
|
||||
CScript EncodeTokenOpRet(uint256 tokenid, std::vector<CPubKey> voutPubkeys, CScript payload)
|
||||
{
|
||||
CScript opret;
|
||||
uint8_t tokenFuncId = 't';
|
||||
uint8_t evalCodeInOpret = EVAL_TOKENS;
|
||||
|
||||
tokenid = revuint256(tokenid);
|
||||
|
||||
uint8_t ccType = 0;
|
||||
if (voutPubkeys.size() >= 0 && voutPubkeys.size() <= 2)
|
||||
ccType = voutPubkeys.size();
|
||||
else {
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_DEBUG2, stream << "EncodeTokenOpRet voutPubkeys.size()=" << voutPubkeys.size() << " not supported" << std::endl);
|
||||
}
|
||||
|
||||
std::vector<uint8_t> vpayload;
|
||||
GetOpReturnData(payload, vpayload);
|
||||
|
||||
opret << OP_RETURN << E_MARSHAL(ss << evalCodeInOpret << tokenFuncId << tokenid << ccType; \
|
||||
if (ccType >= 1) ss << voutPubkeys[0]; \
|
||||
if (ccType == 2) ss << voutPubkeys[1]; \
|
||||
if (vpayload.size() > 0) ss << vpayload);
|
||||
|
||||
// bad opret cases (retries to attach payload without re-serialization):
|
||||
|
||||
// "error 64: scriptpubkey":
|
||||
// if (payload.size() > 0)
|
||||
// opret += payload;
|
||||
|
||||
// error 64: scriptpubkey:
|
||||
// CScript opretPayloadNoOpcode(vpayload);
|
||||
// return opret + opretPayloadNoOpcode;
|
||||
|
||||
// error sig_aborted:
|
||||
// opret.resize(opret.size() + vpayload.size());
|
||||
// CScript::iterator it = opret.begin() + opret.size();
|
||||
// for (int i = 0; i < vpayload.size(); i++, it++)
|
||||
// *it = vpayload[i];
|
||||
|
||||
return opret;
|
||||
}
|
||||
|
||||
// overload for compatibility
|
||||
CScript EncodeTokenOpRet(uint8_t tokenFuncId, uint8_t evalCodeInOpret, uint256 tokenid, std::vector<CPubKey> voutPubkeys, CScript payload)
|
||||
{
|
||||
return EncodeTokenOpRet(tokenid, voutPubkeys, payload);
|
||||
}
|
||||
|
||||
// overload for fungible:
|
||||
uint8_t DecodeTokenCreateOpRet(const CScript &scriptPubKey, std::vector<uint8_t> &origpubkey, std::string &name, std::string &description) {
|
||||
std::vector<uint8_t> vopretNonfungibleDummy;
|
||||
return DecodeTokenCreateOpRet(scriptPubKey, origpubkey, name, description, vopretNonfungibleDummy);
|
||||
}
|
||||
|
||||
uint8_t DecodeTokenCreateOpRet(const CScript &scriptPubKey,std::vector<uint8_t> &origpubkey,std::string &name,std::string &description, std::vector<uint8_t> &vopretNonfungible)
|
||||
{
|
||||
std::vector<uint8_t> vopret; uint8_t dummyEvalcode, funcid, *script, fieldId = 0;
|
||||
|
||||
GetOpReturnData(scriptPubKey, vopret);
|
||||
script = (uint8_t *)vopret.data();
|
||||
|
||||
if ( script != 0 && vopret.size() > 2 && script[0] == EVAL_TOKENS && script[1] == 'c' )
|
||||
{
|
||||
if (E_UNMARSHAL(vopret, ss >> dummyEvalcode; ss >> funcid; ss >> origpubkey; ss >> name; ss >> description; \
|
||||
// we suppose in 'c' opret it might be only non-fungible payload and not any assets/heir/etc payloads
|
||||
if (!ss.eof()) { \
|
||||
ss >> fieldId; \
|
||||
if( fieldId == OPRETID_NONFUNGIBLEDATA ) \
|
||||
ss >> vopretNonfungible; \
|
||||
}))
|
||||
return(funcid);
|
||||
}
|
||||
return (uint8_t)0;
|
||||
}
|
||||
|
||||
// overload for compatibility allows only usual fungible tokens:
|
||||
// warning: it makes vopret marshalling to CScript because this is what caller would expect
|
||||
/*uint8_t DecodeTokenOpRet(const CScript scriptPubKey, uint8_t &evalCode, uint256 &tokenid, std::vector<CPubKey> &voutPubkeys, std::vector<uint8_t> &vopretExtra) {
|
||||
std::vector<uint8_t> vopret1, vopret2;
|
||||
uint8_t funcId = DecodeTokenOpRet(scriptPubKey, evalCode, tokenid, voutPubkeys, vopret1, vopret2);
|
||||
|
||||
CScript opretExtra;
|
||||
vopretExtra.clear();
|
||||
|
||||
// make marshalling for compatibility
|
||||
// callers of this func expect length of full array at the beginning (and they will make 'vopretStripped' from vopretExtra)
|
||||
if (vopret2.empty())
|
||||
opretExtra << OP_RETURN << E_MARSHAL(ss << vopret1); // if first opret (or no oprets)
|
||||
else
|
||||
opretExtra << OP_RETURN << E_MARSHAL(ss << vopret2); // if both oprets present, return assets/heir/gateways/... opret (dump non-fungible opret)
|
||||
|
||||
GetOpReturnData(opretExtra, vopretExtra);
|
||||
return funcId;
|
||||
} */
|
||||
|
||||
// decodes token opret:
|
||||
// for 't' returns all data from opret, vopretExtra contains other contract's data (currently only assets').
|
||||
// for 'c' returns only funcid. NOTE: nonfungible data is not returned
|
||||
uint8_t DecodeTokenOpRet(const CScript scriptPubKey, uint8_t &evalCodeTokens, uint256 &tokenid, std::vector<CPubKey> &voutPubkeys, std::vector<uint8_t> &vopretExtra)
|
||||
{
|
||||
std::vector<uint8_t> vopret, extra, dummyPubkey, vnonfungibleDummy;
|
||||
uint8_t funcId=0, *script, dummyEvalCode, dummyFuncId, ccType, fieldId = 0;
|
||||
std::string dummyName; std::string dummyDescription;
|
||||
CPubKey voutPubkey1, voutPubkey2;
|
||||
|
||||
GetOpReturnData(scriptPubKey, vopret);
|
||||
script = (uint8_t *)vopret.data();
|
||||
tokenid = zeroid;
|
||||
vopretExtra.clear();
|
||||
|
||||
if (script != NULL && vopret.size() > 2)
|
||||
{
|
||||
// NOTE: if parse error occures, parse might not be able to set error. It is safer to treat that it was eof if it is not set!
|
||||
bool isEof = true;
|
||||
|
||||
evalCodeTokens = script[0];
|
||||
if (evalCodeTokens != EVAL_TOKENS)
|
||||
return (uint8_t)0;
|
||||
|
||||
funcId = script[1];
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_DEBUG2, stream << "DecodeTokenOpRet decoded funcId=" << (char)(funcId?funcId:' ') << std::endl);
|
||||
|
||||
switch( funcId )
|
||||
{
|
||||
case 'c':
|
||||
return DecodeTokenCreateOpRet(scriptPubKey, dummyPubkey, dummyName, dummyDescription, vnonfungibleDummy);
|
||||
//break;
|
||||
case 't':
|
||||
//not used yet: case 'l':
|
||||
// NOTE: 'E_UNMARSHAL result==false' means 'parse error' OR 'not eof state'. Consequently, 'result==false' but 'isEof==true' means just 'parse error'
|
||||
if (E_UNMARSHAL(vopret, ss >> dummyEvalCode; ss >> dummyFuncId; ss >> tokenid; ss >> ccType; \
|
||||
if (ccType >= 1) ss >> voutPubkey1; \
|
||||
if (ccType == 2) ss >> voutPubkey2; \
|
||||
isEof = ss.eof(); \
|
||||
if (!isEof) ss >> vopretExtra; \
|
||||
// if something else remains -> bad format
|
||||
isEof = ss.eof()) || !isEof)
|
||||
{
|
||||
|
||||
if (!(ccType >= 0 && ccType <= 2)) { //incorrect ccType
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "DecodeTokenOpRet() incorrect ccType=" << (int)ccType << " tokenid=" << revuint256(tokenid).GetHex() << std::endl);
|
||||
return (uint8_t)0;
|
||||
}
|
||||
|
||||
// add verification pubkeys:
|
||||
voutPubkeys.clear();
|
||||
if (voutPubkey1.IsValid())
|
||||
voutPubkeys.push_back(voutPubkey1);
|
||||
if (voutPubkey2.IsValid())
|
||||
voutPubkeys.push_back(voutPubkey2);
|
||||
|
||||
tokenid = revuint256(tokenid);
|
||||
return(funcId);
|
||||
}
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "DecodeTokenOpRet() bad opret format, isEof=" << isEof << " ccType=" << ccType << " tokenid=" << revuint256(tokenid).GetHex() << std::endl);
|
||||
return (uint8_t)0;
|
||||
|
||||
default:
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "DecodeTokenOpRet() illegal funcid=" << (int)funcId << std::endl);
|
||||
return (uint8_t)0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "DecodeTokenOpRet() empty opret, could not parse" << std::endl);
|
||||
}
|
||||
return (uint8_t)0;
|
||||
}
|
||||
|
||||
// tx validation
|
||||
bool TokensValidate(struct CCcontract_info *cp, Eval* eval, const CTransaction &tx, uint32_t nIn)
|
||||
@@ -233,7 +49,8 @@ bool TokensValidate(struct CCcontract_info *cp, Eval* eval, const CTransaction &
|
||||
CTxDestination address; CTransaction vinTx, createTx; uint256 hashBlock, tokenid, tokenid2;
|
||||
int32_t i, starti, numvins, numvouts, preventCCvins, preventCCvouts;
|
||||
int64_t remaining_price, nValue, tokenoshis, outputs, inputs, tmpprice, totalunits, ignore;
|
||||
std::vector<uint8_t> vopretExtra, tmporigpubkey, ignorepubkey;
|
||||
std::vector<std::pair<uint8_t, vscript_t>> oprets;
|
||||
vscript_t /*vopretExtra,*/ tmporigpubkey, ignorepubkey;
|
||||
uint8_t funcid, evalCodeInOpret;
|
||||
char destaddr[64], origaddr[64], CCaddr[64];
|
||||
std::vector<CPubKey> voutTokenPubkeys, vinTokenPubkeys;
|
||||
@@ -250,7 +67,7 @@ bool TokensValidate(struct CCcontract_info *cp, Eval* eval, const CTransaction &
|
||||
if (numvouts < 1)
|
||||
return eval->Invalid("no vouts");
|
||||
|
||||
if ((funcid = DecodeTokenOpRet(tx.vout[numvouts - 1].scriptPubKey, evalCodeInOpret, tokenid, voutTokenPubkeys, vopretExtra)) == 0)
|
||||
if ((funcid = DecodeTokenOpRet(tx.vout[numvouts - 1].scriptPubKey, evalCodeInOpret, tokenid, voutTokenPubkeys, oprets)) == 0)
|
||||
return eval->Invalid("TokenValidate: invalid opreturn payload");
|
||||
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "TokensValidate funcId=" << (char)(funcid?funcid:' ') << " evalcode=" << std::hex << (int)cp->evalcode << std::endl);
|
||||
@@ -272,11 +89,11 @@ bool TokensValidate(struct CCcontract_info *cp, Eval* eval, const CTransaction &
|
||||
}
|
||||
|
||||
// validate spending from token cc addr: allowed only for burned non-fungible tokens:
|
||||
if (ExtractTokensVinPubkeys(tx, vinTokenPubkeys) && std::find(vinTokenPubkeys.begin(), vinTokenPubkeys.end(), GetUnspendable(cp, NULL)) != vinTokenPubkeys.end()) {
|
||||
if (ExtractTokensCCVinPubkeys(tx, vinTokenPubkeys) && std::find(vinTokenPubkeys.begin(), vinTokenPubkeys.end(), GetUnspendable(cp, NULL)) != vinTokenPubkeys.end()) {
|
||||
// validate spending from token unspendable cc addr:
|
||||
int64_t burnedAmount = HasBurnedTokensvouts(cp, eval, tx, tokenid);
|
||||
if (burnedAmount > 0) {
|
||||
std::vector<uint8_t> vopretNonfungible;
|
||||
vscript_t vopretNonfungible;
|
||||
GetNonfungibleData(tokenid, vopretNonfungible);
|
||||
if( vopretNonfungible.empty() )
|
||||
return eval->Invalid("spending cc marker not supported for fungible tokens");
|
||||
@@ -331,13 +148,14 @@ bool TokensValidate(struct CCcontract_info *cp, Eval* eval, const CTransaction &
|
||||
// helper funcs:
|
||||
|
||||
// extract cc token vins' pubkeys:
|
||||
bool ExtractTokensVinPubkeys(CTransaction tx, std::vector<CPubKey> &vinPubkeys) {
|
||||
bool ExtractTokensCCVinPubkeys(const CTransaction &tx, std::vector<CPubKey> &vinPubkeys) {
|
||||
|
||||
bool found = false;
|
||||
CPubKey pubkey;
|
||||
struct CCcontract_info *cpTokens, tokensC;
|
||||
|
||||
cpTokens = CCinit(&tokensC, EVAL_TOKENS);
|
||||
vinPubkeys.clear();
|
||||
|
||||
for (int32_t i = 0; i < tx.vin.size(); i++)
|
||||
{
|
||||
@@ -384,7 +202,7 @@ uint8_t ValidateTokenOpret(CTransaction tx, uint256 tokenid) {
|
||||
uint8_t funcid;
|
||||
uint8_t dummyEvalCode;
|
||||
std::vector<CPubKey> voutPubkeysDummy;
|
||||
std::vector<uint8_t> vopretExtraDummy;
|
||||
std::vector<std::pair<uint8_t, vscript_t>> opretsDummy;
|
||||
|
||||
// this is just for log messages indentation fur debugging recursive calls:
|
||||
std::string indentStr = std::string().append(tokenValIndentSize, '.');
|
||||
@@ -392,7 +210,7 @@ uint8_t ValidateTokenOpret(CTransaction tx, uint256 tokenid) {
|
||||
if (tx.vout.size() == 0)
|
||||
return (uint8_t)0;
|
||||
|
||||
if ((funcid = DecodeTokenOpRet(tx.vout.back().scriptPubKey, dummyEvalCode, tokenidOpret, voutPubkeysDummy, vopretExtraDummy)) == 0)
|
||||
if ((funcid = DecodeTokenOpRet(tx.vout.back().scriptPubKey, dummyEvalCode, tokenidOpret, voutPubkeysDummy, opretsDummy)) == 0)
|
||||
{
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << indentStr << "ValidateTokenOpret() DecodeTokenOpret could not parse opret for txid=" << tx.GetHash().GetHex() << std::endl);
|
||||
return (uint8_t)0;
|
||||
@@ -400,13 +218,23 @@ uint8_t ValidateTokenOpret(CTransaction tx, uint256 tokenid) {
|
||||
else if (funcid == 'c')
|
||||
{
|
||||
if (tokenid != zeroid && tokenid == tx.GetHash()) {
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_DEBUG1, stream << indentStr << "ValidateTokenOpret() this is the tokenbase 'c' tx, txid=" << tx.GetHash().GetHex() << " returning true" << std::endl);
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_DEBUG1, stream << indentStr << "ValidateTokenOpret() this is tokenbase 'c' tx, txid=" << tx.GetHash().GetHex() << " returning true" << std::endl);
|
||||
return funcid;
|
||||
}
|
||||
else {
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_DEBUG1, stream << indentStr << "ValidateTokenOpret() not my tokenbase txid=" << tx.GetHash().GetHex() << std::endl);
|
||||
}
|
||||
}
|
||||
else if (funcid == 'i')
|
||||
{
|
||||
if (tokenid != zeroid && tokenid == tx.GetHash()) {
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_DEBUG1, stream << indentStr << "ValidateTokenOpret() this is import 'i' tx, txid=" << tx.GetHash().GetHex() << " returning true" << std::endl);
|
||||
return funcid;
|
||||
}
|
||||
else {
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_DEBUG1, stream << indentStr << "ValidateTokenOpret() not my import txid=" << tx.GetHash().GetHex() << std::endl);
|
||||
}
|
||||
}
|
||||
else if (funcid == 't')
|
||||
{
|
||||
//std::cerr << indentStr << "ValidateTokenOpret() tokenid=" << tokenid.GetHex() << " tokenIdOpret=" << tokenidOpret.GetHex() << " txid=" << tx.GetHash().GetHex() << std::endl;
|
||||
@@ -425,17 +253,31 @@ uint8_t ValidateTokenOpret(CTransaction tx, uint256 tokenid) {
|
||||
}
|
||||
|
||||
// remove token->unspendablePk (it is only for marker usage)
|
||||
std::vector<CPubKey> FilterOutTokensUnspendablePk(std::vector<CPubKey> sourcePubkeys) {
|
||||
void FilterOutTokensUnspendablePk(const std::vector<CPubKey> &sourcePubkeys, std::vector<CPubKey> &destPubkeys) {
|
||||
struct CCcontract_info *cpTokens, tokensC;
|
||||
cpTokens = CCinit(&tokensC, EVAL_TOKENS);
|
||||
CPubKey tokensUnspendablePk = GetUnspendable(cpTokens, NULL);
|
||||
std::vector<CPubKey> destPubkeys;
|
||||
destPubkeys.clear();
|
||||
|
||||
for (auto pk : sourcePubkeys)
|
||||
if (pk != tokensUnspendablePk)
|
||||
destPubkeys.push_back(pk);
|
||||
|
||||
return destPubkeys;
|
||||
}
|
||||
|
||||
void FilterOutNonCCOprets(const std::vector<std::pair<uint8_t, vscript_t>> &oprets, vscript_t &vopret) {
|
||||
|
||||
vopret.clear();
|
||||
|
||||
if (oprets.size() > 2)
|
||||
LOGSTREAM("cctokens", CCLOG_INFO, stream << "FilterOutNonCCOprets() warning!! oprets.size > 2 currently not supported" << oprets.size() << std::endl);
|
||||
|
||||
for (auto o : oprets) {
|
||||
if (o.first < OPRETID_FIRSTNONCCDATA) { // skip burn, import, etc opret data
|
||||
vopret = o.second; // return first contract opret (more than 1 is not supported yet)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Checks if the vout is a really Tokens CC vout
|
||||
@@ -488,7 +330,8 @@ int64_t IsTokensvout(bool goDeeper, bool checkPubkeys /*<--not used, always true
|
||||
uint8_t dummyEvalCode;
|
||||
uint256 tokenIdOpret;
|
||||
std::vector<CPubKey> voutPubkeys, voutPubkeysInOpret;
|
||||
std::vector<uint8_t> vopretExtra, vopretNonfungible;
|
||||
vscript_t vopretExtra, vopretNonfungible;
|
||||
std::vector<std::pair<uint8_t, vscript_t>> oprets;
|
||||
|
||||
uint8_t evalCode = EVAL_TOKENS; // if both payloads are empty maybe it is a transfer to non-payload-one-eval-token vout like GatewaysClaim
|
||||
uint8_t evalCode2 = 0; // will be checked if zero or not
|
||||
@@ -496,12 +339,16 @@ int64_t IsTokensvout(bool goDeeper, bool checkPubkeys /*<--not used, always true
|
||||
// test vouts for possible token use-cases:
|
||||
std::vector<std::pair<CTxOut, std::string>> testVouts;
|
||||
|
||||
DecodeTokenOpRet(tx.vout.back().scriptPubKey, dummyEvalCode, tokenIdOpret, voutPubkeysInOpret, vopretExtra);
|
||||
DecodeTokenOpRet(tx.vout.back().scriptPubKey, dummyEvalCode, tokenIdOpret, voutPubkeysInOpret, oprets);
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_DEBUG2, stream << "IsTokensvout() oprets.size()=" << oprets.size() << std::endl);
|
||||
|
||||
// get assets/channels/gateways token data:
|
||||
FilterOutNonCCOprets(oprets, vopretExtra); // NOTE: only 1 additional evalcode in token opret is currently supported
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_DEBUG2, stream << "IsTokensvout() vopretExtra=" << HexStr(vopretExtra) << std::endl);
|
||||
|
||||
// get non-fungible data
|
||||
GetNonfungibleData(reftokenid, vopretNonfungible);
|
||||
|
||||
voutPubkeys = FilterOutTokensUnspendablePk(voutPubkeysInOpret); // cannot send tokens to token unspendable cc addr (only marker is allowed there)
|
||||
FilterOutTokensUnspendablePk(voutPubkeysInOpret, voutPubkeys); // cannot send tokens to token unspendable cc addr (only marker is allowed there)
|
||||
|
||||
// NOTE: evalcode order in vouts is important:
|
||||
// non-fungible-eval -> EVAL_TOKENS -> assets-eval
|
||||
@@ -512,7 +359,7 @@ int64_t IsTokensvout(bool goDeeper, bool checkPubkeys /*<--not used, always true
|
||||
evalCode2 = vopretExtra.begin()[0];
|
||||
|
||||
if (evalCode == EVAL_TOKENS && evalCode2 != 0) {
|
||||
evalCode = evalCode2;
|
||||
evalCode = evalCode2; // for using MakeTokensCC1vout(evalcode,...) instead of MakeCC1vout(EVAL_TOKENS, evalcode...)
|
||||
evalCode2 = 0;
|
||||
}
|
||||
|
||||
@@ -562,8 +409,8 @@ int64_t IsTokensvout(bool goDeeper, bool checkPubkeys /*<--not used, always true
|
||||
|
||||
// maybe it is single-eval or dual/three-eval token change?
|
||||
std::vector<CPubKey> vinPubkeys, vinPubkeysUnfiltered;
|
||||
ExtractTokensVinPubkeys(tx, vinPubkeysUnfiltered);
|
||||
vinPubkeys = FilterOutTokensUnspendablePk(vinPubkeysUnfiltered); // cannot send tokens to token unspendable cc addr (only marker is allowed there)
|
||||
ExtractTokensCCVinPubkeys(tx, vinPubkeysUnfiltered);
|
||||
FilterOutTokensUnspendablePk(vinPubkeysUnfiltered, vinPubkeys); // cannot send tokens to token unspendable cc addr (only marker is allowed there)
|
||||
|
||||
for(std::vector<CPubKey>::iterator it = vinPubkeys.begin(); it != vinPubkeys.end(); it++) {
|
||||
testVouts.push_back(std::make_pair(MakeCC1vout(EVAL_TOKENS, tx.vout[v].nValue, *it), std::string("single-eval cc1 self vin pk")));
|
||||
@@ -577,11 +424,11 @@ int64_t IsTokensvout(bool goDeeper, bool checkPubkeys /*<--not used, always true
|
||||
}
|
||||
else {
|
||||
CPubKey origPubkey;
|
||||
std::vector<uint8_t> vorigPubkey;
|
||||
vscript_t vorigPubkey;
|
||||
std::string dummyName, dummyDescription;
|
||||
std::vector<uint8_t> vopret1;
|
||||
std::vector<std::pair<uint8_t, vscript_t>> oprets;
|
||||
|
||||
if (DecodeTokenCreateOpRet(tx.vout.back().scriptPubKey, vorigPubkey, dummyName, dummyDescription, vopret1) == 0) {
|
||||
if (DecodeTokenCreateOpRet(tx.vout.back().scriptPubKey, vorigPubkey, dummyName, dummyDescription, oprets) == 0) {
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << indentStr << "IsTokensvout() could not decode create opret" << " for txid=" << tx.GetHash().GetHex() << " for tokenid=" << reftokenid.GetHex() << std::endl);
|
||||
return 0;
|
||||
}
|
||||
@@ -689,7 +536,7 @@ bool TokensExactAmounts(bool goDeeper, struct CCcontract_info *cp, int64_t &inpu
|
||||
|
||||
|
||||
// get non-fungible data from 'tokenbase' tx (the data might be empty)
|
||||
void GetNonfungibleData(uint256 tokenid, std::vector<uint8_t> &vopretNonfungible)
|
||||
void GetNonfungibleData(uint256 tokenid, vscript_t &vopretNonfungible)
|
||||
{
|
||||
CTransaction tokenbasetx;
|
||||
uint256 hashBlock;
|
||||
@@ -704,22 +551,24 @@ void GetNonfungibleData(uint256 tokenid, std::vector<uint8_t> &vopretNonfungible
|
||||
if (tokenbasetx.vout.size() > 0) {
|
||||
std::vector<uint8_t> origpubkey;
|
||||
std::string name, description;
|
||||
std::vector<uint8_t> vopretExtra;
|
||||
if (DecodeTokenCreateOpRet(tokenbasetx.vout.back().scriptPubKey, origpubkey, name, description, vopretExtra) == 'c')
|
||||
vopretNonfungible = vopretExtra;
|
||||
std::vector<std::pair<uint8_t, vscript_t>> oprets;
|
||||
|
||||
if (DecodeTokenCreateOpRet(tokenbasetx.vout.back().scriptPubKey, origpubkey, name, description, oprets) == 'c') {
|
||||
GetOpretBlob(oprets, OPRETID_NONFUNGIBLEDATA, vopretNonfungible);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// overload, adds inputs from token cc addr
|
||||
int64_t AddTokenCCInputs(struct CCcontract_info *cp, CMutableTransaction &mtx, CPubKey pk, uint256 tokenid, int64_t total, int32_t maxinputs) {
|
||||
std::vector<uint8_t> vopretNonfungibleDummy;
|
||||
vscript_t vopretNonfungibleDummy;
|
||||
return AddTokenCCInputs(cp, mtx, pk, tokenid, total, maxinputs, vopretNonfungibleDummy);
|
||||
}
|
||||
|
||||
// adds inputs from token cc addr and returns non-fungible opret payload if present
|
||||
// also sets evalcode in cp, if needed
|
||||
int64_t AddTokenCCInputs(struct CCcontract_info *cp, CMutableTransaction &mtx, CPubKey pk, uint256 tokenid, int64_t total, int32_t maxinputs, std::vector<uint8_t> &vopretNonfungible)
|
||||
int64_t AddTokenCCInputs(struct CCcontract_info *cp, CMutableTransaction &mtx, CPubKey pk, uint256 tokenid, int64_t total, int32_t maxinputs, vscript_t &vopretNonfungible)
|
||||
{
|
||||
char tokenaddr[64], destaddr[64];
|
||||
int64_t threshold, nValue, price, totalinputs = 0;
|
||||
@@ -737,8 +586,7 @@ int64_t AddTokenCCInputs(struct CCcontract_info *cp, CMutableTransaction &mtx, C
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "AddTokenCCInputs() no utxos for token dual/three eval addr=" << tokenaddr << " evalcode=" << (int)cp->evalcode << " additionalTokensEvalcode2=" << (int)cp->additionalTokensEvalcode2 << std::endl);
|
||||
}
|
||||
|
||||
threshold = total / (maxinputs != 0 ? maxinputs : 64); // TODO: maxinputs really could not be over 64? what if i want to calc total balance for all available uxtos?
|
||||
// maybe it is better to add all uxtos if maxinputs == 0
|
||||
threshold = total / (maxinputs != 0 ? maxinputs : CC_MAXVINS);
|
||||
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it = unspentOutputs.begin(); it != unspentOutputs.end(); it++)
|
||||
{
|
||||
@@ -771,7 +619,7 @@ int64_t AddTokenCCInputs(struct CCcontract_info *cp, CMutableTransaction &mtx, C
|
||||
{
|
||||
//for non-fungible tokens check payload:
|
||||
if (!vopretNonfungible.empty()) {
|
||||
std::vector<uint8_t> vopret;
|
||||
vscript_t vopret;
|
||||
|
||||
// check if it is non-fungible token:
|
||||
GetNonfungibleData(tokenid, vopret);
|
||||
@@ -807,7 +655,8 @@ int64_t HasBurnedTokensvouts(struct CCcontract_info *cp, Eval* eval, const CTran
|
||||
uint8_t dummyEvalCode;
|
||||
uint256 tokenIdOpret;
|
||||
std::vector<CPubKey> voutPubkeys, voutPubkeysDummy;
|
||||
std::vector<uint8_t> vopretExtra, vopretNonfungible;
|
||||
std::vector<std::pair<uint8_t, vscript_t>> oprets;
|
||||
vscript_t vopretExtra, vopretNonfungible;
|
||||
|
||||
uint8_t evalCode = EVAL_TOKENS; // if both payloads are empty maybe it is a transfer to non-payload-one-eval-token vout like GatewaysClaim
|
||||
uint8_t evalCode2 = 0; // will be checked if zero or not
|
||||
@@ -823,11 +672,14 @@ int64_t HasBurnedTokensvouts(struct CCcontract_info *cp, Eval* eval, const CTran
|
||||
}
|
||||
|
||||
|
||||
if (DecodeTokenOpRet(tx.vout.back().scriptPubKey, dummyEvalCode, tokenIdOpret, voutPubkeysDummy, vopretExtra) == 0) {
|
||||
if (DecodeTokenOpRet(tx.vout.back().scriptPubKey, dummyEvalCode, tokenIdOpret, voutPubkeysDummy, oprets) == 0) {
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "HasBurnedTokensvouts() cannot parse opret DecodeTokenOpRet returned 0, txid=" << tx.GetHash().GetHex() << std::endl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get assets/channels/gateways token data:
|
||||
FilterOutNonCCOprets(oprets, vopretExtra); // NOTE: only 1 additional evalcode in token opret is currently supported
|
||||
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_DEBUG2, stream << "HasBurnedTokensvouts() vopretExtra=" << HexStr(vopretExtra) << std::endl);
|
||||
|
||||
GetNonfungibleData(reftokenid, vopretNonfungible);
|
||||
@@ -874,18 +726,40 @@ int64_t HasBurnedTokensvouts(struct CCcontract_info *cp, Eval* eval, const CTran
|
||||
return burnedAmount;
|
||||
}
|
||||
|
||||
std::string CreateToken(int64_t txfee, int64_t tokensupply, std::string name, std::string description, std::vector<uint8_t> nonfungibleData)
|
||||
CPubKey GetTokenOriginatorPubKey(CScript scriptPubKey) {
|
||||
|
||||
uint8_t funcId, evalCode;
|
||||
uint256 tokenid;
|
||||
std::vector<CPubKey> voutTokenPubkeys;
|
||||
std::vector<std::pair<uint8_t, vscript_t>> oprets;
|
||||
|
||||
if ((funcId = DecodeTokenOpRet(scriptPubKey, evalCode, tokenid, voutTokenPubkeys, oprets)) != 0) {
|
||||
CTransaction tokenbasetx;
|
||||
uint256 hashBlock;
|
||||
|
||||
if (myGetTransaction(tokenid, tokenbasetx, hashBlock) && tokenbasetx.vout.size() > 0) {
|
||||
vscript_t vorigpubkey;
|
||||
std::string name, desc;
|
||||
if (DecodeTokenCreateOpRet(tokenbasetx.vout.back().scriptPubKey, vorigpubkey, name, desc) != 0)
|
||||
return pubkey2pk(vorigpubkey);
|
||||
}
|
||||
}
|
||||
return CPubKey(); //return invalid pubkey
|
||||
}
|
||||
|
||||
|
||||
std::string CreateToken(int64_t txfee, int64_t tokensupply, std::string name, std::string description, vscript_t nonfungibleData)
|
||||
{
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk; struct CCcontract_info *cp, C;
|
||||
if (tokensupply < 0)
|
||||
{
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "CreateToken() negative tokensupply=" << tokensupply << std::endl);
|
||||
if (tokensupply < 0) {
|
||||
CCerror = "negative tokensupply";
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "CreateToken() =" << CCerror << "=" << tokensupply << std::endl);
|
||||
return std::string("");
|
||||
}
|
||||
if (!nonfungibleData.empty() && tokensupply != 1) {
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "CreateToken() for non-fungible tokens tokensupply should be equal to 1" << std::endl);
|
||||
CCerror = "for non-fungible tokens tokensupply should be equal to 1";
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "CreateToken() " << CCerror << std::endl);
|
||||
return std::string("");
|
||||
}
|
||||
|
||||
@@ -893,8 +767,8 @@ std::string CreateToken(int64_t txfee, int64_t tokensupply, std::string name, st
|
||||
cp = CCinit(&C, EVAL_TOKENS);
|
||||
if (name.size() > 32 || description.size() > 4096) // this is also checked on rpc level
|
||||
{
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "name of=" << name.size() << " or description of=" << description.size() << " is too big" << std::endl);
|
||||
CCerror = "name should be < 32, description should be < 4096";
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "name len=" << name.size() << " or description len=" << description.size() << " is too big" << std::endl);
|
||||
CCerror = "name should be <= 32, description should be <= 4096";
|
||||
return("");
|
||||
}
|
||||
if (txfee == 0)
|
||||
@@ -916,21 +790,22 @@ std::string CreateToken(int64_t txfee, int64_t tokensupply, std::string name, st
|
||||
return(FinalizeCCTx(0, cp, mtx, mypk, txfee, EncodeTokenCreateOpRet('c', Mypubkey(), name, description, nonfungibleData)));
|
||||
}
|
||||
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "cant find normal inputs" << std::endl);
|
||||
CCerror = "cant find normal inputs";
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "CreateToken() " << CCerror << std::endl);
|
||||
return std::string("");
|
||||
}
|
||||
|
||||
// transfer tokens to another pubkey
|
||||
// param additionalEvalCode allows transfer of dual-eval non-fungible tokens
|
||||
std::string TokenTransfer(int64_t txfee, uint256 tokenid, std::vector<uint8_t> destpubkey, int64_t total)
|
||||
std::string TokenTransfer(int64_t txfee, uint256 tokenid, vscript_t destpubkey, int64_t total)
|
||||
{
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk; uint64_t mask; int64_t CCchange = 0, inputs = 0; struct CCcontract_info *cp, C;
|
||||
std::vector<uint8_t> vopretNonfungible;
|
||||
vscript_t vopretNonfungible, vopretEmpty;
|
||||
|
||||
if (total < 0) {
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "negative total=" << total << std::endl);
|
||||
CCerror = strprintf("negative total");
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << CCerror << "=" << total << std::endl);
|
||||
return("");
|
||||
}
|
||||
|
||||
@@ -946,8 +821,8 @@ std::string TokenTransfer(int64_t txfee, uint256 tokenid, std::vector<uint8_t> d
|
||||
if ((inputs = AddTokenCCInputs(cp, mtx, mypk, tokenid, total, 60, vopretNonfungible)) > 0) // NOTE: AddTokenCCInputs might set cp->additionalEvalCode which is used in FinalizeCCtx!
|
||||
{
|
||||
if (inputs < total) { //added dimxy
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "TokenTransfer(): insufficient token funds" << std::endl);
|
||||
CCerror = strprintf("insufficient token inputs");
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "TokenTransfer() " << CCerror << std::endl);
|
||||
return std::string("");
|
||||
}
|
||||
|
||||
@@ -964,17 +839,17 @@ std::string TokenTransfer(int64_t txfee, uint256 tokenid, std::vector<uint8_t> d
|
||||
std::vector<CPubKey> voutTokenPubkeys;
|
||||
voutTokenPubkeys.push_back(pubkey2pk(destpubkey)); // dest pubkey for validating vout
|
||||
|
||||
return(FinalizeCCTx(mask, cp, mtx, mypk, txfee, EncodeTokenOpRet(tokenid, voutTokenPubkeys, CScript())));
|
||||
return FinalizeCCTx(mask, cp, mtx, mypk, txfee, EncodeTokenOpRet(tokenid, voutTokenPubkeys, std::make_pair((uint8_t)0, vopretEmpty)));
|
||||
}
|
||||
else {
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "not enough CC token inputs for amount=" << total << std::endl);
|
||||
CCerror = strprintf("no token inputs");
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "TokenTransfer() " << CCerror << total << std::endl);
|
||||
}
|
||||
//} else fprintf(stderr,"numoutputs.%d != numamounts.%d\n",n,(int32_t)amounts.size());
|
||||
}
|
||||
else {
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "not enough normal inputs for txfee" << std::endl);
|
||||
CCerror = strprintf("insufficient normal inputs");
|
||||
CCerror = strprintf("insufficient normal inputs for tx fee");
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "TokenTransfer() " << CCerror << std::endl);
|
||||
}
|
||||
return("");
|
||||
}
|
||||
@@ -1007,7 +882,8 @@ UniValue TokenInfo(uint256 tokenid)
|
||||
uint256 hashBlock;
|
||||
CTransaction vintx;
|
||||
std::vector<uint8_t> origpubkey;
|
||||
std::vector<uint8_t> vopretNonfungible;
|
||||
std::vector<std::pair<uint8_t, vscript_t>> oprets;
|
||||
vscript_t vopretNonfungible;
|
||||
std::string name, description;
|
||||
struct CCcontract_info *cpTokens, tokensCCinfo;
|
||||
|
||||
@@ -1020,7 +896,7 @@ UniValue TokenInfo(uint256 tokenid)
|
||||
result.push_back(Pair("error", "cant find tokenid"));
|
||||
return(result);
|
||||
}
|
||||
if (vintx.vout.size() > 0 && DecodeTokenCreateOpRet(vintx.vout[vintx.vout.size() - 1].scriptPubKey, origpubkey, name, description, vopretNonfungible) == 0)
|
||||
if (vintx.vout.size() > 0 && DecodeTokenCreateOpRet(vintx.vout[vintx.vout.size() - 1].scriptPubKey, origpubkey, name, description, oprets) != 'c')
|
||||
{
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "TokenInfo() passed tokenid isnt token creation txid" << std::endl);
|
||||
result.push_back(Pair("result", "error"));
|
||||
@@ -1038,6 +914,8 @@ UniValue TokenInfo(uint256 tokenid)
|
||||
supply += output;
|
||||
result.push_back(Pair("supply", supply));
|
||||
result.push_back(Pair("description", description));
|
||||
|
||||
GetOpretBlob(oprets, OPRETID_NONFUNGIBLEDATA, vopretNonfungible);
|
||||
if( !vopretNonfungible.empty() )
|
||||
result.push_back(Pair("data", HexStr(vopretNonfungible)));
|
||||
|
||||
|
||||
@@ -30,8 +30,8 @@ bool TokensValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx
|
||||
bool TokensExactAmounts(bool goDeeper, struct CCcontract_info *cpTokens, int64_t &inputs, int64_t &outputs, Eval* eval, const CTransaction &tx, uint256 tokenid);
|
||||
std::string CreateToken(int64_t txfee, int64_t assetsupply, std::string name, std::string description, std::vector<uint8_t> nonfungibleData);
|
||||
std::string TokenTransfer(int64_t txfee, uint256 assetid, std::vector<uint8_t> destpubkey, int64_t total);
|
||||
bool ExtractTokensVinPubkeys(CTransaction tx, std::vector<CPubKey> &vinPubkeys);
|
||||
int64_t HasBurnedTokensvouts(struct CCcontract_info *cp, Eval* eval, const CTransaction& tx, uint256 reftokenid);
|
||||
CPubKey GetTokenOriginatorPubKey(CScript scriptPubKey);
|
||||
|
||||
int64_t GetTokenBalance(CPubKey pk, uint256 tokenid);
|
||||
UniValue TokenInfo(uint256 tokenid);
|
||||
|
||||
296
src/cc/CCtokensOpRet.cpp
Normal file
296
src/cc/CCtokensOpRet.cpp
Normal file
@@ -0,0 +1,296 @@
|
||||
// encode decode tokens opret
|
||||
// (moved to a separate file to enable linking lib common.so with importcoin.cpp)
|
||||
|
||||
#include "CCtokens.h"
|
||||
|
||||
#ifndef IS_CHARINSTR
|
||||
#define IS_CHARINSTR(c, str) (std::string(str).find((char)(c)) != std::string::npos)
|
||||
#endif
|
||||
|
||||
// NOTE: this inital tx won't be used by other contract
|
||||
// for tokens to be used there should be at least one 't' tx with other contract's custom opret
|
||||
CScript EncodeTokenCreateOpRet(uint8_t funcid, std::vector<uint8_t> origpubkey, std::string name, std::string description, vscript_t vopretNonfungible)
|
||||
{
|
||||
/* CScript opret;
|
||||
uint8_t evalcode = EVAL_TOKENS;
|
||||
funcid = 'c'; // override the param
|
||||
|
||||
opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << origpubkey << name << description; \
|
||||
if (!vopretNonfungible.empty()) {
|
||||
ss << (uint8_t)OPRETID_NONFUNGIBLEDATA;
|
||||
ss << vopretNonfungible;
|
||||
}); */
|
||||
|
||||
std::vector<std::pair<uint8_t, vscript_t>> oprets;
|
||||
|
||||
if(!vopretNonfungible.empty())
|
||||
oprets.push_back(std::make_pair(OPRETID_NONFUNGIBLEDATA, vopretNonfungible));
|
||||
return EncodeTokenCreateOpRet(funcid, origpubkey, name, description, oprets);
|
||||
}
|
||||
|
||||
CScript EncodeTokenCreateOpRet(uint8_t funcid, std::vector<uint8_t> origpubkey, std::string name, std::string description, std::vector<std::pair<uint8_t, vscript_t>> oprets)
|
||||
{
|
||||
CScript opret;
|
||||
uint8_t evalcode = EVAL_TOKENS;
|
||||
funcid = 'c'; // override the param
|
||||
|
||||
opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << origpubkey << name << description;
|
||||
for (auto o : oprets) {
|
||||
if (o.first != 0) {
|
||||
ss << (uint8_t)o.first;
|
||||
ss << o.second;
|
||||
}
|
||||
});
|
||||
return(opret);
|
||||
}
|
||||
|
||||
// opret 'i' for imported tokens
|
||||
CScript EncodeTokenImportOpRet(std::vector<uint8_t> origpubkey, std::string name, std::string description, uint256 srctokenid, std::vector<std::pair<uint8_t, vscript_t>> oprets)
|
||||
{
|
||||
CScript opret;
|
||||
uint8_t evalcode = EVAL_TOKENS;
|
||||
uint8_t funcid = 'i';
|
||||
|
||||
srctokenid = revuint256(srctokenid); // do not forget this
|
||||
|
||||
opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << origpubkey << name << description << srctokenid;
|
||||
for (auto o : oprets) {
|
||||
if (o.first != 0) {
|
||||
ss << (uint8_t)o.first;
|
||||
ss << o.second;
|
||||
}
|
||||
});
|
||||
return(opret);
|
||||
}
|
||||
|
||||
|
||||
|
||||
CScript EncodeTokenOpRet(uint256 tokenid, std::vector<CPubKey> voutPubkeys, std::pair<uint8_t, vscript_t> opretWithId)
|
||||
{
|
||||
std::vector<std::pair<uint8_t, vscript_t>> oprets;
|
||||
oprets.push_back(opretWithId);
|
||||
return EncodeTokenOpRet(tokenid, voutPubkeys, oprets);
|
||||
}
|
||||
|
||||
CScript EncodeTokenOpRet(uint256 tokenid, std::vector<CPubKey> voutPubkeys, std::vector<std::pair<uint8_t, vscript_t>> oprets)
|
||||
{
|
||||
CScript opret;
|
||||
uint8_t tokenFuncId = 't';
|
||||
uint8_t evalCodeInOpret = EVAL_TOKENS;
|
||||
|
||||
tokenid = revuint256(tokenid);
|
||||
|
||||
uint8_t ccType = 0;
|
||||
if (voutPubkeys.size() >= 0 && voutPubkeys.size() <= 2)
|
||||
ccType = voutPubkeys.size();
|
||||
else {
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_DEBUG2, stream << "EncodeTokenOpRet voutPubkeys.size()=" << voutPubkeys.size() << " not supported" << std::endl);
|
||||
}
|
||||
|
||||
//vopret_t vpayload;
|
||||
//GetOpReturnData(payload, vpayload);
|
||||
|
||||
opret << OP_RETURN << E_MARSHAL(ss << evalCodeInOpret << tokenFuncId << tokenid << ccType;
|
||||
if (ccType >= 1) ss << voutPubkeys[0];
|
||||
if (ccType == 2) ss << voutPubkeys[1];
|
||||
for (auto o : oprets) {
|
||||
if (o.first != 0) {
|
||||
ss << (uint8_t)o.first;
|
||||
ss << o.second;
|
||||
}
|
||||
});
|
||||
|
||||
// bad opret cases (tries to attach payload without re-serialization):
|
||||
|
||||
// error "64: scriptpubkey":
|
||||
// if (payload.size() > 0)
|
||||
// opret += payload;
|
||||
|
||||
// error "64: scriptpubkey":
|
||||
// CScript opretPayloadNoOpcode(vpayload);
|
||||
// return opret + opretPayloadNoOpcode;
|
||||
|
||||
// error "sig_aborted":
|
||||
// opret.resize(opret.size() + vpayload.size());
|
||||
// CScript::iterator it = opret.begin() + opret.size();
|
||||
// for (int i = 0; i < vpayload.size(); i++, it++)
|
||||
// *it = vpayload[i];
|
||||
|
||||
return opret;
|
||||
}
|
||||
|
||||
// overload for compatibility
|
||||
//CScript EncodeTokenOpRet(uint8_t tokenFuncId, uint8_t evalCodeInOpret, uint256 tokenid, std::vector<CPubKey> voutPubkeys, CScript payload)
|
||||
//{
|
||||
// return EncodeTokenOpRet(tokenid, voutPubkeys, payload);
|
||||
//}
|
||||
|
||||
// overload for fungible tokens (no additional data in opret):
|
||||
uint8_t DecodeTokenCreateOpRet(const CScript &scriptPubKey, std::vector<uint8_t> &origpubkey, std::string &name, std::string &description) {
|
||||
//vopret_t vopretNonfungibleDummy;
|
||||
std::vector<std::pair<uint8_t, vscript_t>> opretsDummy;
|
||||
return DecodeTokenCreateOpRet(scriptPubKey, origpubkey, name, description, opretsDummy);
|
||||
}
|
||||
|
||||
uint8_t DecodeTokenCreateOpRet(const CScript &scriptPubKey, std::vector<uint8_t> &origpubkey, std::string &name, std::string &description, std::vector<std::pair<uint8_t, vscript_t>> &oprets)
|
||||
{
|
||||
vscript_t vopret, vblob;
|
||||
uint8_t dummyEvalcode, funcid, opretId = 0;
|
||||
|
||||
GetOpReturnData(scriptPubKey, vopret);
|
||||
oprets.clear();
|
||||
|
||||
if (vopret.size() > 2 && vopret.begin()[0] == EVAL_TOKENS && vopret.begin()[1] == 'c')
|
||||
{
|
||||
if (E_UNMARSHAL(vopret, ss >> dummyEvalcode; ss >> funcid; ss >> origpubkey; ss >> name; ss >> description;
|
||||
while (!ss.eof()) {
|
||||
ss >> opretId;
|
||||
if (!ss.eof()) {
|
||||
ss >> vblob;
|
||||
oprets.push_back(std::make_pair(opretId, vblob));
|
||||
}
|
||||
}))
|
||||
{
|
||||
return(funcid);
|
||||
}
|
||||
}
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "DecodeTokenCreateOpRet() incorrect token create opret" << std::endl);
|
||||
return (uint8_t)0;
|
||||
}
|
||||
|
||||
// for imported tokens
|
||||
uint8_t DecodeTokenImportOpRet(const CScript &scriptPubKey, std::vector<uint8_t> &origpubkey, std::string &name, std::string &description, uint256 &srctokenid, std::vector<std::pair<uint8_t, vscript_t>> &oprets)
|
||||
{
|
||||
vscript_t vopret, vblob;
|
||||
uint8_t dummyEvalcode, funcid, opretId = 0;
|
||||
|
||||
GetOpReturnData(scriptPubKey, vopret);
|
||||
oprets.clear();
|
||||
|
||||
if (vopret.size() > 2 && vopret.begin()[0] == EVAL_TOKENS && vopret.begin()[1] == 'i')
|
||||
{
|
||||
if (E_UNMARSHAL(vopret, ss >> dummyEvalcode; ss >> funcid; ss >> origpubkey; ss >> name; ss >> description; ss >> srctokenid;
|
||||
while (!ss.eof()) {
|
||||
ss >> opretId;
|
||||
if (!ss.eof()) {
|
||||
ss >> vblob;
|
||||
oprets.push_back(std::make_pair(opretId, vblob));
|
||||
}
|
||||
}))
|
||||
{
|
||||
srctokenid = revuint256(srctokenid); // do not forget this
|
||||
return(funcid);
|
||||
}
|
||||
}
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "DecodeTokenImportOpRet() incorrect token import opret" << std::endl);
|
||||
return (uint8_t)0;
|
||||
}
|
||||
|
||||
// decodes token opret:
|
||||
// for 't' returns all data from opret, vopretExtra contains other contract's data (currently only assets').
|
||||
// for 'c' and 'i' returns only funcid. NOTE: nonfungible data is not returned
|
||||
uint8_t DecodeTokenOpRet(const CScript scriptPubKey, uint8_t &evalCodeTokens, uint256 &tokenid, std::vector<CPubKey> &voutPubkeys, std::vector<std::pair<uint8_t, vscript_t>> &oprets)
|
||||
{
|
||||
vscript_t vopret, vblob, dummyPubkey, vnonfungibleDummy;
|
||||
uint8_t funcId = 0, *script, dummyEvalCode, dummyFuncId, ccType, opretId = 0;
|
||||
std::string dummyName; std::string dummyDescription;
|
||||
uint256 dummySrcTokenId;
|
||||
CPubKey voutPubkey1, voutPubkey2;
|
||||
|
||||
vscript_t voldstyledata;
|
||||
bool foundOldstyle = false;
|
||||
|
||||
GetOpReturnData(scriptPubKey, vopret);
|
||||
script = (uint8_t *)vopret.data();
|
||||
tokenid = zeroid;
|
||||
oprets.clear();
|
||||
|
||||
if (script != NULL && vopret.size() > 2)
|
||||
{
|
||||
// NOTE: if parse error occures, parse might not be able to set error. It is safer to treat that it was eof if it is not set!
|
||||
// bool isEof = true;
|
||||
|
||||
evalCodeTokens = script[0];
|
||||
if (evalCodeTokens != EVAL_TOKENS) {
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "DecodeTokenOpRet() incorrect evalcode in tokens opret" << std::endl);
|
||||
return (uint8_t)0;
|
||||
}
|
||||
|
||||
funcId = script[1];
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_DEBUG2, stream << "DecodeTokenOpRet decoded funcId=" << (char)(funcId ? funcId : ' ') << std::endl);
|
||||
|
||||
switch (funcId)
|
||||
{
|
||||
case 'c':
|
||||
return DecodeTokenCreateOpRet(scriptPubKey, dummyPubkey, dummyName, dummyDescription, oprets);
|
||||
case 'i':
|
||||
return DecodeTokenImportOpRet(scriptPubKey, dummyPubkey, dummyName, dummyDescription, dummySrcTokenId, oprets);
|
||||
//break;
|
||||
case 't':
|
||||
|
||||
// compatibility with old-style rogue or assets data (with no opretid):
|
||||
// try to unmarshal old-style rogue or assets data:
|
||||
foundOldstyle = E_UNMARSHAL(vopret, ss >> dummyEvalCode; ss >> dummyFuncId; ss >> tokenid; ss >> ccType;
|
||||
if (ccType >= 1) ss >> voutPubkey1;
|
||||
if (ccType == 2) ss >> voutPubkey2;
|
||||
if (!ss.eof()) {
|
||||
ss >> voldstyledata;
|
||||
}) && voldstyledata.size() >= 2 &&
|
||||
(voldstyledata.begin()[0] == 0x11 /*EVAL_ROGUE*/ && IS_CHARINSTR(voldstyledata.begin()[1], "RHQKG") ||
|
||||
voldstyledata.begin()[0] == EVAL_ASSETS && IS_CHARINSTR(voldstyledata.begin()[1], "sbSBxo")) ;
|
||||
|
||||
if (foundOldstyle || // fix for compatibility with old style data (no opretid)
|
||||
E_UNMARSHAL(vopret, ss >> dummyEvalCode; ss >> dummyFuncId; ss >> tokenid; ss >> ccType;
|
||||
if (ccType >= 1) ss >> voutPubkey1;
|
||||
if (ccType == 2) ss >> voutPubkey2;
|
||||
while (!ss.eof()) {
|
||||
ss >> opretId;
|
||||
if (!ss.eof()) {
|
||||
ss >> vblob;
|
||||
oprets.push_back(std::make_pair(opretId, vblob));
|
||||
}
|
||||
}))
|
||||
{
|
||||
if (!(ccType >= 0 && ccType <= 2)) { //incorrect ccType
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "DecodeTokenOpRet() incorrect ccType=" << (int)ccType << " tokenid=" << revuint256(tokenid).GetHex() << std::endl);
|
||||
return (uint8_t)0;
|
||||
}
|
||||
|
||||
// add verification pubkeys:
|
||||
voutPubkeys.clear();
|
||||
if (voutPubkey1.IsValid())
|
||||
voutPubkeys.push_back(voutPubkey1);
|
||||
if (voutPubkey2.IsValid())
|
||||
voutPubkeys.push_back(voutPubkey2);
|
||||
|
||||
tokenid = revuint256(tokenid);
|
||||
|
||||
if (foundOldstyle) { //patch for old-style opret data with no opretid
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_DEBUG1, stream << "DecodeTokenOpRet() found old-style rogue/asset data, evalcode=" << (int)voldstyledata.begin()[0] << " funcid=" << (char)voldstyledata.begin()[1] << " for tokenid=" << revuint256(tokenid).GetHex() << std::endl);
|
||||
uint8_t opretIdRestored;
|
||||
if (voldstyledata.begin()[0] == 0x11 /*EVAL_ROGUE*/)
|
||||
opretIdRestored = OPRETID_ROGUEGAMEDATA;
|
||||
else // EVAL_ASSETS
|
||||
opretIdRestored = OPRETID_ASSETSDATA;
|
||||
|
||||
oprets.push_back(std::make_pair(opretIdRestored, voldstyledata));
|
||||
}
|
||||
|
||||
return(funcId);
|
||||
}
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "DecodeTokenOpRet() bad opret format," << " ccType=" << (int)ccType << " tokenid=" << revuint256(tokenid).GetHex() << std::endl);
|
||||
return (uint8_t)0;
|
||||
|
||||
default:
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "DecodeTokenOpRet() illegal funcid=" << (int)funcId << std::endl);
|
||||
return (uint8_t)0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOGSTREAM((char *)"cctokens", CCLOG_INFO, stream << "DecodeTokenOpRet() empty opret, could not parse" << std::endl);
|
||||
}
|
||||
return (uint8_t)0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -290,6 +290,16 @@ std::string FinalizeCCTx(uint64_t CCmask,struct CCcontract_info *cp,CMutableTran
|
||||
cc_free(othercond3);
|
||||
if ( othercond4 != 0 )
|
||||
cc_free(othercond4);
|
||||
if ( othercond1of2 != 0 )
|
||||
cc_free(othercond1of2);
|
||||
if ( othercond1of2tokens != 0 )
|
||||
cc_free(othercond1of2tokens);
|
||||
if ( mytokenscond != 0 )
|
||||
cc_free(mytokenscond);
|
||||
if ( mysingletokenscond != 0 )
|
||||
cc_free(mysingletokenscond);
|
||||
if ( othertokenscond != 0 )
|
||||
cc_free(othertokenscond);
|
||||
std::string strHex = EncodeHexTx(mtx);
|
||||
if ( strHex.size() > 0 )
|
||||
return(strHex);
|
||||
@@ -347,17 +357,29 @@ int64_t CCutxovalue(char *coinaddr,uint256 utxotxid,int32_t utxovout)
|
||||
return(0);
|
||||
}
|
||||
|
||||
int32_t CCgettxout(uint256 txid,int32_t vout,int32_t mempoolflag)
|
||||
int32_t CCgettxout(uint256 txid,int32_t vout,int32_t mempoolflag,int32_t lockflag)
|
||||
{
|
||||
CCoins coins;
|
||||
//fprintf(stderr,"CCgettxoud %s/v%d\n",txid.GetHex().c_str(),vout);
|
||||
if ( mempoolflag != 0 )
|
||||
{
|
||||
LOCK(mempool.cs);
|
||||
CCoinsViewMemPool view(pcoinsTip, mempool);
|
||||
if (!view.GetCoins(txid, coins))
|
||||
return(-1);
|
||||
if ( myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) != 0 )
|
||||
return(-1);
|
||||
if ( lockflag != 0 )
|
||||
{
|
||||
LOCK(mempool.cs);
|
||||
CCoinsViewMemPool view(pcoinsTip, mempool);
|
||||
if (!view.GetCoins(txid, coins))
|
||||
return(-1);
|
||||
else if ( myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) != 0 )
|
||||
return(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
CCoinsViewMemPool view(pcoinsTip, mempool);
|
||||
if (!view.GetCoins(txid, coins))
|
||||
return(-1);
|
||||
else if ( myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) != 0 )
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -399,7 +421,7 @@ int64_t CCfullsupply(uint256 tokenid)
|
||||
{
|
||||
if (DecodeTokenCreateOpRet(tx.vout[numvouts-1].scriptPubKey,origpubkey,name,description))
|
||||
{
|
||||
return(tx.vout[0].nValue);
|
||||
return(tx.vout[1].nValue);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
@@ -420,7 +442,8 @@ int64_t CCtoken_balance(char *coinaddr,uint256 reftokenid)
|
||||
{
|
||||
char str[65];
|
||||
std::vector<CPubKey> voutTokenPubkeys;
|
||||
if ( reftokenid==txid || (DecodeTokenOpRet(tx.vout[numvouts-1].scriptPubKey, evalCode, tokenid, voutTokenPubkeys, vopretExtra) != 0 && reftokenid == tokenid))
|
||||
std::vector<std::pair<uint8_t, vscript_t>> oprets;
|
||||
if ( reftokenid==txid || (DecodeTokenOpRet(tx.vout[numvouts-1].scriptPubKey, evalCode, tokenid, voutTokenPubkeys, oprets) != 0 && reftokenid == tokenid))
|
||||
{
|
||||
sum += it->second.satoshis;
|
||||
}
|
||||
@@ -486,16 +509,18 @@ int32_t CC_vinselect(int32_t *aboveip,int64_t *abovep,int32_t *belowip,int64_t *
|
||||
|
||||
int64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int32_t maxinputs)
|
||||
{
|
||||
int32_t abovei,belowi,ind,vout,i,n = 0,maxutxos=CC_MAXVINS; int64_t sum,threshold,above,below; int64_t remains,nValue,totalinputs = 0; uint256 txid,hashBlock; std::vector<COutput> vecOutputs; CTransaction tx; struct CC_utxo *utxos,*up;
|
||||
int32_t abovei,belowi,ind,vout,i,n = 0; int64_t sum,threshold,above,below; int64_t remains,nValue,totalinputs = 0; uint256 txid,hashBlock; std::vector<COutput> vecOutputs; CTransaction tx; struct CC_utxo *utxos,*up;
|
||||
#ifdef ENABLE_WALLET
|
||||
assert(pwalletMain != NULL);
|
||||
const CKeyStore& keystore = *pwalletMain;
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
pwalletMain->AvailableCoins(vecOutputs, false, NULL, true);
|
||||
utxos = (struct CC_utxo *)calloc(maxutxos,sizeof(*utxos));
|
||||
threshold = total/(maxinputs+1);
|
||||
if ( maxinputs > maxutxos )
|
||||
maxutxos = maxinputs;
|
||||
utxos = (struct CC_utxo *)calloc(CC_MAXVINS,sizeof(*utxos));
|
||||
if ( maxinputs > CC_MAXVINS )
|
||||
maxinputs = CC_MAXVINS;
|
||||
if ( maxinputs > 0 )
|
||||
threshold = total/maxinputs;
|
||||
else threshold = total;
|
||||
sum = 0;
|
||||
BOOST_FOREACH(const COutput& out, vecOutputs)
|
||||
{
|
||||
@@ -530,7 +555,7 @@ int64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int3
|
||||
up->vout = vout;
|
||||
sum += up->nValue;
|
||||
//fprintf(stderr,"add %.8f to vins array.%d of %d\n",(double)up->nValue/COIN,n,maxutxos);
|
||||
if ( n >= maxutxos || sum >= total )
|
||||
if ( n >= maxinputs || sum >= total )
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -579,12 +604,14 @@ int64_t AddNormalinputs(CMutableTransaction &mtx,CPubKey mypk,int64_t total,int3
|
||||
|
||||
int64_t AddNormalinputs2(CMutableTransaction &mtx,int64_t total,int32_t maxinputs)
|
||||
{
|
||||
int32_t abovei,belowi,ind,vout,i,n = 0,maxutxos=CC_MAXVINS; int64_t sum,threshold,above,below; int64_t remains,nValue,totalinputs = 0; char coinaddr[64]; uint256 txid,hashBlock; CTransaction tx; struct CC_utxo *utxos,*up;
|
||||
int32_t abovei,belowi,ind,vout,i,n = 0; int64_t sum,threshold,above,below; int64_t remains,nValue,totalinputs = 0; char coinaddr[64]; uint256 txid,hashBlock; CTransaction tx; struct CC_utxo *utxos,*up;
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
utxos = (struct CC_utxo *)calloc(maxutxos,sizeof(*utxos));
|
||||
threshold = total/(maxinputs+1);
|
||||
if ( maxinputs > maxutxos )
|
||||
maxutxos = maxinputs;
|
||||
utxos = (struct CC_utxo *)calloc(CC_MAXVINS,sizeof(*utxos));
|
||||
if ( maxinputs > CC_MAXVINS )
|
||||
maxinputs = CC_MAXVINS;
|
||||
if ( maxinputs > 0 )
|
||||
threshold = total/maxinputs;
|
||||
else threshold = total;
|
||||
sum = 0;
|
||||
Getscriptaddress(coinaddr,CScript() << Mypubkey() << OP_CHECKSIG);
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
@@ -621,7 +648,7 @@ int64_t AddNormalinputs2(CMutableTransaction &mtx,int64_t total,int32_t maxinput
|
||||
up->vout = vout;
|
||||
sum += up->nValue;
|
||||
//fprintf(stderr,"add %.8f to vins array.%d of %d\n",(double)up->nValue/COIN,n,maxutxos);
|
||||
if ( n >= maxutxos || sum >= total )
|
||||
if ( n >= maxinputs || sum >= total )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
105
src/cc/CCutilbits.cpp
Normal file
105
src/cc/CCutilbits.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
/******************************************************************************
|
||||
* Copyright © 2014-2019 The SuperNET Developers. *
|
||||
* *
|
||||
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
|
||||
* the top-level directory of this distribution for the individual copyright *
|
||||
* holder information and the developer policies on copyright and licensing. *
|
||||
* *
|
||||
* Unless otherwise agreed in a custom licensing agreement, no part of the *
|
||||
* SuperNET software, including this file may be copied, modified, propagated *
|
||||
* or distributed except according to the terms contained in the LICENSE file *
|
||||
* *
|
||||
* Removal or modification of this copyright notice is prohibited. *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
CCutilbits.cpp has very low level functions that are universally useful for all contracts and have low dependency from other sources
|
||||
*/
|
||||
|
||||
#include "CCinclude.h"
|
||||
#include "komodo_structs.h"
|
||||
|
||||
int32_t unstringbits(char *buf,uint64_t bits)
|
||||
{
|
||||
int32_t i;
|
||||
for (i=0; i<8; i++,bits>>=8)
|
||||
if ( (buf[i]= (char)(bits & 0xff)) == 0 )
|
||||
break;
|
||||
buf[i] = 0;
|
||||
return(i);
|
||||
}
|
||||
|
||||
uint64_t stringbits(char *str)
|
||||
{
|
||||
uint64_t bits = 0;
|
||||
if ( str == 0 )
|
||||
return(0);
|
||||
int32_t i,n = (int32_t)strlen(str);
|
||||
if ( n > 8 )
|
||||
n = 8;
|
||||
for (i=n-1; i>=0; i--)
|
||||
bits = (bits << 8) | (str[i] & 0xff);
|
||||
//printf("(%s) -> %llx %llu\n",str,(long long)bits,(long long)bits);
|
||||
return(bits);
|
||||
}
|
||||
|
||||
uint256 revuint256(uint256 txid)
|
||||
{
|
||||
uint256 revtxid; int32_t i;
|
||||
for (i=31; i>=0; i--)
|
||||
((uint8_t *)&revtxid)[31-i] = ((uint8_t *)&txid)[i];
|
||||
return(revtxid);
|
||||
}
|
||||
|
||||
char *uint256_str(char *dest,uint256 txid)
|
||||
{
|
||||
int32_t i,j=0;
|
||||
for (i=31; i>=0; i--)
|
||||
sprintf(&dest[j++ * 2],"%02x",((uint8_t *)&txid)[i]);
|
||||
dest[64] = 0;
|
||||
return(dest);
|
||||
}
|
||||
|
||||
char *pubkey33_str(char *dest,uint8_t *pubkey33)
|
||||
{
|
||||
int32_t i;
|
||||
if ( pubkey33 != 0 )
|
||||
{
|
||||
for (i=0; i<33; i++)
|
||||
sprintf(&dest[i * 2],"%02x",pubkey33[i]);
|
||||
} else dest[0] = 0;
|
||||
return(dest);
|
||||
}
|
||||
|
||||
uint256 Parseuint256(const char *hexstr)
|
||||
{
|
||||
uint256 txid; int32_t i; std::vector<unsigned char> txidbytes(ParseHex(hexstr));
|
||||
memset(&txid,0,sizeof(txid));
|
||||
if ( strlen(hexstr) == 64 )
|
||||
{
|
||||
for (i=31; i>=0; i--)
|
||||
((uint8_t *)&txid)[31-i] = ((uint8_t *)txidbytes.data())[i];
|
||||
}
|
||||
return(txid);
|
||||
}
|
||||
|
||||
CPubKey buf2pk(uint8_t *buf33)
|
||||
{
|
||||
CPubKey pk; int32_t i; uint8_t *dest;
|
||||
dest = (uint8_t *)pk.begin();
|
||||
for (i=0; i<33; i++)
|
||||
dest[i] = buf33[i];
|
||||
return(pk);
|
||||
}
|
||||
|
||||
CPubKey pubkey2pk(std::vector<uint8_t> pubkey)
|
||||
{
|
||||
CPubKey pk; int32_t i,n; uint8_t *dest,*pubkey33;
|
||||
n = pubkey.size();
|
||||
dest = (uint8_t *)pk.begin();
|
||||
pubkey33 = (uint8_t *)pubkey.data();
|
||||
for (i=0; i<n; i++)
|
||||
dest[i] = pubkey33[i];
|
||||
return(pk);
|
||||
}
|
||||
@@ -168,89 +168,6 @@ bool IsCCInput(CScript const& scriptSig)
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t unstringbits(char *buf,uint64_t bits)
|
||||
{
|
||||
int32_t i;
|
||||
for (i=0; i<8; i++,bits>>=8)
|
||||
if ( (buf[i]= (char)(bits & 0xff)) == 0 )
|
||||
break;
|
||||
buf[i] = 0;
|
||||
return(i);
|
||||
}
|
||||
|
||||
uint64_t stringbits(char *str)
|
||||
{
|
||||
uint64_t bits = 0;
|
||||
if ( str == 0 )
|
||||
return(0);
|
||||
int32_t i,n = (int32_t)strlen(str);
|
||||
if ( n > 8 )
|
||||
n = 8;
|
||||
for (i=n-1; i>=0; i--)
|
||||
bits = (bits << 8) | (str[i] & 0xff);
|
||||
//printf("(%s) -> %llx %llu\n",str,(long long)bits,(long long)bits);
|
||||
return(bits);
|
||||
}
|
||||
|
||||
uint256 revuint256(uint256 txid)
|
||||
{
|
||||
uint256 revtxid; int32_t i;
|
||||
for (i=31; i>=0; i--)
|
||||
((uint8_t *)&revtxid)[31-i] = ((uint8_t *)&txid)[i];
|
||||
return(revtxid);
|
||||
}
|
||||
|
||||
char *uint256_str(char *dest,uint256 txid)
|
||||
{
|
||||
int32_t i,j=0;
|
||||
for (i=31; i>=0; i--)
|
||||
sprintf(&dest[j++ * 2],"%02x",((uint8_t *)&txid)[i]);
|
||||
dest[64] = 0;
|
||||
return(dest);
|
||||
}
|
||||
|
||||
char *pubkey33_str(char *dest,uint8_t *pubkey33)
|
||||
{
|
||||
int32_t i;
|
||||
if ( pubkey33 != 0 )
|
||||
{
|
||||
for (i=0; i<33; i++)
|
||||
sprintf(&dest[i * 2],"%02x",pubkey33[i]);
|
||||
} else dest[0] = 0;
|
||||
return(dest);
|
||||
}
|
||||
|
||||
uint256 Parseuint256(char *hexstr)
|
||||
{
|
||||
uint256 txid; int32_t i; std::vector<unsigned char> txidbytes(ParseHex(hexstr));
|
||||
memset(&txid,0,sizeof(txid));
|
||||
if ( strlen(hexstr) == 64 )
|
||||
{
|
||||
for (i=31; i>=0; i--)
|
||||
((uint8_t *)&txid)[31-i] = ((uint8_t *)txidbytes.data())[i];
|
||||
}
|
||||
return(txid);
|
||||
}
|
||||
|
||||
CPubKey buf2pk(uint8_t *buf33)
|
||||
{
|
||||
CPubKey pk; int32_t i; uint8_t *dest;
|
||||
dest = (uint8_t *)pk.begin();
|
||||
for (i=0; i<33; i++)
|
||||
dest[i] = buf33[i];
|
||||
return(pk);
|
||||
}
|
||||
|
||||
CPubKey pubkey2pk(std::vector<uint8_t> pubkey)
|
||||
{
|
||||
CPubKey pk; int32_t i,n; uint8_t *dest,*pubkey33;
|
||||
n = pubkey.size();
|
||||
dest = (uint8_t *)pk.begin();
|
||||
pubkey33 = (uint8_t *)pubkey.data();
|
||||
for (i=0; i<n; i++)
|
||||
dest[i] = pubkey33[i];
|
||||
return(pk);
|
||||
}
|
||||
|
||||
// set additional 'unspendable' addr
|
||||
void CCaddr2set(struct CCcontract_info *cp,uint8_t evalcode,CPubKey pk,uint8_t *priv,char *coinaddr)
|
||||
|
||||
@@ -4,7 +4,7 @@ CC_DARWIN = g++-6
|
||||
CC_WIN = x86_64-w64-mingw32-gcc-posix
|
||||
CFLAGS_DARWIN = -DBUILD_ROGUE -std=c++11 -arch x86_64 -I../../depends/$(shell echo `../..//depends/config.guess`/include) -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -Wl,-undefined -Wl,dynamic_lookup -Wno-write-strings -shared -dynamiclib
|
||||
CFLAGS = -Wno-write-strings -DBUILD_ROGUE -std=c++11 -I../../depends/$(shell echo `../..//depends/config.guess`/include) -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared
|
||||
CFLAGS_WIN = -Wno-write-strings -DBUILD_ROGUE -std=c++11 -I../../depends/x86_64-w64-mingw32/include -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared
|
||||
CFLAGS_WIN = -Wno-write-strings -DBUILD_ROGUE -std=c++11 -I./rogue/x86_64-w64-mingw32/include -I./rogue/x86_64-w64-mingw32/include/ncursesw -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared
|
||||
DEBUGFLAGS = -O0 -D _DEBUG
|
||||
RELEASEFLAGS = -O2 -D NDEBUG -combine -fwhole-program
|
||||
$(info $(OS))
|
||||
|
||||
@@ -146,6 +146,13 @@ bool AssetsValidate(struct CCcontract_info *cpAssets,Eval* eval,const CTransacti
|
||||
numvouts = tx.vout.size();
|
||||
outputsDummy = inputs = 0;
|
||||
preventCCvins = preventCCvouts = -1;
|
||||
|
||||
// add specific chains exceptions for old token support:
|
||||
if (strcmp(ASSETCHAINS_SYMBOL, "SEC") == 0 && chainActive.Height() <= 144073)
|
||||
return true;
|
||||
|
||||
if (strcmp(ASSETCHAINS_SYMBOL, "MGNX") == 0 && chainActive.Height() <= 210190)
|
||||
return true;
|
||||
|
||||
// add specific chains exceptions for old token support:
|
||||
if (strcmp(ASSETCHAINS_SYMBOL, "SEC") == 0 && chainActive.Height() <= 144073)
|
||||
@@ -290,6 +297,7 @@ bool AssetsValidate(struct CCcontract_info *cpAssets,Eval* eval,const CTransacti
|
||||
return eval->Invalid("vout2 doesnt go to origpubkey fillbuy");
|
||||
else if ( inputs != tx.vout[2].nValue + tx.vout[4].nValue )
|
||||
return eval->Invalid("asset inputs doesnt match vout2+3 fillbuy");
|
||||
preventCCvouts ++;
|
||||
}
|
||||
else if( ConstrainVout(tx.vout[2], 1, origTokensCCaddr, inputs) == 0 ) // tokens to originator cc addr (tokens+nonfungible evals)
|
||||
return eval->Invalid("vout2 doesnt match inputs fillbuy");
|
||||
@@ -461,7 +469,7 @@ bool AssetsValidate(struct CCcontract_info *cpAssets,Eval* eval,const CTransacti
|
||||
}
|
||||
|
||||
// what does this do?
|
||||
bool bPrevent = PreventCC(eval, tx, preventCCvins, numvins, preventCCvouts, numvouts);
|
||||
bool bPrevent = PreventCC(eval, tx, preventCCvins, numvins, preventCCvouts, numvouts); // seems we do not need this call as we already checked vouts well
|
||||
//std::cerr << "AssetsValidate() PreventCC returned=" << bPrevent << std::endl;
|
||||
return (bPrevent);
|
||||
}
|
||||
|
||||
@@ -33,8 +33,12 @@
|
||||
#ifdef BUILD_ROGUE
|
||||
#define EVAL_ROGUE 17
|
||||
std::string MYCCLIBNAME = (char *)"rogue";
|
||||
#else
|
||||
|
||||
|
||||
#elif BUILD_CUSTOMCC
|
||||
#include "customcc.h"
|
||||
|
||||
#else
|
||||
#define EVAL_SUDOKU 17
|
||||
#define EVAL_MUSIG 18
|
||||
#define EVAL_DILITHIUM 19
|
||||
@@ -67,6 +71,8 @@ CClib_methods[] =
|
||||
{ (char *)"rogue", (char *)"games", (char *)"<no args>", 0, 0, 'F', EVAL_ROGUE },
|
||||
{ (char *)"rogue", (char *)"setname", (char *)"pname", 1, 1, 'N', EVAL_ROGUE },
|
||||
{ (char *)"rogue", (char *)"extract", (char *)"gametxid [pubkey]", 1, 2, 'X', EVAL_ROGUE },
|
||||
#elif BUILD_CUSTOMCC
|
||||
RPC_FUNCS
|
||||
#else
|
||||
{ (char *)"sudoku", (char *)"gen", (char *)"<no args>", 0, 0, 'G', EVAL_SUDOKU },
|
||||
{ (char *)"sudoku", (char *)"txidinfo", (char *)"txid", 1, 1, 'T', EVAL_SUDOKU },
|
||||
@@ -83,10 +89,12 @@ CClib_methods[] =
|
||||
{ (char *)"musig", (char *)"spend", (char *)"sendtxid sig scriptPubKey", 3, 3, 'y', EVAL_MUSIG },
|
||||
{ (char *)"dilithium", (char *)"keypair", (char *)"[hexseed]", 0, 1, 'K', EVAL_DILITHIUM },
|
||||
{ (char *)"dilithium", (char *)"register", (char *)"handle, [hexseed]", 1, 2, 'R', EVAL_DILITHIUM },
|
||||
{ (char *)"dilithium", (char *)"handleinfo", (char *)"handle", 1, 1, 'I', EVAL_DILITHIUM },
|
||||
{ (char *)"dilithium", (char *)"sign", (char *)"msg [hexseed]", 1, 2, 'S', EVAL_DILITHIUM },
|
||||
{ (char *)"dilithium", (char *)"verify", (char *)"pubtxid msg sig", 3, 3, 'V', EVAL_DILITHIUM },
|
||||
{ (char *)"dilithium", (char *)"send", (char *)"handle pubtxid amount", 3, 3, 'x', EVAL_DILITHIUM },
|
||||
{ (char *)"dilithium", (char *)"spend", (char *)"sendtxid scriptPubKey [hexseed]", 2, 3, 'y', EVAL_DILITHIUM },
|
||||
{ (char *)"dilithium", (char *)"Qsend", (char *)"mypubtxid hexseed/'mypriv' destpubtxid,amount, ...", 4, 66, 'Q', EVAL_DILITHIUM },
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -129,11 +137,13 @@ UniValue musig_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
|
||||
|
||||
bool dilithium_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx);
|
||||
UniValue dilithium_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
|
||||
UniValue dilithium_handleinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
|
||||
UniValue dilithium_send(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
|
||||
UniValue dilithium_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
|
||||
UniValue dilithium_keypair(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
|
||||
UniValue dilithium_sign(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
|
||||
UniValue dilithium_verify(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
|
||||
UniValue dilithium_Qsend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -210,6 +220,8 @@ UniValue CClib_method(struct CCcontract_info *cp,char *method,char *jsonstr)
|
||||
return(result);
|
||||
}
|
||||
}
|
||||
#elif BUILD_CUSTOMCC
|
||||
CUSTOM_DISPATCH
|
||||
#else
|
||||
if ( cp->evalcode == EVAL_SUDOKU )
|
||||
{
|
||||
@@ -261,7 +273,9 @@ UniValue CClib_method(struct CCcontract_info *cp,char *method,char *jsonstr)
|
||||
}
|
||||
else if ( cp->evalcode == EVAL_DILITHIUM )
|
||||
{
|
||||
if ( strcmp(method,"send") == 0 )
|
||||
if ( strcmp(method,"Qsend") == 0 )
|
||||
return(dilithium_Qsend(txfee,cp,params));
|
||||
else if ( strcmp(method,"send") == 0 )
|
||||
return(dilithium_send(txfee,cp,params));
|
||||
else if ( strcmp(method,"spend") == 0 )
|
||||
return(dilithium_spend(txfee,cp,params));
|
||||
@@ -269,6 +283,8 @@ UniValue CClib_method(struct CCcontract_info *cp,char *method,char *jsonstr)
|
||||
return(dilithium_keypair(txfee,cp,params));
|
||||
else if ( strcmp(method,"register") == 0 )
|
||||
return(dilithium_register(txfee,cp,params));
|
||||
else if ( strcmp(method,"handleinfo") == 0 )
|
||||
return(dilithium_handleinfo(txfee,cp,params));
|
||||
else if ( strcmp(method,"sign") == 0 )
|
||||
return(dilithium_sign(txfee,cp,params));
|
||||
else if ( strcmp(method,"verify") == 0 )
|
||||
@@ -402,6 +418,8 @@ bool CClib_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const C
|
||||
{
|
||||
#ifdef BUILD_ROGUE
|
||||
return(rogue_validate(cp,height,eval,tx));
|
||||
#elif BUILD_CUSTOMCC
|
||||
return(custom_validate(cp,height,eval,tx));
|
||||
#else
|
||||
if ( cp->evalcode == EVAL_SUDOKU )
|
||||
return(sudoku_validate(cp,height,eval,tx));
|
||||
@@ -474,7 +492,11 @@ int64_t AddCClibInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
GetCCaddress(cp,coinaddr,pk);
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
threshold = total/(maxinputs+1);
|
||||
if ( maxinputs > CC_MAXVINS )
|
||||
maxinputs = CC_MAXVINS;
|
||||
if ( maxinputs != 0 )
|
||||
threshold = total/maxinputs;
|
||||
else threshold = total;
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||
{
|
||||
txid = it->first.txhash;
|
||||
@@ -500,6 +522,31 @@ int64_t AddCClibInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK
|
||||
return(totalinputs);
|
||||
}
|
||||
|
||||
int64_t AddCClibtxfee(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk)
|
||||
{
|
||||
char coinaddr[64]; int64_t nValue,txfee = 10000; uint256 txid,hashBlock; CTransaction vintx; int32_t vout;
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
GetCCaddress(cp,coinaddr,pk);
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||
{
|
||||
txid = it->first.txhash;
|
||||
vout = (int32_t)it->first.index;
|
||||
//char str[65]; fprintf(stderr,"%s check %s/v%d %.8f vs %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN,(double)threshold/COIN);
|
||||
if ( it->second.satoshis < txfee )
|
||||
continue;
|
||||
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
|
||||
{
|
||||
if ( (nValue= IsCClibvout(cp,vintx,vout,coinaddr)) != 0 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
|
||||
{
|
||||
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
|
||||
return(it->second.satoshis);
|
||||
} //else fprintf(stderr,"nValue %.8f too small or already spent in mempool\n",(double)nValue/COIN);
|
||||
} else fprintf(stderr,"couldnt get tx\n");
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
std::string Faucet2Fund(struct CCcontract_info *cp,uint64_t txfee,int64_t funds)
|
||||
{
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
@@ -627,6 +674,9 @@ int32_t cclib_parsehash(uint8_t *hash32,cJSON *item,int32_t len)
|
||||
#include "rogue/weapons.c"
|
||||
#include "rogue/wizard.c"
|
||||
|
||||
#elif BUILD_CUSTOMCC
|
||||
#include "customcc.cpp"
|
||||
|
||||
#else
|
||||
#include "sudoku.cpp"
|
||||
#include "musig.cpp"
|
||||
|
||||
@@ -92,24 +92,27 @@ int64_t IsChannelsMarkervout(struct CCcontract_info *cp,const CTransaction& tx,C
|
||||
CScript EncodeChannelsOpRet(uint8_t funcid,uint256 tokenid,uint256 opentxid,CPubKey srcpub,CPubKey destpub,int32_t numpayments,int64_t payment,uint256 hashchain)
|
||||
{
|
||||
CScript opret; uint8_t evalcode = EVAL_CHANNELS;
|
||||
vscript_t vopret;
|
||||
|
||||
opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << opentxid << srcpub << destpub << numpayments << payment << hashchain);
|
||||
vopret = E_MARSHAL(ss << evalcode << funcid << opentxid << srcpub << destpub << numpayments << payment << hashchain);
|
||||
if (tokenid!=zeroid)
|
||||
{
|
||||
std::vector<CPubKey> pks;
|
||||
pks.push_back(srcpub);
|
||||
pks.push_back(destpub);
|
||||
return(EncodeTokenOpRet(tokenid,pks,opret));
|
||||
return(EncodeTokenOpRet(tokenid,pks, std::make_pair(OPRETID_CHANNELSDATA, vopret)));
|
||||
}
|
||||
opret << OP_RETURN << vopret;
|
||||
return(opret);
|
||||
}
|
||||
|
||||
uint8_t DecodeChannelsOpRet(const CScript &scriptPubKey, uint256 &tokenid, uint256 &opentxid, CPubKey &srcpub,CPubKey &destpub,int32_t &numpayments,int64_t &payment,uint256 &hashchain)
|
||||
{
|
||||
std::vector<std::pair<uint8_t, vscript_t>> oprets;
|
||||
std::vector<uint8_t> vopret,vOpretExtra; uint8_t *script,e,f,tokenevalcode;
|
||||
std::vector<CPubKey> pubkeys;
|
||||
|
||||
if (DecodeTokenOpRet(scriptPubKey,tokenevalcode,tokenid,pubkeys,vOpretExtra)!=0 && tokenevalcode==EVAL_TOKENS && vOpretExtra.size()>0)
|
||||
if (DecodeTokenOpRet(scriptPubKey,tokenevalcode,tokenid,pubkeys,oprets)!=0 && GetOpretBlob(oprets, OPRETID_CHANNELSDATA, vOpretExtra) && tokenevalcode==EVAL_TOKENS && vOpretExtra.size()>0)
|
||||
{
|
||||
vopret=vOpretExtra;
|
||||
}
|
||||
|
||||
88
src/cc/customcc.cpp
Normal file
88
src/cc/customcc.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
simple stub custom cc
|
||||
|
||||
Just update the functions in this file, then from ~/komodo/src/cc
|
||||
|
||||
../komodo-cli -ac_name=CUSTOM stop
|
||||
./makecustom
|
||||
../komodod -ac_name=CUSTOM -ac_cclib=custom -ac_cc=2 ...
|
||||
|
||||
The above will rebuild komodod and get it running again
|
||||
*/
|
||||
|
||||
CScript custom_opret(uint8_t funcid,CPubKey pk)
|
||||
{
|
||||
CScript opret; uint8_t evalcode = EVAL_CUSTOM;
|
||||
opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << pk);
|
||||
return(opret);
|
||||
}
|
||||
|
||||
uint8_t custom_opretdecode(CPubKey &pk,CScript scriptPubKey)
|
||||
{
|
||||
std::vector<uint8_t> vopret; uint8_t e,f;
|
||||
GetOpReturnData(scriptPubKey,vopret);
|
||||
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> pk) != 0 && e == EVAL_CUSTOM )
|
||||
{
|
||||
return(f);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
UniValue custom_rawtxresult(UniValue &result,std::string rawtx,int32_t broadcastflag)
|
||||
{
|
||||
CTransaction tx;
|
||||
if ( rawtx.size() > 0 )
|
||||
{
|
||||
result.push_back(Pair("hex",rawtx));
|
||||
if ( DecodeHexTx(tx,rawtx) != 0 )
|
||||
{
|
||||
if ( broadcastflag != 0 && myAddtomempool(tx) != 0 )
|
||||
RelayTransaction(tx);
|
||||
result.push_back(Pair("txid",tx.GetHash().ToString()));
|
||||
result.push_back(Pair("result","success"));
|
||||
} else result.push_back(Pair("error","decode hex"));
|
||||
} else result.push_back(Pair("error","couldnt finalize CCtx"));
|
||||
return(result);
|
||||
}
|
||||
|
||||
UniValue custom_func0(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ);
|
||||
result.push_back(Pair("result","success"));
|
||||
result.push_back(Pair("message","just an example of an information returning rpc"));
|
||||
return(result);
|
||||
}
|
||||
|
||||
// send yourself 1 coin to your CC address using normal utxo from your -pubkey
|
||||
|
||||
UniValue custom_func1(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
{
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); std::string rawtx;
|
||||
UniValue result(UniValue::VOBJ); CPubKey mypk; int64_t amount = COIN; int32_t broadcastflag=0;
|
||||
if ( txfee == 0 )
|
||||
txfee = CUSTOM_TXFEE;
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
if ( AddNormalinputs(mtx,mypk,COIN+txfee,64) >= COIN+txfee ) // add utxo to mtx
|
||||
{
|
||||
mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,mypk)); // make vout0
|
||||
// add opreturn, change is automatically added and tx is properly signed
|
||||
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,custom_opret('1',mypk));
|
||||
return(custom_rawtxresult(result,rawtx,broadcastflag));
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
bool custom_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx)
|
||||
{
|
||||
char expectedaddress[64]; CPubKey pk;
|
||||
if ( tx.vout.size() != 2 ) // make sure the tx only has 2 outputs
|
||||
return eval->Invalid("invalid number of vouts");
|
||||
else if ( custom_opretdecode(pk,tx.vout[1].scriptPubKey) != '1' ) // verify has opreturn
|
||||
return eval->Invalid("invalid opreturn");
|
||||
GetCCaddress(cp,expectedaddress,pk);
|
||||
if ( IsCClibvout(cp,tx,0,expectedaddress) == COIN ) // make sure amount and destination matches
|
||||
return(true);
|
||||
else return eval->Invalid("invalid vout0 amount");
|
||||
}
|
||||
|
||||
|
||||
45
src/cc/customcc.h
Normal file
45
src/cc/customcc.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
to create a custom libcc.so:
|
||||
|
||||
1. change "func0" and "func1" to method names that fit your custom cc. Of course, you can create more functions by adding another entry to RPC_FUNCS. there is not any practical limit to the number of methods.
|
||||
|
||||
2. For each method make sure there is a UniValue function declaration and CUSTOM_DISPATCH has an if statement checking for it that calls the custom_func
|
||||
|
||||
3. write the actual custom_func0, custom_func1 and custom_validate in customcc.cpp
|
||||
|
||||
4. ./makecustom, which builds cclib.cpp with -DBUILD_CUSTOMCC and puts the libcc.so in ~/komodo/src and rebuilds komodod
|
||||
|
||||
5. launch your chain with -ac_cclib=customcc -ac_cc=2
|
||||
|
||||
*/
|
||||
|
||||
std::string MYCCLIBNAME = (char *)"customcc";
|
||||
|
||||
#define EVAL_CUSTOM (EVAL_FAUCET2+1)
|
||||
#define CUSTOM_TXFEE 10000
|
||||
|
||||
#define MYCCNAME "custom"
|
||||
|
||||
#define RPC_FUNCS \
|
||||
{ (char *)MYCCNAME, (char *)"func0", (char *)"<parameter help>", 1, 1, '0', EVAL_CUSTOM }, \
|
||||
{ (char *)MYCCNAME, (char *)"func1", (char *)"<no args>", 0, 0, '1', EVAL_CUSTOM },
|
||||
|
||||
bool custom_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx);
|
||||
UniValue custom_func0(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
|
||||
UniValue custom_func1(uint64_t txfee,struct CCcontract_info *cp,cJSON *params);
|
||||
|
||||
#define CUSTOM_DISPATCH \
|
||||
if ( cp->evalcode == EVAL_CUSTOM ) \
|
||||
{ \
|
||||
if ( strcmp(method,"func0") == 0 ) \
|
||||
return(custom_func0(txfee,cp,params)); \
|
||||
else if ( strcmp(method,"func1") == 0 ) \
|
||||
return(custom_func1(txfee,cp,params)); \
|
||||
else \
|
||||
{ \
|
||||
result.push_back(Pair("result","error")); \
|
||||
result.push_back(Pair("error","invalid customcc method")); \
|
||||
result.push_back(Pair("method",method)); \
|
||||
return(result); \
|
||||
} \
|
||||
}
|
||||
@@ -1052,9 +1052,11 @@ uint64_t AddDiceInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
GetCCaddress(cp,coinaddr,pk);
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
if ( maxinputs > CC_MAXVINS )
|
||||
maxinputs = CC_MAXVINS;
|
||||
if ( maxinputs > 0 )
|
||||
threshold = total / maxinputs;
|
||||
else threshold = total / 64;
|
||||
else threshold = total;
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||
{
|
||||
txid = it->first.txhash;
|
||||
@@ -1213,6 +1215,9 @@ int64_t DicePlanFunds(uint64_t &entropyval,uint256 &entropytxid,uint64_t refsbit
|
||||
} else {
|
||||
return(0);
|
||||
}
|
||||
//fprintf(stderr,"numentropy tx %d: %.8f\n",n,(double)totalinputs/COIN);
|
||||
entropytxs = n;
|
||||
return(totalinputs);
|
||||
}
|
||||
|
||||
bool DicePlanExists(CScript &fundingPubKey,uint256 &fundingtxid,struct CCcontract_info *cp,uint64_t refsbits,CPubKey dicepk,int64_t &minbet,int64_t &maxbet,int64_t &maxodds,int64_t &timeoutblocks)
|
||||
|
||||
@@ -2908,6 +2908,20 @@ int32_t main(void)
|
||||
this generates a really big hex, broadcast it and if all went well it will get confirmed.
|
||||
a dilithium spend!
|
||||
|
||||
to generate a seed that wont be directly derivable from an secp256k1 keypair, do:
|
||||
cclib keypair 19 \"[%22rand%22]\"
|
||||
|
||||
to do a Qsend (multiple dilithium inputs and outputs)
|
||||
|
||||
cclib Qsend 19 \"[%22mypubtxid%22,%22<hexseed>%22,%22<destpubtxid>%22,0.777]\"
|
||||
there can be up to 64 outputs, where each one can be a different destpubtxid or scriptPubKey. The only restriction is that scriptPubKey hex cant be 32 bytes.
|
||||
|
||||
Qsend is able to spend many Qvins as long as they are for the same dilithium bigpub + secp pub33. And the outputs can be to many different Qvouts or normal vouts. This allows to keep funds totally within the dilithium system and also to transfer back to normal taddrs. Qsend currently only sends from Qfunds, though it could also use funds from normal inputs.
|
||||
|
||||
Currently, to get funds from normal inputs to a dilithium, the send rpc can be used as above. So that provides a way to push funds into dilithium. The spend rpc becomes redundant with Qsend.
|
||||
|
||||
To properly test this, we need to make sure that transactions Qsend can use send outputs, and Qsend outputs and a combination. Of course, it needs to be validated that funds are not lost, Qsends work properly, etc.
|
||||
|
||||
*/
|
||||
|
||||
#define DILITHIUM_TXFEE 10000
|
||||
@@ -2915,6 +2929,69 @@ int32_t main(void)
|
||||
void calc_rmd160_sha256(uint8_t rmd160[20],uint8_t *data,int32_t datalen);
|
||||
char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey_or_rmd160,int32_t len);
|
||||
|
||||
struct dilithium_handle
|
||||
{
|
||||
UT_hash_handle hh;
|
||||
uint256 destpubtxid;
|
||||
char handle[32];
|
||||
} *Dilithium_handles;
|
||||
|
||||
pthread_mutex_t DILITHIUM_MUTEX;
|
||||
|
||||
struct dilithium_handle *dilithium_handlenew(char *handle)
|
||||
{
|
||||
struct dilithium_handle *hashstr = 0; int32_t len = (int32_t)strlen(handle);
|
||||
if ( len < sizeof(Dilithium_handles[0].handle)-1 )
|
||||
{
|
||||
pthread_mutex_lock(&DILITHIUM_MUTEX);
|
||||
HASH_FIND(hh,Dilithium_handles,handle,len,hashstr);
|
||||
if ( hashstr == 0 )
|
||||
{
|
||||
hashstr = (struct dilithium_handle *)calloc(1,sizeof(*hashstr));
|
||||
strncpy(hashstr->handle,handle,sizeof(hashstr->handle));
|
||||
HASH_ADD_KEYPTR(hh,Dilithium_handles,hashstr->handle,len,hashstr);
|
||||
}
|
||||
pthread_mutex_unlock(&DILITHIUM_MUTEX);
|
||||
}
|
||||
return(hashstr);
|
||||
}
|
||||
|
||||
struct dilithium_handle *dilithium_handlefind(char *handle)
|
||||
{
|
||||
struct dilithium_handle *hashstr = 0; int32_t len = (int32_t)strlen(handle);
|
||||
if ( len < sizeof(Dilithium_handles[0].handle)-1 )
|
||||
{
|
||||
pthread_mutex_lock(&DILITHIUM_MUTEX);
|
||||
HASH_FIND(hh,Dilithium_handles,handle,len,hashstr);
|
||||
pthread_mutex_unlock(&DILITHIUM_MUTEX);
|
||||
}
|
||||
return(hashstr);
|
||||
}
|
||||
|
||||
int32_t dilithium_Qmsghash(uint8_t *msg,CTransaction tx,int32_t numvouts,std::vector<uint256> voutpubtxids)
|
||||
{
|
||||
CScript data; uint256 hash; int32_t i,numvins,len = 0; std::vector<uint256> vintxids; std::vector<int32_t> vinprevns; std::vector<CTxOut> vouts;
|
||||
numvins = tx.vin.size();
|
||||
for (i=0; i<numvins; i++)
|
||||
{
|
||||
vintxids.push_back(tx.vin[i].prevout.hash);
|
||||
vinprevns.push_back(tx.vin[i].prevout.n);
|
||||
//fprintf(stderr,"%s/v%d ",tx.vin[i].prevout.hash.GetHex().c_str(),tx.vin[i].prevout.n);
|
||||
}
|
||||
for (i=0; i<numvouts; i++)
|
||||
{
|
||||
//char destaddr[64];
|
||||
//Getscriptaddress(destaddr,tx.vout[i].scriptPubKey);
|
||||
//fprintf(stderr,"%s %.8f ",destaddr,(double)tx.vout[i].nValue/COIN);
|
||||
vouts.push_back(tx.vout[i]);
|
||||
}
|
||||
data << E_MARSHAL(ss << vintxids << vinprevns << vouts << voutpubtxids);
|
||||
//fprintf(stderr,"numvins.%d numvouts.%d size of data.%d\n",numvins,numvouts,(int32_t)data.size());
|
||||
hash = Hash(data.begin(),data.end());
|
||||
memcpy(msg,&hash,sizeof(hash));
|
||||
return(0);
|
||||
}
|
||||
|
||||
CScript dilithium_registeropret(std::string handle,CPubKey pk,std::vector<uint8_t> bigpub)
|
||||
{
|
||||
CScript opret; uint8_t evalcode = EVAL_DILITHIUM;
|
||||
@@ -2969,6 +3046,24 @@ uint8_t dilithium_spendopretdecode(uint256 &destpubtxid,std::vector<uint8_t> &si
|
||||
return(0);
|
||||
}
|
||||
|
||||
CScript dilithium_Qsendopret(uint256 destpubtxid,std::vector<uint8_t>sig,std::vector<uint256> voutpubtxids)
|
||||
{
|
||||
CScript opret; uint8_t evalcode = EVAL_DILITHIUM;
|
||||
opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'Q' << destpubtxid << sig << voutpubtxids);
|
||||
return(opret);
|
||||
}
|
||||
|
||||
uint8_t dilithium_Qsendopretdecode(uint256 &destpubtxid,std::vector<uint8_t>&sig,std::vector<uint256> &voutpubtxids,CScript scriptPubKey)
|
||||
{
|
||||
std::vector<uint8_t> vopret; uint8_t e,f;
|
||||
GetOpReturnData(scriptPubKey,vopret);
|
||||
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> destpubtxid; ss >> sig; ss >> voutpubtxids) != 0 && e == EVAL_DILITHIUM && f == 'Q' )
|
||||
{
|
||||
return(f);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
UniValue dilithium_rawtxresult(UniValue &result,std::string rawtx)
|
||||
{
|
||||
CTransaction tx;
|
||||
@@ -3014,14 +3109,17 @@ char *dilithium_hexstr(char *str,uint8_t *buf,int32_t len)
|
||||
|
||||
int32_t dilithium_bigpubget(std::string &handle,CPubKey &pk33,uint8_t *pk,uint256 pubtxid)
|
||||
{
|
||||
CTransaction tx; uint256 hashBlock; int32_t numvouts; std::vector<uint8_t> bigpub;
|
||||
if ( myGetTransaction(pubtxid,tx,hashBlock) != 0 && (numvouts= tx.vout.size()) > 1 )
|
||||
CTransaction tx; uint8_t funcid; uint256 hashBlock; int32_t numvouts=0; std::vector<uint8_t> bigpub;
|
||||
if ( myGetTransaction(pubtxid,tx,hashBlock) != 0 )
|
||||
{
|
||||
if ( dilithium_registeropretdecode(handle,pk33,bigpub,tx.vout[numvouts-1].scriptPubKey) == 'R' && bigpub.size() == CRYPTO_PUBLICKEYBYTES )
|
||||
if ( (numvouts= tx.vout.size()) > 1 )
|
||||
{
|
||||
memcpy(pk,&bigpub[0],CRYPTO_PUBLICKEYBYTES);
|
||||
return(0);
|
||||
} else return(-2);
|
||||
if ( (funcid= dilithium_registeropretdecode(handle,pk33,bigpub,tx.vout[numvouts-1].scriptPubKey)) == 'R' && bigpub.size() == CRYPTO_PUBLICKEYBYTES )
|
||||
{
|
||||
memcpy(pk,&bigpub[0],CRYPTO_PUBLICKEYBYTES);
|
||||
return(0);
|
||||
} else return(-2);
|
||||
}
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
@@ -3051,12 +3149,20 @@ UniValue dilithium_keypair(uint64_t txfee,struct CCcontract_info *cp,cJSON *para
|
||||
return(result);
|
||||
}
|
||||
|
||||
CPubKey Faucet_pubkeyget()
|
||||
{
|
||||
struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_FAUCET);
|
||||
return(GetUnspendable(cp,0));
|
||||
}
|
||||
|
||||
UniValue dilithium_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
{
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
UniValue result(UniValue::VOBJ); std::string rawtx; CPubKey mypk,dilithiumpk; uint8_t seed[SEEDBYTES],pk[CRYPTO_PUBLICKEYBYTES],sk[CRYPTO_SECRETKEYBYTES]; char coinaddr[64],str[CRYPTO_SECRETKEYBYTES*2+1]; std::vector<uint8_t> bigpub; int32_t i,n,warningflag = 0;
|
||||
UniValue result(UniValue::VOBJ); std::string rawtx; CPubKey faucetpk,mypk,dilithiumpk; uint8_t seed[SEEDBYTES],pk[CRYPTO_PUBLICKEYBYTES],sk[CRYPTO_SECRETKEYBYTES]; char coinaddr[64],str[CRYPTO_SECRETKEYBYTES*2+1]; int64_t CCchange,inputs; std::vector<uint8_t> bigpub; int32_t i,n,warningflag = 0;
|
||||
if ( txfee == 0 )
|
||||
txfee = DILITHIUM_TXFEE;
|
||||
faucetpk = Faucet_pubkeyget();
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
dilithiumpk = GetUnspendable(cp,0);
|
||||
if ( params != 0 && ((n= cJSON_GetArraySize(params)) == 1 || n == 2) )
|
||||
@@ -3073,14 +3179,23 @@ UniValue dilithium_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *par
|
||||
result.push_back(Pair("skaddr",dilithium_addr(coinaddr,sk,CRYPTO_SECRETKEYBYTES)));
|
||||
for (i=0; i<CRYPTO_PUBLICKEYBYTES; i++)
|
||||
bigpub.push_back(pk[i]);
|
||||
if ( AddNormalinputs(mtx,mypk,3*txfee,64) >= 3*txfee )
|
||||
if ( (inputs= AddCClibtxfee(cp,mtx,dilithiumpk)) > 0 )
|
||||
{
|
||||
mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,dilithiumpk));
|
||||
mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,mypk));
|
||||
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,dilithium_registeropret(handle,mypk,bigpub));
|
||||
return(musig_rawtxresult(result,rawtx));
|
||||
} else return(cclib_error(result,"couldnt find enough funds"));
|
||||
} else return(cclib_error(result,"not enough parameters"));
|
||||
if ( inputs > txfee )
|
||||
CCchange = (inputs - txfee);
|
||||
else CCchange = 0;
|
||||
if ( AddNormalinputs(mtx,mypk,COIN+3*txfee,64) >= 3*txfee )
|
||||
{
|
||||
mtx.vout.push_back(MakeCC1vout(cp->evalcode,2*txfee,dilithiumpk));
|
||||
mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,mypk));
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_FAUCET,COIN,faucetpk));
|
||||
if ( CCchange != 0 )
|
||||
mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange,dilithiumpk));
|
||||
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,dilithium_registeropret(handle,mypk,bigpub));
|
||||
return(musig_rawtxresult(result,rawtx));
|
||||
} else return(cclib_error(result,"couldnt find enough funds"));
|
||||
} else return(cclib_error(result,"not enough parameters"));
|
||||
} else return(cclib_error(result,"not dilithiumpk funds"));
|
||||
}
|
||||
|
||||
UniValue dilithium_sign(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
@@ -3169,16 +3284,6 @@ UniValue dilithium_send(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
} else return(cclib_error(result,"not enough parameters"));
|
||||
}
|
||||
|
||||
/*
|
||||
ultimately what is needed is to be able to scan all utxos to the CC address and be able to spend many vins in the same tx. to do this the opreturn would need to be able to have txid of special with the sigs. However, it is complicated by the need to create a specific message to sign that is the desired outputs and all the inputs. Also, to properly be able to do change and keep everything in dilithium outputs, there needs to be a second destpub.
|
||||
|
||||
so the proposed opreturn for spend would be:
|
||||
|
||||
destpubtxid0, destpubtxid1 (zeroid if only 1), vector of sigs/sigtxid where if it is len 32 it is a txid that just has the sig in the opreturn.
|
||||
|
||||
however, for now, to keep things simple we will only support spending a specific txid to normal output to avoid needing a combined opreturn and other complications.
|
||||
*/
|
||||
|
||||
UniValue dilithium_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
{
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
@@ -3229,10 +3334,320 @@ UniValue dilithium_spend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params
|
||||
} else return(cclib_error(result,"need to have exactly 2 params sendtxid, scriptPubKey"));
|
||||
}
|
||||
|
||||
int64_t dilithium_inputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,uint256 destpubtxid,int64_t total,int32_t maxinputs,char *cmpaddr)
|
||||
{
|
||||
char coinaddr[64]; int64_t threshold,nValue,price,totalinputs = 0; uint256 checktxid,txid,hashBlock; std::vector<uint8_t> origpubkey,tmpsig; CTransaction vintx; int32_t vout,numvouts,n = 0; std::vector<uint256> voutpubtxids;
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
GetCCaddress(cp,coinaddr,pk);
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
if ( maxinputs > CC_MAXVINS )
|
||||
maxinputs = CC_MAXVINS;
|
||||
if ( maxinputs > 0 )
|
||||
threshold = total/maxinputs;
|
||||
else threshold = total;
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||
{
|
||||
txid = it->first.txhash;
|
||||
vout = (int32_t)it->first.index;
|
||||
//char str[65]; fprintf(stderr,"%s check %s/v%d %.8f vs %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN,(double)threshold/COIN);
|
||||
if ( it->second.satoshis < threshold || it->second.satoshis == DILITHIUM_TXFEE )
|
||||
continue;
|
||||
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 && (numvouts= vintx.vout.size()) > 1 )
|
||||
{
|
||||
if ( (nValue= IsCClibvout(cp,vintx,vout,cmpaddr)) > DILITHIUM_TXFEE && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
|
||||
{
|
||||
if ( (dilithium_Qsendopretdecode(checktxid,tmpsig,voutpubtxids,vintx.vout[numvouts-1].scriptPubKey) == 'Q' && vout < voutpubtxids.size() && destpubtxid == voutpubtxids[vout]) || (dilithium_sendopretdecode(checktxid,vintx.vout[numvouts-1].scriptPubKey) == 'x' && destpubtxid == checktxid) )
|
||||
{
|
||||
if ( total != 0 && maxinputs != 0 )
|
||||
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
|
||||
nValue = it->second.satoshis;
|
||||
totalinputs += nValue;
|
||||
n++;
|
||||
if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
|
||||
break;
|
||||
}
|
||||
} //else fprintf(stderr,"nValue %.8f too small or already spent in mempool\n",(double)nValue/COIN);
|
||||
} else fprintf(stderr,"couldnt get tx\n");
|
||||
}
|
||||
return(totalinputs);
|
||||
}
|
||||
|
||||
UniValue dilithium_Qsend(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
{
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
UniValue result(UniValue::VOBJ); std::string rawtx; CPubKey mypk,destpub33; CTransaction tx,vintx; uint256 prevhash,mypubtxid,hashBlock,destpubtxid; int64_t amount,inputsum,outputsum,change; int32_t i,smlen,n,numvouts; char str[129],myCCaddr[64],*scriptstr; CTxOut vout; std::string handle; uint8_t pk[CRYPTO_PUBLICKEYBYTES],pk2[CRYPTO_PUBLICKEYBYTES],sk[CRYPTO_SECRETKEYBYTES],msg[32],seed[32]; std::vector<uint8_t> sig; std::vector<uint256> voutpubtxids;
|
||||
if ( txfee == 0 )
|
||||
txfee = DILITHIUM_TXFEE;
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
GetCCaddress(cp,myCCaddr,mypk);
|
||||
if ( params != 0 && (n= cJSON_GetArraySize(params)) >= 4 && (n & 1) == 0 )
|
||||
{
|
||||
mypubtxid = juint256(jitem(params,0));
|
||||
if ( cclib_parsehash(seed,jitem(params,1),32) < 0 )
|
||||
{
|
||||
Myprivkey(seed);
|
||||
result.push_back(Pair("warning","test mode using privkey for -pubkey, only for testing. there is no point using quantum secure signing if you are using a privkey with a known secp256k1 pubkey!!"));
|
||||
}
|
||||
_dilithium_keypair(pk,sk,seed);
|
||||
outputsum = 0;
|
||||
for (i=2; i<n; i+=2)
|
||||
{
|
||||
amount = jdouble(jitem(params,i+1),0)*COIN + 0.0000000049;
|
||||
scriptstr = jstr(jitem(params,i),0);
|
||||
if ( is_hexstr(scriptstr,0) == 64 )
|
||||
{
|
||||
prevhash = juint256(jitem(params,i));
|
||||
if ( dilithium_bigpubget(handle,destpub33,pk2,prevhash) < 0 )
|
||||
{
|
||||
result.push_back(Pair("destpubtxid",prevhash.GetHex().c_str()));
|
||||
return(cclib_error(result,"couldnt find bigpub at destpubtxid"));
|
||||
}
|
||||
else
|
||||
{
|
||||
mtx.vout.push_back(MakeCC1vout(cp->evalcode,amount,destpub33));
|
||||
voutpubtxids.push_back(prevhash); // binds destpub22 CC addr with dilithium bigpub
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CScript scriptPubKey;
|
||||
scriptPubKey.resize(strlen(scriptstr)/2);
|
||||
decode_hex(&scriptPubKey[0],strlen(scriptstr)/2,scriptstr);
|
||||
vout.nValue = amount;
|
||||
vout.scriptPubKey = scriptPubKey;
|
||||
mtx.vout.push_back(vout);
|
||||
voutpubtxids.push_back(zeroid);
|
||||
}
|
||||
outputsum += amount;
|
||||
}
|
||||
if ( (inputsum= dilithium_inputs(cp,mtx,mypk,mypubtxid,outputsum+txfee,64,myCCaddr)) >= outputsum+txfee )
|
||||
{
|
||||
change = (inputsum - outputsum - txfee);
|
||||
if ( change >= txfee )
|
||||
{
|
||||
mtx.vout.push_back(MakeCC1vout(cp->evalcode,change,mypk));
|
||||
voutpubtxids.push_back(mypubtxid);
|
||||
}
|
||||
tx = mtx;
|
||||
dilithium_Qmsghash(msg,tx,(int32_t)voutpubtxids.size(),voutpubtxids);
|
||||
//for (i=0; i<32; i++)
|
||||
// fprintf(stderr,"%02x",msg[i]);
|
||||
//fprintf(stderr," msg\n");
|
||||
sig.resize(32+CRYPTO_BYTES);
|
||||
if ( dilithium_bigpubget(handle,destpub33,pk2,mypubtxid) < 0 )
|
||||
return(cclib_error(result,"couldnt get bigpub"));
|
||||
else if ( memcmp(pk,pk2,sizeof(pk)) != 0 )
|
||||
return(cclib_error(result,"dilithium bigpub mismatch"));
|
||||
else if ( destpub33 != mypk )
|
||||
return(cclib_error(result,"destpub33 is not for this -pubkey"));
|
||||
else if ( _dilithium_sign(&sig[0],&smlen,msg,32,sk) < 0 )
|
||||
return(cclib_error(result,"dilithium signing error"));
|
||||
else if ( smlen != 32+CRYPTO_BYTES )
|
||||
return(cclib_error(result,"siglen error"));
|
||||
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,dilithium_Qsendopret(mypubtxid,sig,voutpubtxids));
|
||||
return(dilithium_rawtxresult(result,rawtx));
|
||||
} else return(cclib_error(result,"Q couldnt find enough Q or x inputs"));
|
||||
} else return(cclib_error(result,"need to have exactly 2 params sendtxid, scriptPubKey"));
|
||||
}
|
||||
|
||||
bool dilithium_Qvalidate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx)
|
||||
{
|
||||
int32_t i,numvins,numvouts,mlen,smlen=CRYPTO_BYTES+32; CPubKey destpub33; std::string handle; uint256 tmptxid,hashBlock,destpubtxid,signerpubtxid; CTransaction vintx; std::vector<uint8_t> tmpsig,sig,vopret; uint8_t msg[32],msg2[CRYPTO_BYTES+32],pk[CRYPTO_PUBLICKEYBYTES],*script; std::vector<uint256> voutpubtxids;
|
||||
numvins = tx.vin.size();
|
||||
signerpubtxid = zeroid;
|
||||
for (i=0; i<numvins; i++)
|
||||
{
|
||||
if ( IsCCInput(tx.vin[i].scriptSig) != 0 )
|
||||
{
|
||||
if ( myGetTransaction(tx.vin[i].prevout.hash,vintx,hashBlock) != 0 && (numvouts= vintx.vout.size()) > 1 )
|
||||
{
|
||||
GetOpReturnData(vintx.vout[numvouts-1].scriptPubKey,vopret);
|
||||
script = (uint8_t *)vopret.data();
|
||||
if ( script[1] == 'Q' )
|
||||
{
|
||||
if ( dilithium_Qsendopretdecode(tmptxid,tmpsig,voutpubtxids,vintx.vout[numvouts-1].scriptPubKey) != 'Q' )
|
||||
return eval->Invalid("couldnt decode destpubtxid from Qsend");
|
||||
else if ( tx.vin[i].prevout.n > voutpubtxids.size() )
|
||||
return eval->Invalid("no destpubtxid for prevout.n");
|
||||
destpubtxid = voutpubtxids[tx.vin[i].prevout.n];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( dilithium_sendopretdecode(destpubtxid,vintx.vout[numvouts-1].scriptPubKey) != 'x' )
|
||||
return eval->Invalid("couldnt decode destpubtxid from send");
|
||||
}
|
||||
if ( signerpubtxid == zeroid )
|
||||
signerpubtxid = destpubtxid;
|
||||
else if ( destpubtxid != signerpubtxid )
|
||||
return eval->Invalid("destpubtxid of vini doesnt match first one");
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( signerpubtxid != zeroid )
|
||||
{
|
||||
numvouts = tx.vout.size();
|
||||
if ( dilithium_Qsendopretdecode(destpubtxid,sig,voutpubtxids,tx.vout[numvouts-1].scriptPubKey) == 'Q' && destpubtxid == signerpubtxid && sig.size() == smlen )
|
||||
{
|
||||
if ( dilithium_Qmsghash(msg,tx,numvouts-1,voutpubtxids) < 0 )
|
||||
return eval->Invalid("couldnt get Qmsghash");
|
||||
else if ( dilithium_bigpubget(handle,destpub33,pk,signerpubtxid) < 0 )
|
||||
return eval->Invalid("couldnt get bigpub");
|
||||
else
|
||||
{
|
||||
if ( _dilithium_verify(msg2,&mlen,&sig[0],smlen,pk) < 0 )
|
||||
return eval->Invalid("failed dilithium verify");
|
||||
else if ( mlen != 32 || memcmp(msg,msg2,32) != 0 )
|
||||
{
|
||||
for (i=0; i<32; i++)
|
||||
fprintf(stderr,"%02x",msg[i]);
|
||||
fprintf(stderr," vs ");
|
||||
for (i=0; i<mlen; i++)
|
||||
fprintf(stderr,"%02x",msg2[i]);
|
||||
fprintf(stderr,"mlen.%d\n",mlen);
|
||||
return eval->Invalid("failed dilithium msg verify");
|
||||
}
|
||||
else return true;
|
||||
}
|
||||
} else return eval->Invalid("failed decode Qsend");
|
||||
} else return eval->Invalid("unexpected zero signerpubtxid");
|
||||
}
|
||||
|
||||
int32_t dilithium_registrationpub33(char *pkaddr,CPubKey &pub33,uint256 txid)
|
||||
{
|
||||
std::string handle; std::vector<uint8_t> bigpub; CTransaction tx; uint256 hashBlock; int32_t numvouts;
|
||||
pkaddr[0] = 0;
|
||||
if ( myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts= tx.vout.size()) > 1 )
|
||||
{
|
||||
if ( dilithium_registeropretdecode(handle,pub33,bigpub,tx.vout[numvouts-1].scriptPubKey) == 'R' )
|
||||
{
|
||||
dilithium_addr(pkaddr,&bigpub[0],CRYPTO_PUBLICKEYBYTES);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
void dilithium_handleinit(struct CCcontract_info *cp)
|
||||
{
|
||||
static int32_t didinit;
|
||||
std::vector<std::pair<CAddressIndexKey, CAmount> > txids; struct dilithium_handle *hashstr; CPubKey dilithiumpk,pub33; uint256 txid,hashBlock; CTransaction txi; int32_t numvouts; std::vector<uint8_t> bigpub; std::string handle; char CCaddr[64];
|
||||
if ( didinit != 0 )
|
||||
return;
|
||||
pthread_mutex_init(&DILITHIUM_MUTEX,NULL);
|
||||
dilithiumpk = GetUnspendable(cp,0);
|
||||
GetCCaddress(cp,CCaddr,dilithiumpk);
|
||||
SetCCtxids(txids,CCaddr);
|
||||
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=txids.begin(); it!=txids.end(); it++)
|
||||
{
|
||||
txid = it->first.txhash;
|
||||
if ( myGetTransaction(txid,txi,hashBlock) != 0 && (numvouts= txi.vout.size()) > 1 )
|
||||
{
|
||||
if ( dilithium_registeropretdecode(handle,pub33,bigpub,txi.vout[numvouts-1].scriptPubKey) == 'R' )
|
||||
{
|
||||
if ( (hashstr= dilithium_handlenew((char *)handle.c_str())) != 0 )
|
||||
{
|
||||
if ( hashstr->destpubtxid != txid )
|
||||
{
|
||||
if ( hashstr->destpubtxid != zeroid )
|
||||
fprintf(stderr,"overwriting %s %s with %s\n",handle.c_str(),hashstr->destpubtxid.GetHex().c_str(),txid.GetHex().c_str());
|
||||
fprintf(stderr,"%s <- %s\n",handle.c_str(),txid.GetHex().c_str());
|
||||
hashstr->destpubtxid = txid;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
didinit = 1;
|
||||
}
|
||||
|
||||
UniValue dilithium_handleinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ); CPubKey pub33; int32_t i,n; char *handlestr,pkaddr[64],str[67]; struct dilithium_handle *hashstr;
|
||||
if ( params != 0 && (n= cJSON_GetArraySize(params)) == 1 )
|
||||
{
|
||||
dilithium_handleinit(cp);
|
||||
if ( (handlestr= jstr(jitem(params,0),0)) != 0 )
|
||||
{
|
||||
result.push_back(Pair("result","success"));
|
||||
result.push_back(Pair("handle",handlestr));
|
||||
if ( (hashstr= dilithium_handlefind(handlestr)) != 0 )
|
||||
{
|
||||
result.push_back(Pair("destpubtxid",hashstr->destpubtxid.GetHex().c_str()));
|
||||
if ( dilithium_registrationpub33(pkaddr,pub33,hashstr->destpubtxid) == 0 )
|
||||
{
|
||||
for (i=0; i<33; i++)
|
||||
sprintf(&str[i<<1],"%02x",((uint8_t *)pub33.begin())[i]);
|
||||
str[i<<1] = 0;
|
||||
result.push_back(Pair("pkaddr",pkaddr));
|
||||
}
|
||||
result.push_back(Pair("pubkey",str));
|
||||
} else result.push_back(Pair("status","available"));
|
||||
return(result);
|
||||
}
|
||||
}
|
||||
result.push_back(Pair("result","error"));
|
||||
return(result);
|
||||
}
|
||||
|
||||
bool dilithium_Rvalidate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx)
|
||||
{
|
||||
static int32_t didinit;
|
||||
uint256 txid; int32_t numvouts; struct dilithium_handle *hashstr; std::string handle; std::vector<uint8_t> bigpub; CPubKey oldpub33,pub33,dilithiumpk; CTxOut vout,vout0; char pkaddr[64];
|
||||
if ( height < 14500 )
|
||||
return(true);
|
||||
dilithium_handleinit(cp);
|
||||
dilithiumpk = GetUnspendable(cp,0);
|
||||
if ( (numvouts= tx.vout.size()) <= 1 )
|
||||
return eval->Invalid("not enough vouts for registration tx");
|
||||
else if ( dilithium_registeropretdecode(handle,pub33,bigpub,tx.vout[numvouts-1].scriptPubKey) == 'R' )
|
||||
{
|
||||
// relies on all current block tx to be put into mempool
|
||||
txid = tx.GetHash();
|
||||
vout0 = MakeCC1vout(cp->evalcode,2*DILITHIUM_TXFEE,dilithiumpk);
|
||||
vout = MakeCC1vout(EVAL_FAUCET,COIN,Faucet_pubkeyget());
|
||||
if ( tx.vout[0] != vout0 )
|
||||
return eval->Invalid("mismatched vout0 for register");
|
||||
else if ( tx.vout[1].nValue != DILITHIUM_TXFEE )
|
||||
return eval->Invalid("vout1 for register not txfee");
|
||||
else if ( tx.vout[2] != vout )
|
||||
return eval->Invalid("register not sending to faucet");
|
||||
else if ( (hashstr= dilithium_handlenew((char *)handle.c_str())) == 0 )
|
||||
return eval->Invalid("error creating dilithium handle");
|
||||
else if ( hashstr->destpubtxid == zeroid )
|
||||
{
|
||||
hashstr->destpubtxid = txid;
|
||||
return(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( hashstr->destpubtxid == txid )
|
||||
return(true);
|
||||
else if ( dilithium_registrationpub33(pkaddr,oldpub33,hashstr->destpubtxid) == 0 )
|
||||
{
|
||||
if ( oldpub33 == pub33 )
|
||||
{
|
||||
hashstr->destpubtxid = txid;
|
||||
fprintf(stderr,"ht.%d %s <- %s\n",height,handle.c_str(),txid.GetHex().c_str());
|
||||
return(true);
|
||||
}
|
||||
}
|
||||
return eval->Invalid("duplicate dilithium handle rejected");
|
||||
}
|
||||
} else return eval->Invalid("couldnt decode register opret");
|
||||
}
|
||||
|
||||
bool dilithium_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx)
|
||||
{
|
||||
CPubKey destpub33; std::string handle; uint256 hashBlock,destpubtxid,checktxid; CTransaction vintx; int32_t numvouts,mlen,smlen=CRYPTO_BYTES+32; std::vector<uint8_t> sig; uint8_t msg[32],msg2[CRYPTO_BYTES+32],pk[CRYPTO_PUBLICKEYBYTES];
|
||||
if ( tx.vout.size() != 2 )
|
||||
CPubKey destpub33; std::string handle; uint256 hashBlock,destpubtxid,checktxid; CTransaction vintx; int32_t numvouts,mlen,smlen=CRYPTO_BYTES+32; std::vector<uint8_t> sig,vopret; uint8_t msg[32],msg2[CRYPTO_BYTES+32],pk[CRYPTO_PUBLICKEYBYTES],*script;
|
||||
// if all dilithium tx -> do multispend/send, else:
|
||||
numvouts = tx.vout.size();
|
||||
GetOpReturnData(tx.vout[numvouts-1].scriptPubKey,vopret);
|
||||
script = (uint8_t *)vopret.data();
|
||||
if ( script[1] == 'R' )
|
||||
return(dilithium_Rvalidate(cp,height,eval,tx));
|
||||
else if ( script[1] == 'Q' )
|
||||
return(dilithium_Qvalidate(cp,height,eval,tx));
|
||||
else if ( tx.vout.size() != 2 )
|
||||
return eval->Invalid("numvouts != 2");
|
||||
else if ( tx.vin.size() != 1 )
|
||||
return eval->Invalid("numvins != 1");
|
||||
|
||||
@@ -154,46 +154,17 @@ int32_t Eval::GetNotaries(uint8_t pubkeys[64][33], int32_t height, uint32_t time
|
||||
return komodo_notaries(pubkeys, height, timestamp);
|
||||
}
|
||||
|
||||
|
||||
bool Eval::CheckNotaryInputs(const CTransaction &tx, uint32_t height, uint32_t timestamp) const
|
||||
{
|
||||
if (tx.vin.size() < 11) return false;
|
||||
|
||||
uint8_t seenNotaries[64] = {0};
|
||||
uint8_t notaries[64][33];
|
||||
int nNotaries = GetNotaries(notaries, height, timestamp);
|
||||
CrosschainAuthority auth;
|
||||
auth.requiredSigs = 11;
|
||||
auth.size = GetNotaries(auth.notaries, height, timestamp);
|
||||
|
||||
BOOST_FOREACH(const CTxIn &txIn, tx.vin)
|
||||
{
|
||||
// Get notary pubkey
|
||||
CTransaction tx;
|
||||
uint256 hashBlock;
|
||||
if (!GetTxUnconfirmed(txIn.prevout.hash, tx, hashBlock)) return false;
|
||||
if (tx.vout.size() < txIn.prevout.n) return false;
|
||||
CScript spk = tx.vout[txIn.prevout.n].scriptPubKey;
|
||||
if (spk.size() != 35) return false;
|
||||
std::vector<unsigned char> scriptVec = std::vector<unsigned char>(spk.begin(),spk.end());
|
||||
const unsigned char *pk = scriptVec.data();
|
||||
if (pk++[0] != 33) return false;
|
||||
if (pk[33] != OP_CHECKSIG) return false;
|
||||
|
||||
// Check it's a notary
|
||||
for (int i=0; i<nNotaries; i++) {
|
||||
if (!seenNotaries[i]) {
|
||||
if (memcmp(pk, notaries[i], 33) == 0) {
|
||||
seenNotaries[i] = 1;
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
found:;
|
||||
}
|
||||
|
||||
return true;
|
||||
return CheckTxAuthority(tx, auth);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get MoM from a notarisation tx hash (on KMD)
|
||||
*/
|
||||
|
||||
@@ -146,7 +146,11 @@ int64_t AddFaucetInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPub
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
GetCCaddress(cp,coinaddr,pk);
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
threshold = total/(maxinputs+1);
|
||||
if ( maxinputs > CC_MAXVINS )
|
||||
maxinputs = CC_MAXVINS;
|
||||
if ( maxinputs > 0 )
|
||||
threshold = total/maxinputs;
|
||||
else threshold = total;
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||
{
|
||||
txid = it->first.txhash;
|
||||
|
||||
@@ -157,19 +157,21 @@ CScript EncodeGatewaysBindOpRet(uint8_t funcid,uint256 tokenid,std::string coin,
|
||||
{
|
||||
CScript opret; uint8_t evalcode = EVAL_GATEWAYS; struct CCcontract_info *cp,C; CPubKey gatewayspk;
|
||||
std::vector<CPubKey> pubkeys;
|
||||
vscript_t vopret;
|
||||
|
||||
cp = CCinit(&C,EVAL_GATEWAYS);
|
||||
gatewayspk = GetUnspendable(cp,0);
|
||||
pubkeys.push_back(gatewayspk);
|
||||
opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << coin << totalsupply << oracletxid << M << N << gatewaypubkeys << taddr << prefix << prefix2 << wiftype);
|
||||
return(EncodeTokenOpRet(tokenid,pubkeys,opret));
|
||||
vopret = E_MARSHAL(ss << evalcode << funcid << coin << totalsupply << oracletxid << M << N << gatewaypubkeys << taddr << prefix << prefix2 << wiftype);
|
||||
return(EncodeTokenOpRet(tokenid,pubkeys, std::make_pair(OPRETID_GATEWAYSDATA, vopret)));
|
||||
}
|
||||
|
||||
uint8_t DecodeGatewaysBindOpRet(char *depositaddr,const CScript &scriptPubKey,uint256 &tokenid,std::string &coin,int64_t &totalsupply,uint256 &oracletxid,uint8_t &M,uint8_t &N,std::vector<CPubKey> &gatewaypubkeys,uint8_t &taddr,uint8_t &prefix,uint8_t &prefix2,uint8_t wiftype)
|
||||
uint8_t DecodeGatewaysBindOpRet(char *depositaddr,const CScript &scriptPubKey,uint256 &tokenid,std::string &coin,int64_t &totalsupply,uint256 &oracletxid,uint8_t &M,uint8_t &N,std::vector<CPubKey> &gatewaypubkeys,uint8_t &taddr,uint8_t &prefix,uint8_t &prefix2,uint8_t &wiftype)
|
||||
{
|
||||
std::vector<std::pair<uint8_t, vscript_t>> oprets;
|
||||
std::vector<uint8_t> vopret,vOpretExtra; uint8_t *script,e,f,tokenevalcode; std::vector<CPubKey> pubkeys;
|
||||
|
||||
if (DecodeTokenOpRet(scriptPubKey,tokenevalcode,tokenid,pubkeys,vOpretExtra)!=0 && tokenevalcode==EVAL_TOKENS && vOpretExtra.size()>0)
|
||||
if (DecodeTokenOpRet(scriptPubKey,tokenevalcode,tokenid,pubkeys,oprets)!=0 && GetOpretBlob(oprets, OPRETID_GATEWAYSDATA, vOpretExtra) && tokenevalcode==EVAL_TOKENS && vOpretExtra.size()>0)
|
||||
{
|
||||
vopret=vOpretExtra;
|
||||
}
|
||||
@@ -183,7 +185,7 @@ uint8_t DecodeGatewaysBindOpRet(char *depositaddr,const CScript &scriptPubKey,ui
|
||||
if ( N > 1 )
|
||||
{
|
||||
strcpy(depositaddr,CBitcoinAddress(CScriptID(GetScriptForMultisig(M,gatewaypubkeys))).ToString().c_str());
|
||||
LogPrint("gatewayscc-1","f.%c M.%d of N.%d size.%d -> %s\n",f,M,N,(int32_t)gatewaypubkeys.size(),depositaddr);
|
||||
LOGSTREAM("gatewayscc", CCLOG_DEBUG1, stream << "f." << f << " M." << M << " of N." << N << " size." << (int32_t)gatewaypubkeys.size() << " -> " << depositaddr << std::endl);
|
||||
} else Getscriptaddress(depositaddr,CScript() << ParseHex(HexStr(gatewaypubkeys[0])) << OP_CHECKSIG);
|
||||
}
|
||||
else
|
||||
@@ -192,7 +194,7 @@ uint8_t DecodeGatewaysBindOpRet(char *depositaddr,const CScript &scriptPubKey,ui
|
||||
else GetCustomscriptaddress(depositaddr,CScript() << ParseHex(HexStr(gatewaypubkeys[0])) << OP_CHECKSIG,taddr,prefix,prefix2);
|
||||
}
|
||||
return(f);
|
||||
} else LogPrint("gatewayscc-1","error decoding bind opret\n");
|
||||
} else LOGSTREAM("gatewayscc",CCLOG_DEBUG1, stream << "error decoding bind opret" << std::endl);
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -221,17 +223,19 @@ CScript EncodeGatewaysClaimOpRet(uint8_t funcid,uint256 tokenid,uint256 bindtxid
|
||||
{
|
||||
CScript opret; uint8_t evalcode = EVAL_GATEWAYS; struct CCcontract_info *cp,C; CPubKey gatewayspk;
|
||||
std::vector<CPubKey> pubkeys;
|
||||
vscript_t vopret;
|
||||
|
||||
pubkeys.push_back(destpub);
|
||||
opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << bindtxid << refcoin << deposittxid << destpub << amount);
|
||||
return(EncodeTokenOpRet(tokenid,pubkeys,opret));
|
||||
vopret = /*<< OP_RETURN <<*/ E_MARSHAL(ss << evalcode << funcid << bindtxid << refcoin << deposittxid << destpub << amount);
|
||||
return(EncodeTokenOpRet(tokenid,pubkeys, make_pair(OPRETID_GATEWAYSDATA, vopret)));
|
||||
}
|
||||
|
||||
uint8_t DecodeGatewaysClaimOpRet(const CScript &scriptPubKey,uint256 &tokenid,uint256 &bindtxid,std::string &refcoin,uint256 &deposittxid,CPubKey &destpub,int64_t &amount)
|
||||
{
|
||||
std::vector<std::pair<uint8_t, vscript_t>> oprets;
|
||||
std::vector<uint8_t> vopret,vOpretExtra; uint8_t *script,e,f,tokenevalcode; std::vector<CPubKey> pubkeys;
|
||||
|
||||
if (DecodeTokenOpRet(scriptPubKey,tokenevalcode,tokenid,pubkeys,vOpretExtra)!=0 && tokenevalcode==EVAL_TOKENS && vOpretExtra.size()>0)
|
||||
if (DecodeTokenOpRet(scriptPubKey,tokenevalcode,tokenid,pubkeys, oprets)!=0 && GetOpretBlob(oprets, OPRETID_GATEWAYSDATA, vOpretExtra) && tokenevalcode==EVAL_TOKENS && vOpretExtra.size()>0)
|
||||
{
|
||||
vopret=vOpretExtra;
|
||||
}
|
||||
@@ -248,19 +252,21 @@ CScript EncodeGatewaysWithdrawOpRet(uint8_t funcid,uint256 tokenid,uint256 bindt
|
||||
{
|
||||
CScript opret; uint8_t evalcode = EVAL_GATEWAYS; struct CCcontract_info *cp,C; CPubKey gatewayspk;
|
||||
std::vector<CPubKey> pubkeys;
|
||||
vscript_t vopret;
|
||||
|
||||
cp = CCinit(&C,EVAL_GATEWAYS);
|
||||
gatewayspk = GetUnspendable(cp,0);
|
||||
pubkeys.push_back(gatewayspk);
|
||||
opret << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << bindtxid << refcoin << withdrawpub << amount);
|
||||
return(EncodeTokenOpRet(tokenid,pubkeys,opret));
|
||||
vopret = /*opret << OP_RETURN << */ E_MARSHAL(ss << evalcode << funcid << bindtxid << refcoin << withdrawpub << amount);
|
||||
return(EncodeTokenOpRet(tokenid,pubkeys, std::make_pair(OPRETID_GATEWAYSDATA, vopret)));
|
||||
}
|
||||
|
||||
uint8_t DecodeGatewaysWithdrawOpRet(const CScript &scriptPubKey, uint256& tokenid, uint256 &bindtxid, std::string &refcoin, CPubKey &withdrawpub, int64_t &amount)
|
||||
{
|
||||
std::vector<std::pair<uint8_t, vscript_t>> oprets;
|
||||
std::vector<uint8_t> vopret,vOpretExtra; uint8_t *script,e,f,tokenevalcode; std::vector<CPubKey> pubkeys;
|
||||
|
||||
if (DecodeTokenOpRet(scriptPubKey,tokenevalcode,tokenid,pubkeys,vOpretExtra)!=0 && tokenevalcode==EVAL_TOKENS && vOpretExtra.size()>0)
|
||||
if (DecodeTokenOpRet(scriptPubKey,tokenevalcode,tokenid,pubkeys, oprets)!=0 && GetOpretBlob(oprets, OPRETID_GATEWAYSDATA, vOpretExtra) && tokenevalcode==EVAL_TOKENS && vOpretExtra.size()>0)
|
||||
{
|
||||
vopret=vOpretExtra;
|
||||
}
|
||||
@@ -336,9 +342,10 @@ uint8_t DecodeGatewaysMarkDoneOpRet(const CScript &scriptPubKey, uint256 &withdr
|
||||
|
||||
uint8_t DecodeGatewaysOpRet(const CScript &scriptPubKey)
|
||||
{
|
||||
std::vector<std::pair<uint8_t, vscript_t>> oprets;
|
||||
std::vector<uint8_t> vopret,vOpretExtra; uint8_t *script,e,f,tokenevalcode; std::vector<CPubKey> pubkeys; uint256 tokenid;
|
||||
|
||||
if (DecodeTokenOpRet(scriptPubKey,tokenevalcode,tokenid,pubkeys,vOpretExtra)!=0 && tokenevalcode==EVAL_TOKENS && vOpretExtra.size()>0)
|
||||
if (DecodeTokenOpRet(scriptPubKey,tokenevalcode,tokenid,pubkeys, oprets)!=0 && GetOpretBlob(oprets, OPRETID_GATEWAYSDATA, vOpretExtra) && tokenevalcode==EVAL_TOKENS && vOpretExtra.size()>0)
|
||||
{
|
||||
vopret=vOpretExtra;
|
||||
}
|
||||
@@ -374,15 +381,15 @@ bool GatewaysExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransacti
|
||||
numvouts = tx.vout.size();
|
||||
for (i=0; i<numvins; i++)
|
||||
{
|
||||
//LogPrint("gatewayscc","vini.%d\n",i);
|
||||
LOGSTREAM("gatewayscc",CCLOG_DEBUG2, stream << "vini." << i << std::endl);
|
||||
if ( (*cp->ismyvin)(tx.vin[i].scriptSig) != 0 )
|
||||
{
|
||||
//LogPrint("gatewayscc","vini.%d check mempool\n",i);
|
||||
LOGSTREAM("gatewayscc",CCLOG_DEBUG2, stream << "vini." << i << " check mempool" << std::endl);
|
||||
if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 )
|
||||
return eval->Invalid("cant find vinTx");
|
||||
else
|
||||
{
|
||||
//LogPrint("gatewayscc","vini.%d check hash and vout\n",i);
|
||||
LOGSTREAM("gatewayscc",CCLOG_DEBUG2, stream << "vini." << i << " check hash and vout" << std::endl);
|
||||
if ( hashBlock == zerohash )
|
||||
return eval->Invalid("cant Gateways from mempool");
|
||||
if ( (assetoshis= IsGatewaysvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 )
|
||||
@@ -392,13 +399,13 @@ bool GatewaysExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransacti
|
||||
}
|
||||
for (i=0; i<numvouts; i++)
|
||||
{
|
||||
//LogPrint("gatewayscc","i.%d of numvouts.%d\n",i,numvouts);
|
||||
LOGSTREAM("gatewayscc",CCLOG_DEBUG2, stream << "i." << i << " of numvouts." << numvouts << std::endl);
|
||||
if ( (assetoshis= IsGatewaysvout(cp,tx,i)) != 0 )
|
||||
outputs += assetoshis;
|
||||
}
|
||||
if ( inputs != outputs+txfee )
|
||||
{
|
||||
LogPrint("gatewayscc","inputs %llu vs outputs %llu\n",(long long)inputs,(long long)outputs);
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << "inputs " << (long long)inputs << " vs outputs " << (long long)outputs << std::endl);
|
||||
return eval->Invalid("mismatched inputs != outputs + txfee");
|
||||
}
|
||||
else return(true);
|
||||
@@ -418,7 +425,7 @@ static int32_t myIs_coinaddr_inmempoolvout(char *coinaddr)
|
||||
Getscriptaddress(destaddr,tx.vout[i].scriptPubKey);
|
||||
if ( strcmp(destaddr,coinaddr) == 0 )
|
||||
{
|
||||
LogPrint("gatewayscc-1","found (%s) vout in mempool\n",coinaddr);
|
||||
LOGSTREAM("gatewayscc",CCLOG_DEBUG1, stream << "found (" << coinaddr << ") vout in mempool" << std::endl);
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
@@ -431,36 +438,35 @@ uint256 GatewaysReverseScan(uint256 &txid,int32_t height,uint256 reforacletxid,u
|
||||
{
|
||||
CTransaction tx; uint256 hash,mhash,bhash,hashBlock,oracletxid; int32_t len,len2,numvouts; int64_t val,merkleht; CPubKey pk; std::vector<uint8_t>data;
|
||||
txid = zeroid;
|
||||
char str[65];
|
||||
LogPrint("gatewayscc-2","start reverse scan %s\n",uint256_str(str,batontxid));
|
||||
LOGSTREAM("gatewayscc",CCLOG_DEBUG2, stream << "start reverse scan " << batontxid.GetHex() << std::endl);
|
||||
while ( myGetTransaction(batontxid,tx,hashBlock) != 0 && (numvouts= tx.vout.size()) > 0 )
|
||||
{
|
||||
LogPrint("gatewayscc-2","check %s\n",uint256_str(str,batontxid));
|
||||
LOGSTREAM("gatewayscc",CCLOG_DEBUG2, stream << "check " << batontxid.GetHex() << std::endl);
|
||||
if ( DecodeOraclesData(tx.vout[numvouts-1].scriptPubKey,oracletxid,bhash,pk,data) == 'D' && oracletxid == reforacletxid )
|
||||
{
|
||||
LogPrint("gatewayscc-2","decoded %s\n",uint256_str(str,batontxid));
|
||||
LOGSTREAM("gatewayscc",CCLOG_DEBUG2, stream << "decoded " << batontxid.GetHex() << std::endl);
|
||||
if ( oracle_format(&hash,&merkleht,0,'I',(uint8_t *)data.data(),0,(int32_t)data.size()) == sizeof(int32_t) && merkleht == height )
|
||||
{
|
||||
len = oracle_format(&hash,&val,0,'h',(uint8_t *)data.data(),sizeof(int32_t),(int32_t)data.size());
|
||||
len2 = oracle_format(&mhash,&val,0,'h',(uint8_t *)data.data(),(int32_t)(sizeof(int32_t)+sizeof(uint256)),(int32_t)data.size());
|
||||
char str2[65]; LogPrint("gatewayscc","found merkleht.%d len.%d len2.%d %s %s\n",(int32_t)merkleht,len,len2,uint256_str(str,hash),uint256_str(str2,mhash));
|
||||
LOGSTREAM("gatewayscc",CCLOG_DEBUG1, stream << "found merkleht." << (int32_t)merkleht << " len." << len << " len2." << len2 << " " << hash.GetHex() << " " << mhash.GetHex() << std::endl);
|
||||
if ( len == sizeof(hash)+sizeof(int32_t) && len2 == 2*sizeof(mhash)+sizeof(int32_t) && mhash != zeroid )
|
||||
{
|
||||
txid = batontxid;
|
||||
LogPrint("gatewayscc-2","set txid\n");
|
||||
LOGSTREAM("gatewayscc",CCLOG_DEBUG2, stream << "set txid" << std::endl);
|
||||
return(mhash);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogPrint("gatewayscc-2","missing hash\n");
|
||||
LOGSTREAM("gatewayscc",CCLOG_DEBUG2, stream << "missing hash" << std::endl);
|
||||
return(zeroid);
|
||||
}
|
||||
} else LogPrint("gatewayscc-2","height.%d vs search ht.%d\n",(int32_t)merkleht,(int32_t)height);
|
||||
} else LOGSTREAM("gatewayscc",CCLOG_DEBUG2, stream << "height." << (int32_t)merkleht << " vs search ht." << (int32_t)height << std::endl);
|
||||
batontxid = bhash;
|
||||
LogPrint("gatewayscc-2","new hash %s\n",uint256_str(str,batontxid));
|
||||
LOGSTREAM("gatewayscc",CCLOG_DEBUG2, stream << "new hash " << batontxid.GetHex() << std::endl);
|
||||
} else break;
|
||||
}
|
||||
LogPrint("gatewayscc-2","end of loop\n");
|
||||
LOGSTREAM("gatewayscc",CCLOG_DEBUG2, stream << "end of loop\n");
|
||||
return(zeroid);
|
||||
}
|
||||
|
||||
@@ -493,27 +499,27 @@ uint256 BitcoinGetProofMerkleRoot(const std::vector<uint8_t> &proofData, std::ve
|
||||
int64_t GatewaysVerify(char *refdepositaddr,uint256 oracletxid,int32_t claimvout,std::string refcoin,uint256 cointxid,const std::string deposithex,std::vector<uint8_t>proof,uint256 merkleroot,CPubKey destpub,uint8_t taddr,uint8_t prefix,uint8_t prefix2)
|
||||
{
|
||||
std::vector<uint256> txids; uint256 proofroot,hashBlock,txid = zeroid; CTransaction tx; std::string name,description,format;
|
||||
char destaddr[64],destpubaddr[64],claimaddr[64],str[65],str2[65]; int32_t i,numvouts; int64_t nValue = 0;
|
||||
char destaddr[64],destpubaddr[64],claimaddr[64]; int32_t i,numvouts; int64_t nValue = 0;
|
||||
|
||||
if ( myGetTransaction(oracletxid,tx,hashBlock) == 0 || (numvouts= tx.vout.size()) <= 0 )
|
||||
{
|
||||
LogPrint("gatewayscc","GatewaysVerify cant find oracletxid %s\n",uint256_str(str,oracletxid));
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << "GatewaysVerify cant find oracletxid " << oracletxid.GetHex() << std::endl);
|
||||
return(0);
|
||||
}
|
||||
if ( DecodeOraclesCreateOpRet(tx.vout[numvouts-1].scriptPubKey,name,description,format) != 'C' || name != refcoin )
|
||||
{
|
||||
LogPrint("gatewayscc","GatewaysVerify mismatched oracle name %s != %s\n",name.c_str(),refcoin.c_str());
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << "GatewaysVerify mismatched oracle name " << name << " != " << refcoin << std::endl);
|
||||
return(0);
|
||||
}
|
||||
proofroot = BitcoinGetProofMerkleRoot(proof,txids);
|
||||
if ( proofroot != merkleroot )
|
||||
{
|
||||
LogPrint("gatewayscc","GatewaysVerify mismatched merkleroot %s != %s\n",uint256_str(str,proofroot),uint256_str(str2,merkleroot));
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << "GatewaysVerify mismatched merkleroot " << proofroot.GetHex() << " != " << merkleroot.GetHex() << std::endl);
|
||||
return(0);
|
||||
}
|
||||
if (std::find(txids.begin(), txids.end(), cointxid) == txids.end())
|
||||
{
|
||||
LogPrint("gatewayscc", "GatewaysVerify invalid proof for this cointxid\n");
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << "GatewaysVerify invalid proof for this cointxid" << std::endl);
|
||||
return 0;
|
||||
}
|
||||
if ( DecodeHexTx(tx,deposithex) != 0 )
|
||||
@@ -534,10 +540,10 @@ int64_t GatewaysVerify(char *refdepositaddr,uint256 oracletxid,int32_t claimvout
|
||||
}
|
||||
if ( txid == cointxid )
|
||||
{
|
||||
LogPrint("gatewayscc-1","verified proof for cointxid in merkleroot\n");
|
||||
LOGSTREAM("gatewayscc",CCLOG_DEBUG1, stream << "verified proof for cointxid in merkleroot" << std::endl);
|
||||
return(nValue);
|
||||
} else LogPrint("gatewayscc","(%s) != (%s) or txid %s mismatch.%d or script mismatch\n",refdepositaddr,destaddr,uint256_str(str,txid),txid != cointxid);
|
||||
} else LogPrint("gatewayscc","claimaddr.(%s) != destpubaddr.(%s)\n",claimaddr,destpubaddr);
|
||||
} else LOGSTREAM("gatewayscc",CCLOG_INFO, stream << "(" << refdepositaddr << ") != (" << destaddr << ") or txid " << txid.GetHex() << " mismatch." << (txid!=cointxid) << " or script mismatch" << std::endl);
|
||||
} else LOGSTREAM("gatewayscc",CCLOG_INFO, stream << "claimaddr." << claimaddr << " != destpubaddr." << destpubaddr << std::endl);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
@@ -571,7 +577,7 @@ int32_t GatewaysBindExists(struct CCcontract_info *cp,CPubKey gatewayspk,uint256
|
||||
{
|
||||
if ( tokenid == reftokenid )
|
||||
{
|
||||
LogPrint("gatewayscc","trying to bind an existing tokenid\n");
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << "trying to bind an existing tokenid" << std::endl);
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
@@ -869,7 +875,7 @@ bool GatewaysValidate(struct CCcontract_info *cp,Eval *eval,const CTransaction &
|
||||
}
|
||||
retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts);
|
||||
if ( retval != 0 )
|
||||
LogPrint("gatewayscc","Gateways tx validated\n");
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << "Gateways tx validated" << std::endl);
|
||||
else fprintf(stderr,"Gateways tx invalid\n");
|
||||
return(retval);
|
||||
// }
|
||||
@@ -892,8 +898,12 @@ int64_t AddGatewaysInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CP
|
||||
{
|
||||
GetTokensCCaddress(cp,coinaddr,pk);
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
threshold = total/(maxinputs+1);
|
||||
LogPrint("gatewayscc-1","check %s for gateway inputs\n",coinaddr);
|
||||
if ( maxinputs > CC_MAXVINS )
|
||||
maxinputs = CC_MAXVINS;
|
||||
if ( maxinputs > 0 )
|
||||
threshold = total/maxinputs;
|
||||
else threshold = total;
|
||||
LOGSTREAM("gatewayscc",CCLOG_DEBUG1, stream << "check " << coinaddr << " for gateway inputs" << std::endl);
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||
{
|
||||
txid = it->first.txhash;
|
||||
@@ -928,9 +938,9 @@ int64_t AddGatewaysInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CP
|
||||
}
|
||||
return(totalinputs);
|
||||
}
|
||||
else LogPrint("gatewayscc","invalid GatewaysBind\n");
|
||||
else LOGSTREAM("gatewayscc",CCLOG_INFO, stream << "invalid GatewaysBind" << std::endl);
|
||||
}
|
||||
else LogPrint("gatewayscc","can't find GatewaysBind txid\n");
|
||||
else LOGSTREAM("gatewayscc",CCLOG_INFO, stream << "can't find GatewaysBind txid" << std::endl);
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -956,18 +966,18 @@ std::string GatewaysBind(uint64_t txfee,std::string coin,uint256 tokenid,int64_t
|
||||
prefix2 = p2;
|
||||
wiftype = p3;
|
||||
taddr = p4;
|
||||
LogPrint("gatewayscc-1","set prefix %d, prefix2 %d, wiftype %d for %s\n",prefix,prefix2,wiftype,coin.c_str());
|
||||
LOGSTREAM("gatewayscc",CCLOG_DEBUG1, stream << "set prefix " << prefix << ", prefix2 " << prefix2 << ", wiftype " << wiftype << ", taddr " << taddr << " for " << coin << std::endl);
|
||||
}
|
||||
if ( N == 0 || N > 15 || M > N )
|
||||
{
|
||||
CCerror = strprintf("illegal M.%d or N.%d",M,N);
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if ( pubkeys.size() != N )
|
||||
{
|
||||
CCerror = strprintf("M.%d N.%d but pubkeys[%d]",M,N,(int32_t)pubkeys.size());
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
for (i=0; i<N; i++)
|
||||
@@ -976,7 +986,7 @@ std::string GatewaysBind(uint64_t txfee,std::string coin,uint256 tokenid,int64_t
|
||||
if ( CCaddress_balance(coinaddr) == 0 )
|
||||
{
|
||||
CCerror = strprintf("M.%d N.%d but pubkeys[%d] has no balance",M,N,i);
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
}
|
||||
@@ -988,43 +998,43 @@ std::string GatewaysBind(uint64_t txfee,std::string coin,uint256 tokenid,int64_t
|
||||
if ( _GetCCaddress(destaddr,EVAL_GATEWAYS,gatewayspk) == 0 )
|
||||
{
|
||||
CCerror = strprintf("Gateway bind.%s (%s) cant create globaladdr",coin.c_str(),uint256_str(str,tokenid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if ( (fullsupply=CCfullsupply(tokenid)) != totalsupply )
|
||||
{
|
||||
CCerror = strprintf("Gateway bind.%s (%s) globaladdr.%s totalsupply %.8f != fullsupply %.8f",coin.c_str(),uint256_str(str,tokenid),cp->unspendableCCaddr,(double)totalsupply/COIN,(double)fullsupply/COIN);
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if ( CCtoken_balance(myTokenCCaddr,tokenid) != totalsupply )
|
||||
{
|
||||
CCerror = strprintf("token balance on %s %.8f != %.8f",myTokenCCaddr,(double)CCtoken_balance(myTokenCCaddr,tokenid)/COIN,(double)totalsupply/COIN);
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if ( GetTransaction(oracletxid,oracletx,hashBlock,false) == 0 || (numvouts= oracletx.vout.size()) <= 0 )
|
||||
{
|
||||
CCerror = strprintf("cant find oracletxid %s",uint256_str(str,oracletxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if ( DecodeOraclesCreateOpRet(oracletx.vout[numvouts-1].scriptPubKey,name,description,format) != 'C' )
|
||||
{
|
||||
CCerror = strprintf("mismatched oracle name %s != %s",name.c_str(),coin.c_str());
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if ( (fstr=(char *)format.c_str()) == 0 || strncmp(fstr,"Ihh",3) != 0 )
|
||||
{
|
||||
CCerror = strprintf("illegal format (%s) != (%s)",fstr,(char *)"Ihh");
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if ( GatewaysBindExists(cp,gatewayspk,tokenid) != 0 )
|
||||
{
|
||||
CCerror = strprintf("Gateway bind.%s (%s) already exists",coin.c_str(),uint256_str(str,tokenid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if ( AddNormalinputs(mtx,mypk,2*txfee,3) > 0 )
|
||||
@@ -1037,7 +1047,7 @@ std::string GatewaysBind(uint64_t txfee,std::string coin,uint256 tokenid,int64_t
|
||||
}
|
||||
}
|
||||
CCerror = strprintf("cant find enough inputs");
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
|
||||
@@ -1052,30 +1062,31 @@ std::string GatewaysDeposit(uint64_t txfee,uint256 bindtxid,int32_t height,std::
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
LogPrint("gatewayscc-1","GatewaysDeposit ht.%d %s %.8f numpks.%d\n",height,refcoin.c_str(),(double)amount/COIN,(int32_t)pubkeys.size());
|
||||
LOGSTREAM("gatewayscc",CCLOG_DEBUG1, stream << "GatewaysDeposit ht." << height << " " << refcoin << " " << (double)amount/COIN << " numpks." << (int32_t)pubkeys.size() << std::endl);
|
||||
if ( GetTransaction(bindtxid,bindtx,hashBlock,false) == 0 || (numvouts= bindtx.vout.size()) <= 0 )
|
||||
{
|
||||
CCerror = strprintf("cant find bindtxid %s",uint256_str(str,bindtxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if ( DecodeGatewaysBindOpRet(depositaddr,bindtx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B' || refcoin != coin )
|
||||
{
|
||||
CCerror = strprintf("invalid coin - bindtxid %s coin.%s",uint256_str(str,bindtxid),coin.c_str());
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if (komodo_txnotarizedconfirmed(bindtxid)==false)
|
||||
{
|
||||
CCerror = strprintf("gatewaysbind tx not yet confirmed/notarized");
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
n = (int32_t)pubkeys.size();
|
||||
merkleroot = zeroid;
|
||||
for (i=m=0; i<n; i++)
|
||||
{
|
||||
LogPrint("gatewayscc","pubkeys[%d] %s\n",i,pubkey33_str(str,(uint8_t *)&pubkeys[i]));
|
||||
pubkey33_str(str,(uint8_t *)&pubkeys[i]);
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << "pubkeys[" << i << "] " << str << std::endl);
|
||||
if ( (mhash= GatewaysReverseScan(txid,height,oracletxid,OraclesBatontxid(oracletxid,pubkeys[i]))) != zeroid )
|
||||
{
|
||||
if ( merkleroot == zeroid )
|
||||
@@ -1086,23 +1097,23 @@ std::string GatewaysDeposit(uint64_t txfee,uint256 bindtxid,int32_t height,std::
|
||||
txids.push_back(txid);
|
||||
}
|
||||
}
|
||||
LogPrint("gatewayscc","cointxid.%s m.%d of n.%d\n",uint256_str(str,cointxid),m,n);
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << "cointxid." << cointxid.GetHex() << " m." << m << " of n." << n << std::endl);
|
||||
if ( merkleroot == zeroid || m < n/2 )
|
||||
{
|
||||
CCerror = strprintf("couldnt find merkleroot for ht.%d %s oracle.%s m.%d vs n.%d",height,coin.c_str(),uint256_str(str,oracletxid),m,n);
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if ( GatewaysCointxidExists(cp,cointxid) != 0 )
|
||||
{
|
||||
CCerror = strprintf("cointxid.%s already exists",uint256_str(str,cointxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if ( GatewaysVerify(depositaddr,oracletxid,claimvout,coin,cointxid,deposithex,proof,merkleroot,destpub,taddr,prefix,prefix2) != amount )
|
||||
{
|
||||
CCerror = strprintf("deposittxid didnt validate");
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if ( AddNormalinputs(mtx,mypk,3*txfee,4) > 0 )
|
||||
@@ -1112,7 +1123,7 @@ std::string GatewaysDeposit(uint64_t txfee,uint256 bindtxid,int32_t height,std::
|
||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeGatewaysDepositOpRet('D',bindtxid,coin,publishers,txids,height,cointxid,claimvout,deposithex,proof,destpub,amount)));
|
||||
}
|
||||
CCerror = strprintf("cant find enough inputs");
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
|
||||
@@ -1132,49 +1143,49 @@ std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,ui
|
||||
if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 )
|
||||
{
|
||||
CCerror = strprintf("cant find bindtxid %s",uint256_str(str,bindtxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if ( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,msigpubkeys,taddr,prefix,prefix2,wiftype) != 'B' || coin != refcoin )
|
||||
{
|
||||
CCerror = strprintf("invalid coin - bindtxid %s coin.%s",uint256_str(str,bindtxid),coin.c_str());
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if (komodo_txnotarizedconfirmed(bindtxid)==false)
|
||||
{
|
||||
CCerror = strprintf("gatewaysbind tx not yet confirmed/notarized");
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if ( GetTransaction(deposittxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 )
|
||||
{
|
||||
CCerror = strprintf("cant find deposittxid %s",uint256_str(str,bindtxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if (DecodeGatewaysDepositOpRet(tx.vout[numvouts-1].scriptPubKey,tmptxid,coin,publishers,txids,height,cointxid,claimvout,deposithex,proof,tmpdestpub,tmpamount) != 'D' || coin != refcoin)
|
||||
{
|
||||
CCerror = strprintf("invalid coin - deposittxid %s coin.%s",uint256_str(str,bindtxid),coin.c_str());
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if (komodo_txnotarizedconfirmed(deposittxid)==false)
|
||||
{
|
||||
CCerror = strprintf("gatewaysdeposit tx not yet confirmed/notarized");
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if (tmpdestpub!=destpub)
|
||||
{
|
||||
CCerror = strprintf("different destination pubkey from desdeposit tx");
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if ( (depositamount=GatewaysDepositval(tx,mypk)) != amount )
|
||||
{
|
||||
CCerror = strprintf("invalid Gateways deposittxid %s %.8f != %.8f",uint256_str(str,deposittxid),(double)depositamount/COIN,(double)amount/COIN);
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if ( AddNormalinputs(mtx,mypk,txfee,3) > 0 )
|
||||
@@ -1189,7 +1200,7 @@ std::string GatewaysClaim(uint64_t txfee,uint256 bindtxid,std::string refcoin,ui
|
||||
}
|
||||
}
|
||||
CCerror = strprintf("cant find enough inputs or mismatched total");
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
|
||||
@@ -1211,19 +1222,19 @@ std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin
|
||||
if( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 )
|
||||
{
|
||||
CCerror = strprintf("cant find bindtxid %s",uint256_str(str,bindtxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,msigpubkeys,taddr,prefix,prefix2,wiftype) != 'B' || coin != refcoin )
|
||||
{
|
||||
CCerror = strprintf("invalid bindtxid %s coin.%s",uint256_str(str,bindtxid),coin.c_str());
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if (komodo_txnotarizedconfirmed(bindtxid)==false)
|
||||
{
|
||||
CCerror = strprintf("gatewaysbind tx not yet confirmed/notarized");
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
_GetCCaddress(coinaddr,EVAL_GATEWAYS,gatewayspk);
|
||||
@@ -1241,7 +1252,7 @@ std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin
|
||||
&& refcoin==coin && tmptokenid==tokenid && tmpbindtxid==bindtxid)
|
||||
{
|
||||
CCerror = strprintf("unable to create withdraw, another withdraw pending");
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
|
||||
@@ -1250,7 +1261,7 @@ std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin
|
||||
&& refcoin==coin && tmptokenid==tokenid && tmpbindtxid==bindtxid)
|
||||
{
|
||||
CCerror = strprintf("unable to create withdraw, another withdraw pending");
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
}
|
||||
@@ -1268,12 +1279,12 @@ std::string GatewaysWithdraw(uint64_t txfee,uint256 bindtxid,std::string refcoin
|
||||
else
|
||||
{
|
||||
CCerror = strprintf("not enough balance of tokens for withdraw");
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
}
|
||||
CCerror = strprintf("cant find enough normal inputs");
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
|
||||
@@ -1294,7 +1305,7 @@ std::string GatewaysPartialSign(uint64_t txfee,uint256 lasttxid,std::string refc
|
||||
|| (funcid=DecodeGatewaysOpRet(tx.vout[numvouts-1].scriptPubKey))==0 || (funcid!='W' && funcid!='P'))
|
||||
{
|
||||
CCerror = strprintf("can't find last tx %s",uint256_str(str,lasttxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if (funcid=='W')
|
||||
@@ -1303,26 +1314,26 @@ std::string GatewaysPartialSign(uint64_t txfee,uint256 lasttxid,std::string refc
|
||||
if (DecodeGatewaysWithdrawOpRet(tx.vout[numvouts-1].scriptPubKey,tmptokenid,bindtxid,coin,withdrawpub,amount)!='W' || refcoin!=coin)
|
||||
{
|
||||
CCerror = strprintf("invalid withdraw tx %s",uint256_str(str,lasttxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
else if (komodo_txnotarizedconfirmed(withdrawtxid)==false)
|
||||
{
|
||||
CCerror = strprintf("gatewayswithdraw tx not yet confirmed/notarized");
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
else if (GetTransaction(bindtxid,tmptx,hashBlock,false)==0 || (numvouts=tmptx.vout.size())<=0)
|
||||
{
|
||||
CCerror = strprintf("can't find bind tx %s",uint256_str(str,bindtxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
else if (DecodeGatewaysBindOpRet(depositaddr,tmptx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B'
|
||||
|| refcoin!=coin || tokenid!=tmptokenid)
|
||||
{
|
||||
CCerror = strprintf("invalid bind tx %s",uint256_str(str,bindtxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
}
|
||||
@@ -1331,39 +1342,39 @@ std::string GatewaysPartialSign(uint64_t txfee,uint256 lasttxid,std::string refc
|
||||
if (DecodeGatewaysPartialOpRet(tx.vout[numvouts-1].scriptPubKey,withdrawtxid,coin,K,signerpk,tmphex)!='P' || refcoin!=coin)
|
||||
{
|
||||
CCerror = strprintf("cannot decode partialsign tx opret %s",uint256_str(str,lasttxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
else if (GetTransaction(withdrawtxid,tmptx,hashBlock,false)==0 || (numvouts= tmptx.vout.size())<=0)
|
||||
{
|
||||
CCerror = strprintf("can't find withdraw tx %s",uint256_str(str,withdrawtxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
else if (DecodeGatewaysWithdrawOpRet(tmptx.vout[numvouts-1].scriptPubKey,tmptokenid,bindtxid,coin,withdrawpub,amount)!='W'
|
||||
|| refcoin!=coin)
|
||||
{
|
||||
CCerror = strprintf("invalid withdraw tx %s",uint256_str(str,lasttxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
else if (komodo_txnotarizedconfirmed(withdrawtxid)==false)
|
||||
{
|
||||
CCerror = strprintf("gatewayswithdraw tx not yet confirmed/notarized");
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
else if (GetTransaction(bindtxid,tmptx,hashBlock,false)==0 || (numvouts=tmptx.vout.size())<=0)
|
||||
{
|
||||
CCerror = strprintf("can't find bind tx %s",uint256_str(str,bindtxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
else if (DecodeGatewaysBindOpRet(depositaddr,tmptx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B'
|
||||
|| refcoin!=coin || tokenid!=tmptokenid)
|
||||
{
|
||||
CCerror = strprintf("invalid bind tx %s",uint256_str(str,bindtxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
}
|
||||
@@ -1374,7 +1385,7 @@ std::string GatewaysPartialSign(uint64_t txfee,uint256 lasttxid,std::string refc
|
||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeGatewaysPartialOpRet('P',withdrawtxid,refcoin,K+1,mypk,hex)));
|
||||
}
|
||||
CCerror = strprintf("error adding funds for partialsign");
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
|
||||
@@ -1394,7 +1405,7 @@ std::string GatewaysCompleteSigning(uint64_t txfee,uint256 lasttxid,std::string
|
||||
|| (funcid=DecodeGatewaysOpRet(tx.vout[numvouts-1].scriptPubKey))==0 || (funcid!='W' && funcid!='P'))
|
||||
{
|
||||
CCerror = strprintf("invalid last txid %s",uint256_str(str,lasttxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if (funcid=='W')
|
||||
@@ -1403,26 +1414,26 @@ std::string GatewaysCompleteSigning(uint64_t txfee,uint256 lasttxid,std::string
|
||||
if (DecodeGatewaysWithdrawOpRet(tx.vout[numvouts-1].scriptPubKey,tmptokenid,bindtxid,coin,withdrawpub,amount)!='W' || refcoin!=coin)
|
||||
{
|
||||
CCerror = strprintf("cannot decode withdraw tx opret %s",uint256_str(str,lasttxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
else if (GetTransaction(bindtxid,tmptx,hashBlock,false)==0 || (numvouts=tmptx.vout.size())<=0)
|
||||
{
|
||||
CCerror = strprintf("can't find bind tx %s",uint256_str(str,bindtxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
else if (komodo_txnotarizedconfirmed(withdrawtxid)==false)
|
||||
{
|
||||
CCerror = strprintf("gatewayswithdraw tx not yet confirmed/notarized");
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
else if (DecodeGatewaysBindOpRet(depositaddr,tmptx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B'
|
||||
|| refcoin!=coin || tokenid!=tmptokenid)
|
||||
{
|
||||
CCerror = strprintf("invalid bind tx %s",uint256_str(str,bindtxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
}
|
||||
@@ -1431,38 +1442,38 @@ std::string GatewaysCompleteSigning(uint64_t txfee,uint256 lasttxid,std::string
|
||||
if (DecodeGatewaysPartialOpRet(tx.vout[numvouts-1].scriptPubKey,withdrawtxid,coin,K,signerpk,tmphex)!='P' || refcoin!=coin)
|
||||
{
|
||||
CCerror = strprintf("cannot decode partialsign tx opret %s",uint256_str(str,lasttxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
else if (GetTransaction(withdrawtxid,tmptx,hashBlock,false)==0 || (numvouts=tmptx.vout.size())==0)
|
||||
{
|
||||
CCerror = strprintf("invalid withdraw txid %s",uint256_str(str,withdrawtxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
else if (DecodeGatewaysWithdrawOpRet(tmptx.vout[numvouts-1].scriptPubKey,tmptokenid,bindtxid,coin,withdrawpub,amount)!='W' || refcoin!=coin)
|
||||
{
|
||||
CCerror = strprintf("cannot decode withdraw tx opret %s",uint256_str(str,withdrawtxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
else if (komodo_txnotarizedconfirmed(withdrawtxid)==false)
|
||||
{
|
||||
CCerror = strprintf("gatewayswithdraw tx not yet confirmed/notarized");
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
else if (GetTransaction(bindtxid,tmptx,hashBlock,false)==0 || (numvouts=tmptx.vout.size())<=0)
|
||||
{
|
||||
CCerror = strprintf("can't find bind tx %s",uint256_str(str,bindtxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
else if (DecodeGatewaysBindOpRet(depositaddr,tmptx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B'
|
||||
|| refcoin!=coin || tokenid!=tmptokenid)
|
||||
{
|
||||
CCerror = strprintf("invalid bind tx %s",uint256_str(str,bindtxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
}
|
||||
@@ -1473,7 +1484,7 @@ std::string GatewaysCompleteSigning(uint64_t txfee,uint256 lasttxid,std::string
|
||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeGatewaysCompleteSigningOpRet('S',withdrawtxid,refcoin,K+1,hex)));
|
||||
}
|
||||
CCerror = strprintf("error adding funds for completesigning");
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
|
||||
@@ -1491,44 +1502,44 @@ std::string GatewaysMarkDone(uint64_t txfee,uint256 completetxid,std::string ref
|
||||
if (GetTransaction(completetxid,tx,hashBlock,false)==0 || (numvouts= tx.vout.size())<=0)
|
||||
{
|
||||
CCerror = strprintf("invalid completesigning txid %s",uint256_str(str,completetxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
else if (DecodeGatewaysCompleteSigningOpRet(tx.vout[numvouts-1].scriptPubKey,withdrawtxid,coin,K,hex)!='S' || refcoin!=coin)
|
||||
{
|
||||
CCerror = strprintf("cannot decode completesigning tx opret %s",uint256_str(str,completetxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if (komodo_txnotarizedconfirmed(completetxid)==false)
|
||||
{
|
||||
CCerror = strprintf("gatewayscompletesigning tx not yet confirmed/notarized");
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
else if (GetTransaction(withdrawtxid,tx,hashBlock,false)==0 || (numvouts= tx.vout.size())==0)
|
||||
{
|
||||
CCerror = strprintf("invalid withdraw txid %s",uint256_str(str,withdrawtxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
else if (DecodeGatewaysWithdrawOpRet(tx.vout[numvouts-1].scriptPubKey,tmptokenid,bindtxid,coin,withdrawpub,amount)!='W' || refcoin!=coin)
|
||||
{
|
||||
CCerror = strprintf("cannot decode withdraw tx opret %s\n",uint256_str(str,withdrawtxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
else if (GetTransaction(bindtxid,tx,hashBlock,false)==0 || (numvouts=tx.vout.size())<=0)
|
||||
{
|
||||
CCerror = strprintf("can't find bind tx %s",uint256_str(str,bindtxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
else if (DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B'
|
||||
|| refcoin!=coin || tokenid!=tmptokenid)
|
||||
{
|
||||
CCerror = strprintf("invalid bind tx %s",uint256_str(str,bindtxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if (AddNormalinputs(mtx,mypk,txfee,3)!=0)
|
||||
@@ -1538,7 +1549,7 @@ std::string GatewaysMarkDone(uint64_t txfee,uint256 completetxid,std::string ref
|
||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,EncodeGatewaysMarkDoneOpRet('M',withdrawtxid,refcoin,completetxid)));
|
||||
}
|
||||
CCerror = strprintf("error adding funds for markdone");
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
|
||||
@@ -1558,13 +1569,13 @@ UniValue GatewaysPendingDeposits(uint256 bindtxid,std::string refcoin)
|
||||
if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 )
|
||||
{
|
||||
CCerror = strprintf("cant find bindtxid %s",uint256_str(str,bindtxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if ( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,pubkeys,taddr,prefix,prefix2,wiftype) != 'B' || refcoin != coin)
|
||||
{
|
||||
CCerror = strprintf("invalid bindtxid %s coin.%s",uint256_str(str,bindtxid),coin.c_str());
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
@@ -1613,13 +1624,13 @@ UniValue GatewaysPendingWithdraws(uint256 bindtxid,std::string refcoin)
|
||||
if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 )
|
||||
{
|
||||
CCerror = strprintf("cant find bindtxid %s",uint256_str(str,bindtxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if ( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,msigpubkeys,taddr,prefix,prefix2,wiftype) != 'B' || refcoin != coin )
|
||||
{
|
||||
CCerror = strprintf("invalid bindtxid %s coin.%s",uint256_str(str,bindtxid),coin.c_str());
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
n = msigpubkeys.size();
|
||||
@@ -1701,13 +1712,13 @@ UniValue GatewaysProcessedWithdraws(uint256 bindtxid,std::string refcoin)
|
||||
if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 )
|
||||
{
|
||||
CCerror = strprintf("cant find bindtxid %s",uint256_str(str,bindtxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if ( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,msigpubkeys,taddr,prefix,prefix2,wiftype) != 'B' || refcoin != coin)
|
||||
{
|
||||
CCerror = strprintf("invalid bindtxid %s coin.%s",uint256_str(str,bindtxid),coin.c_str());
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
n = msigpubkeys.size();
|
||||
@@ -1779,13 +1790,13 @@ UniValue GatewaysExternalAddress(uint256 bindtxid,CPubKey pubkey)
|
||||
if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 )
|
||||
{
|
||||
CCerror = strprintf("cant find bindtxid %s",uint256_str(str,bindtxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if ( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,msigpubkeys,taddr,prefix,prefix2,wiftype) != 'B')
|
||||
{
|
||||
CCerror = strprintf("invalid bindtxid %s coin.%s",uint256_str(str,bindtxid),coin.c_str());
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
GetCustomscriptaddress(addr,CScript() << ParseHex(HexStr(pubkey)) << OP_CHECKSIG,taddr,prefix,prefix2);
|
||||
@@ -1803,19 +1814,19 @@ UniValue GatewaysDumpPrivKey(uint256 bindtxid,CKey key)
|
||||
if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 )
|
||||
{
|
||||
CCerror = strprintf("cant find bindtxid %s",uint256_str(str,bindtxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if ( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,msigpubkeys,taddr,prefix,prefix2,wiftype) != 'B')
|
||||
{
|
||||
CCerror = strprintf("invalid bindtxid %s coin.%s",uint256_str(str,bindtxid),coin.c_str());
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
|
||||
priv=EncodeCustomSecret(key,wiftype);
|
||||
result.push_back(Pair("result","success"));
|
||||
result.push_back(Pair("address",priv.c_str()));
|
||||
result.push_back(Pair("privkey",priv.c_str()));
|
||||
return(result);
|
||||
}
|
||||
|
||||
@@ -1832,13 +1843,13 @@ UniValue GatewaysInfo(uint256 bindtxid)
|
||||
if ( GetTransaction(bindtxid,tx,hashBlock,false) == 0 || (numvouts= tx.vout.size()) <= 0 )
|
||||
{
|
||||
CCerror = strprintf("cant find bindtxid %s",uint256_str(str,bindtxid));
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if ( DecodeGatewaysBindOpRet(depositaddr,tx.vout[numvouts-1].scriptPubKey,tokenid,coin,totalsupply,oracletxid,M,N,msigpubkeys,taddr,prefix,prefix2,wiftype) != 'B')
|
||||
{
|
||||
CCerror = strprintf("invalid bindtxid %s coin.%s",uint256_str(str,bindtxid),coin.c_str());
|
||||
LogPrint("gatewayscc","%s\n", CCerror.c_str() );
|
||||
LOGSTREAM("gatewayscc",CCLOG_INFO, stream << CCerror << std::endl);
|
||||
return("");
|
||||
}
|
||||
if ( GetTransaction(bindtxid,tx,hashBlock,false) != 0 )
|
||||
|
||||
@@ -255,25 +255,25 @@ template <class Helper> int64_t IsHeirFundingVout(struct CCcontract_info* cp, co
|
||||
}
|
||||
|
||||
// makes coin initial tx opret
|
||||
CScript EncodeHeirCreateOpRet(uint8_t funcid, CPubKey ownerPubkey, CPubKey heirPubkey, int64_t inactivityTimeSec, std::string heirName, std::string memo)
|
||||
vscript_t EncodeHeirCreateOpRet(uint8_t funcid, CPubKey ownerPubkey, CPubKey heirPubkey, int64_t inactivityTimeSec, std::string heirName, std::string memo)
|
||||
{
|
||||
uint8_t evalcode = EVAL_HEIR;
|
||||
|
||||
return CScript() << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << ownerPubkey << heirPubkey << inactivityTimeSec << heirName << memo);
|
||||
return /*CScript() << OP_RETURN <<*/ E_MARSHAL(ss << evalcode << funcid << ownerPubkey << heirPubkey << inactivityTimeSec << heirName << memo);
|
||||
}
|
||||
|
||||
// makes coin additional tx opret
|
||||
CScript EncodeHeirOpRet(uint8_t funcid, uint256 fundingtxid, uint8_t hasHeirSpendingBegun)
|
||||
vscript_t EncodeHeirOpRet(uint8_t funcid, uint256 fundingtxid, uint8_t hasHeirSpendingBegun)
|
||||
{
|
||||
uint8_t evalcode = EVAL_HEIR;
|
||||
|
||||
fundingtxid = revuint256(fundingtxid);
|
||||
return CScript() << OP_RETURN << E_MARSHAL(ss << evalcode << funcid << fundingtxid << hasHeirSpendingBegun);
|
||||
return /*CScript() << OP_RETURN <<*/ E_MARSHAL(ss << evalcode << funcid << fundingtxid << hasHeirSpendingBegun);
|
||||
}
|
||||
|
||||
|
||||
// decode opret vout for Heir contract
|
||||
uint8_t _DecodeHeirOpRet(std::vector<uint8_t> vopret, CPubKey& ownerPubkey, CPubKey& heirPubkey, int64_t& inactivityTime, std::string& heirName, std::string& memo, uint256& fundingTxidInOpret, uint8_t &hasHeirSpendingBegun, bool noLogging)
|
||||
uint8_t _DecodeHeirOpRet(vscript_t vopret, CPubKey& ownerPubkey, CPubKey& heirPubkey, int64_t& inactivityTime, std::string& heirName, std::string& memo, uint256& fundingTxidInOpret, uint8_t &hasHeirSpendingBegun, bool noLogging)
|
||||
{
|
||||
uint8_t evalCodeInOpret = 0;
|
||||
uint8_t heirFuncId = 0;
|
||||
@@ -287,13 +287,13 @@ uint8_t _DecodeHeirOpRet(std::vector<uint8_t> vopret, CPubKey& ownerPubkey, CPub
|
||||
uint8_t heirFuncId = 0;
|
||||
hasHeirSpendingBegun = 0;
|
||||
|
||||
bool result = E_UNMARSHAL(vopret, { ss >> evalCodeInOpret; ss >> heirFuncId; \
|
||||
if (heirFuncId == 'F') { \
|
||||
ss >> ownerPubkey; ss >> heirPubkey; ss >> inactivityTime; ss >> heirName; ss >> memo; \
|
||||
} \
|
||||
else { \
|
||||
ss >> fundingTxidInOpret >> hasHeirSpendingBegun; \
|
||||
} \
|
||||
bool result = E_UNMARSHAL(vopret, { ss >> evalCodeInOpret; ss >> heirFuncId;
|
||||
if (heirFuncId == 'F') {
|
||||
ss >> ownerPubkey; ss >> heirPubkey; ss >> inactivityTime; ss >> heirName; ss >> memo;
|
||||
}
|
||||
else {
|
||||
ss >> fundingTxidInOpret >> hasHeirSpendingBegun;
|
||||
}
|
||||
});
|
||||
|
||||
if (!result) {
|
||||
@@ -327,9 +327,11 @@ uint8_t _DecodeHeirEitherOpRet(CScript scriptPubKey, uint256 &tokenid, CPubKey&
|
||||
{
|
||||
uint8_t evalCodeTokens = 0;
|
||||
std::vector<CPubKey> voutPubkeysDummy;
|
||||
std::vector<uint8_t> vopretExtra /*, vopretStripped*/;
|
||||
std::vector<std::pair<uint8_t, vscript_t>> oprets;
|
||||
vscript_t vopretExtra /*, vopretStripped*/;
|
||||
|
||||
if (DecodeTokenOpRet(scriptPubKey, evalCodeTokens, tokenid, voutPubkeysDummy, vopretExtra) != 0) {
|
||||
|
||||
if (DecodeTokenOpRet(scriptPubKey, evalCodeTokens, tokenid, voutPubkeysDummy, oprets) != 0 && GetOpretBlob(oprets, OPRETID_HEIRDATA, vopretExtra)) {
|
||||
/* if (vopretExtra.size() > 1) {
|
||||
// restore the second opret:
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
#define IS_CHARINSTR(c, str) (std::string(str).find((char)(c)) != std::string::npos)
|
||||
|
||||
// makes coin initial tx opret
|
||||
CScript EncodeHeirCreateOpRet(uint8_t funcid, CPubKey ownerPubkey, CPubKey heirPubkey, int64_t inactivityTimeSec, std::string heirName, std::string memo);
|
||||
CScript EncodeHeirOpRet(uint8_t funcid, uint256 fundingtxid, uint8_t isHeirSpendingBegan);
|
||||
vscript_t EncodeHeirCreateOpRet(uint8_t funcid, CPubKey ownerPubkey, CPubKey heirPubkey, int64_t inactivityTimeSec, std::string heirName, std::string memo);
|
||||
vscript_t EncodeHeirOpRet(uint8_t funcid, uint256 fundingtxid, uint8_t isHeirSpendingBegan);
|
||||
|
||||
uint256 FindLatestFundingTx(uint256 fundingtxid, uint256 &tokenid, CScript& opRetScript, uint8_t &isHeirSpendingBegan);
|
||||
//uint8_t DecodeHeirOpRet(CScript scriptPubKey, uint256& fundingtxid, uint8_t &isHeirSpendingBegan, bool noLogging = false);
|
||||
@@ -29,13 +29,13 @@ public:
|
||||
}
|
||||
|
||||
static CScript makeCreateOpRet(uint256 dummyid, std::vector<CPubKey> dummyPubkeys, CPubKey ownerPubkey, CPubKey heirPubkey, int64_t inactivityTimeSec, std::string heirName, std::string memo) {
|
||||
return EncodeHeirCreateOpRet((uint8_t)'F', ownerPubkey, heirPubkey, inactivityTimeSec, heirName, memo);
|
||||
return CScript() << OP_RETURN << EncodeHeirCreateOpRet((uint8_t)'F', ownerPubkey, heirPubkey, inactivityTimeSec, heirName, memo);
|
||||
}
|
||||
static CScript makeAddOpRet(uint256 dummyid, std::vector<CPubKey> dummyPubkeys, uint256 fundingtxid, uint8_t isHeirSpendingBegan) {
|
||||
return EncodeHeirOpRet((uint8_t)'A', fundingtxid, isHeirSpendingBegan);
|
||||
return CScript() << OP_RETURN << EncodeHeirOpRet((uint8_t)'A', fundingtxid, isHeirSpendingBegan);
|
||||
}
|
||||
static CScript makeClaimOpRet(uint256 dummyid, std::vector<CPubKey> dummyPubkeys, uint256 fundingtxid, uint8_t isHeirSpendingBegan) {
|
||||
return EncodeHeirOpRet((uint8_t)'C', fundingtxid, isHeirSpendingBegan);
|
||||
return CScript() << OP_RETURN << EncodeHeirOpRet((uint8_t)'C', fundingtxid, isHeirSpendingBegan);
|
||||
}
|
||||
static CTxOut make1of2Vout(int64_t amount, CPubKey ownerPubkey, CPubKey heirPubkey) {
|
||||
return MakeCC1of2vout(EVAL_HEIR, amount, ownerPubkey, heirPubkey);
|
||||
@@ -71,15 +71,15 @@ public:
|
||||
|
||||
static CScript makeCreateOpRet(uint256 tokenid, std::vector<CPubKey> voutTokenPubkeys, CPubKey ownerPubkey, CPubKey heirPubkey, int64_t inactivityTimeSec, std::string heirName, std::string memo) {
|
||||
return EncodeTokenOpRet(tokenid, voutTokenPubkeys,
|
||||
EncodeHeirCreateOpRet((uint8_t)'F', ownerPubkey, heirPubkey, inactivityTimeSec, heirName, memo));
|
||||
std::make_pair(OPRETID_HEIRDATA, EncodeHeirCreateOpRet((uint8_t)'F', ownerPubkey, heirPubkey, inactivityTimeSec, heirName, memo)));
|
||||
}
|
||||
static CScript makeAddOpRet(uint256 tokenid, std::vector<CPubKey> voutTokenPubkeys, uint256 fundingtxid, uint8_t isHeirSpendingBegan) {
|
||||
return EncodeTokenOpRet(tokenid, voutTokenPubkeys,
|
||||
EncodeHeirOpRet((uint8_t)'A', fundingtxid, isHeirSpendingBegan));
|
||||
std::make_pair(OPRETID_HEIRDATA, EncodeHeirOpRet((uint8_t)'A', fundingtxid, isHeirSpendingBegan)));
|
||||
}
|
||||
static CScript makeClaimOpRet(uint256 tokenid, std::vector<CPubKey> voutTokenPubkeys, uint256 fundingtxid, uint8_t isHeirSpendingBegan) {
|
||||
return EncodeTokenOpRet(tokenid, voutTokenPubkeys,
|
||||
EncodeHeirOpRet((uint8_t)'C', fundingtxid, isHeirSpendingBegan));
|
||||
std::make_pair(OPRETID_HEIRDATA, EncodeHeirOpRet((uint8_t)'C', fundingtxid, isHeirSpendingBegan)));
|
||||
}
|
||||
|
||||
static CTxOut make1of2Vout(int64_t amount, CPubKey ownerPubkey, CPubKey heirPubkey) {
|
||||
|
||||
@@ -478,5 +478,3 @@ bool Eval::ImportCoin(const std::vector<uint8_t> params,const CTransaction &impo
|
||||
}
|
||||
return Valid();
|
||||
}
|
||||
|
||||
|
||||
|
||||
7
src/cc/makecustom
Executable file
7
src/cc/makecustom
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
gcc -O3 -DBUILD_CUSTOMCC -std=c++11 -I../secp256k1/include -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -fPIC -shared -c -o customcc.so cclib.cpp
|
||||
cp customcc.so ../libcc.so
|
||||
cd ..
|
||||
make
|
||||
cd cc
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
#!/bin/sh
|
||||
cd rogue;
|
||||
make clean;
|
||||
|
||||
if [ "$HOST" = "x86_64-w64-mingw32" ]; then
|
||||
echo building rogue.exe...
|
||||
./configure --host=x86_64-w64-mingw32
|
||||
mkdir ncurses && cd ncurses
|
||||
echo $PWD
|
||||
wget https://invisible-island.net/datafiles/release/mingw32.zip
|
||||
unzip mingw32.zip && rm mingw32.zip
|
||||
wget https://github.com/KomodoPlatform/rogue/releases/download/0.3.3b-01/x86_64-w64-mingw32.tar.gz
|
||||
tar xvfz x86_64-w64-mingw32.tar.gz && rm x86_64-w64-mingw32.tar.gz
|
||||
echo lib archive cleaned
|
||||
cd ..
|
||||
echo $PWD
|
||||
if make -f Makefile_win "$@"; then
|
||||
echo rogue.exe build SUCCESSFUL
|
||||
|
||||
2
src/cc/maketetris
Executable file
2
src/cc/maketetris
Executable file
@@ -0,0 +1,2 @@
|
||||
gcc -O3 -std=c++11 -I../secp256k1/include -I../univalue/include -I../cryptoconditions/include -I../cryptoconditions/src -I../cryptoconditions/src/asn -I.. -I. -DSTANDALONE tetris.cpp -lncurses -o tetris
|
||||
|
||||
@@ -167,7 +167,7 @@ int32_t MarmaraGetbatontxid(std::vector<uint256> &creditloop,uint256 &batontxid,
|
||||
creditloop.push_back(txid);
|
||||
//fprintf(stderr,"%d: %s\n",n,txid.GetHex().c_str());
|
||||
n++;
|
||||
if ( (value= CCgettxout(spenttxid,vout,1)) == 10000 )
|
||||
if ( (value= CCgettxout(spenttxid,vout,1,1)) == 10000 )
|
||||
{
|
||||
batontxid = spenttxid;
|
||||
//fprintf(stderr,"got baton %s %.8f\n",batontxid.GetHex().c_str(),(double)value/COIN);
|
||||
@@ -388,7 +388,11 @@ int64_t AddMarmarainputs(CMutableTransaction &mtx,std::vector<CPubKey> &pubkeys,
|
||||
uint64_t threshold,nValue,totalinputs = 0; uint256 txid,hashBlock; CTransaction tx; int32_t numvouts,ht,unlockht,vout,i,n = 0; uint8_t funcid; CPubKey pk; std::vector<int64_t> vals;
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
threshold = total/(maxinputs+1);
|
||||
if ( maxinputs > CC_MAXVINS )
|
||||
maxinputs = CC_MAXVINS;
|
||||
if ( maxinputs > 0 )
|
||||
threshold = total/maxinputs;
|
||||
else threshold = total;
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||
{
|
||||
txid = it->first.txhash;
|
||||
|
||||
@@ -15,203 +15,675 @@
|
||||
|
||||
#include "CCPayments.h"
|
||||
|
||||
/*
|
||||
Payments CC is a catchall CC, supported invoices, zpayments, automated funds allocation, including token based revshare
|
||||
/*
|
||||
0) txidopret <- allocation, scriptPubKey, opret
|
||||
1) create <- locked_blocks, minrelease, list of txidopret
|
||||
|
||||
2) fund createtxid amount opretflag to global CC address with opret or txidaddr without
|
||||
|
||||
3) release amount -> vout[i] will be scriptPubKeys[i] and (amount * allocations[i]) / sumallocations[] (only using vins that have been locked for locked_blocks+).
|
||||
|
||||
4) info txid -> display parameters, funds
|
||||
5) list -> all txids
|
||||
|
||||
First step is to create txids with the info needed in their opreturns. this info is the weight, scriptPubKey and opret if needed. To do that txidopret is used:
|
||||
|
||||
./c is a script that invokes komodo-cli with the correct -ac_name
|
||||
|
||||
./c paymentstxidopret \"[9,%222102d6f13a8f745921cdb811e32237bb98950af1a5952be7b3d429abd9152f8e388dac%22]\" -> rawhex with txid 95d9fc8d8a3ef63693c7427e59ff5e177ef63b7345d5f6d6497ac262699a8def
|
||||
|
||||
./c paymentstxidopret \"[1,%2221039433dc3749aece1bd568f374a45da3b0bc6856990d7da3cd175399577940a775ac%22]\" -> rawhex txid 00469695a08b975ceaf7258896abbf1455eb0f383e8a98fc650deace4cbf02a1
|
||||
|
||||
now we have 2 txid with the required info in the opreturn. one of them has a 9 and the other a 1 for a 90%/10% split.
|
||||
|
||||
./c paymentscreate \"[0,0,%2295d9fc8d8a3ef63693c7427e59ff5e177ef63b7345d5f6d6497ac262699a8def%22,%2200469695a08b975ceaf7258896abbf1455eb0f383e8a98fc650deace4cbf02a1%22]\" -> created txid 318d827cc6d8f25f40517e7fb0982e3f707b4aa749d322483fc336686a87b28a that will be the createtxid that the other rpc calls will use.
|
||||
|
||||
lets see if this appears in the list
|
||||
|
||||
./c paymentslist ->
|
||||
{
|
||||
"result": "success",
|
||||
"createtxids": [
|
||||
"318d827cc6d8f25f40517e7fb0982e3f707b4aa749d322483fc336686a87b28a"
|
||||
]
|
||||
}
|
||||
|
||||
It appeared! now lets get more info on it:
|
||||
./c paymentsinfo \"[%22318d827cc6d8f25f40517e7fb0982e3f707b4aa749d322483fc336686a87b28a%22]\"
|
||||
{
|
||||
"lockedblocks": 0,
|
||||
"totalallocations": 10,
|
||||
"minrelease": 0,
|
||||
"RWRM36sC8jSctyFZtsu7CyDcHYPdZX7nPZ": 0.00000000,
|
||||
"REpyKi7avsVduqZ3eimncK4uKqSArLTGGK": 0.00000000,
|
||||
"totalfunds": 0.00000000,
|
||||
"result": "success"
|
||||
}
|
||||
|
||||
There are 2 possible places the funds for this createtxid can be, the first is the special address that is derived from combining the globalCC address with the txidaddr. txidaddr is a non-spendable markeraddress created by converting the txid into a 33 byte pubkey by prefixing 0x02 to the txid. It is a 1of2 address, so it doesnt matter that nobody knows the privkey for this txidaddr. the second address is the global CC address and only utxo to that address with an opreturn containing the createtxid are funds valid for this payments CC createtxid
|
||||
|
||||
next let us add some funds to it. the funds can be to either of the two addresses, controlled by useopret (defaults to 0)
|
||||
|
||||
./c paymentsfund \"[%22318d827cc6d8f25f40517e7fb0982e3f707b4aa749d322483fc336686a87b28a%22,1,0]\" -> txid 28f69b925bb7a21d2a3ba2327e85eb2031b014e976e43f5c2c6fb8a76767b221, which indeed sent funds to RWRM36sC8jSctyFZtsu7CyDcHYPdZX7nPZ without an opreturn and it appears on the payments info.
|
||||
|
||||
./c paymentsfund \"[%22318d827cc6d8f25f40517e7fb0982e3f707b4aa749d322483fc336686a87b28a%22,1,1]\" -> txid cc93330b5c951b724b246b3b138d00519c33f2a600a7c938bc9e51aff6e20e32, which indeed sent funds to REpyKi7avsVduqZ3eimncK4uKqSArLTGGK with an opreturn and it appears on the payments info.
|
||||
|
||||
|
||||
./c paymentsrelease \"[%22318d827cc6d8f25f40517e7fb0982e3f707b4aa749d322483fc336686a87b28a%22,1.5]\" -> a8d5dbbb8ee94c05e75c4f3c5221091f59dcb86e0e9c4e1e3d2cf69e6fce6b81
|
||||
|
||||
it used both fund utxos
|
||||
|
||||
*/
|
||||
|
||||
// start of consensus code
|
||||
|
||||
int64_t IsPaymentsvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v)
|
||||
CScript EncodePaymentsTxidOpRet(int32_t allocation,std::vector<uint8_t> scriptPubKey,std::vector<uint8_t> destopret)
|
||||
{
|
||||
CScript opret; uint8_t evalcode = EVAL_PAYMENTS;
|
||||
opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'T' << allocation << scriptPubKey << destopret);
|
||||
return(opret);
|
||||
}
|
||||
|
||||
uint8_t DecodePaymentsTxidOpRet(CScript scriptPubKey,int32_t &allocation,std::vector<uint8_t> &destscriptPubKey,std::vector<uint8_t> &destopret)
|
||||
{
|
||||
std::vector<uint8_t> vopret; uint8_t *script,e,f;
|
||||
GetOpReturnData(scriptPubKey, vopret);
|
||||
script = (uint8_t *)vopret.data();
|
||||
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> allocation; ss >> destscriptPubKey; ss >> destopret) != 0 )
|
||||
{
|
||||
if ( e == EVAL_PAYMENTS && f == 'T' )
|
||||
return(f);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
CScript EncodePaymentsFundOpRet(uint256 checktxid)
|
||||
{
|
||||
CScript opret; uint8_t evalcode = EVAL_PAYMENTS;
|
||||
opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'F' << checktxid);
|
||||
return(opret);
|
||||
}
|
||||
|
||||
uint8_t DecodePaymentsFundOpRet(CScript scriptPubKey,uint256 &checktxid)
|
||||
{
|
||||
std::vector<uint8_t> vopret; uint8_t *script,e,f;
|
||||
GetOpReturnData(scriptPubKey, vopret);
|
||||
script = (uint8_t *)vopret.data();
|
||||
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> checktxid) != 0 )
|
||||
{
|
||||
if ( e == EVAL_PAYMENTS && f == 'F' )
|
||||
return(f);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
CScript EncodePaymentsOpRet(int32_t lockedblocks,int32_t minrelease,int32_t totalallocations,std::vector<uint256> txidoprets)
|
||||
{
|
||||
CScript opret; uint8_t evalcode = EVAL_PAYMENTS;
|
||||
opret << OP_RETURN << E_MARSHAL(ss << evalcode << 'C' << lockedblocks << minrelease << totalallocations << txidoprets);
|
||||
return(opret);
|
||||
}
|
||||
|
||||
uint8_t DecodePaymentsOpRet(CScript scriptPubKey,int32_t &lockedblocks,int32_t &minrelease,int32_t &totalallocations,std::vector<uint256> &txidoprets)
|
||||
{
|
||||
std::vector<uint8_t> vopret; uint8_t *script,e,f;
|
||||
GetOpReturnData(scriptPubKey, vopret);
|
||||
script = (uint8_t *)vopret.data();
|
||||
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> lockedblocks; ss >> minrelease; ss >> totalallocations; ss >> txidoprets) != 0 )
|
||||
{
|
||||
if ( e == EVAL_PAYMENTS && f == 'C' )
|
||||
return(f);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
int64_t IsPaymentsvout(struct CCcontract_info *cp,const CTransaction& tx,int32_t v,char *cmpaddr)
|
||||
{
|
||||
char destaddr[64];
|
||||
if ( tx.vout[v].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
||||
{
|
||||
if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && strcmp(destaddr,cp->unspendableCCaddr) == 0 )
|
||||
if ( Getscriptaddress(destaddr,tx.vout[v].scriptPubKey) > 0 && (cmpaddr[0] == 0 || strcmp(destaddr,cmpaddr) == 0) )
|
||||
return(tx.vout[v].nValue);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
bool PaymentsExactAmounts(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx,int32_t minage,uint64_t txfee)
|
||||
{
|
||||
static uint256 zerohash;
|
||||
CTransaction vinTx; uint256 hashBlock,activehash; int32_t i,numvins,numvouts; int64_t inputs=0,outputs=0,assetoshis;
|
||||
numvins = tx.vin.size();
|
||||
numvouts = tx.vout.size();
|
||||
for (i=0; i<numvins; i++)
|
||||
{
|
||||
//fprintf(stderr,"vini.%d\n",i);
|
||||
if ( (*cp->ismyvin)(tx.vin[i].scriptSig) != 0 )
|
||||
{
|
||||
//fprintf(stderr,"vini.%d check mempool\n",i);
|
||||
if ( eval->GetTxUnconfirmed(tx.vin[i].prevout.hash,vinTx,hashBlock) == 0 )
|
||||
return eval->Invalid("cant find vinTx");
|
||||
else
|
||||
{
|
||||
//fprintf(stderr,"vini.%d check hash and vout\n",i);
|
||||
if ( hashBlock == zerohash )
|
||||
return eval->Invalid("cant Payments from mempool");
|
||||
if ( (assetoshis= IsPaymentsvout(cp,vinTx,tx.vin[i].prevout.n)) != 0 )
|
||||
inputs += assetoshis;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i=0; i<numvouts; i++)
|
||||
{
|
||||
//fprintf(stderr,"i.%d of numvouts.%d\n",i,numvouts);
|
||||
if ( (assetoshis= IsPaymentsvout(cp,tx,i)) != 0 )
|
||||
outputs += assetoshis;
|
||||
}
|
||||
if ( inputs != outputs+txfee )
|
||||
{
|
||||
fprintf(stderr,"inputs %llu vs outputs %llu\n",(long long)inputs,(long long)outputs);
|
||||
return eval->Invalid("mismatched inputs != outputs + txfee");
|
||||
}
|
||||
else return(true);
|
||||
}
|
||||
|
||||
bool PaymentsValidate(struct CCcontract_info *cp,Eval* eval,const CTransaction &tx, uint32_t nIn)
|
||||
{
|
||||
int32_t numvins,numvouts,preventCCvins,preventCCvouts,i,numblocks; bool retval; uint256 txid; uint8_t hash[32]; char str[65],destaddr[64];
|
||||
return eval->Invalid("no validation yet");
|
||||
std::vector<std::pair<CAddressIndexKey, CAmount> > txids;
|
||||
numvins = tx.vin.size();
|
||||
numvouts = tx.vout.size();
|
||||
preventCCvins = preventCCvouts = -1;
|
||||
if ( numvouts < 1 )
|
||||
return eval->Invalid("no vouts");
|
||||
else
|
||||
{
|
||||
for (i=0; i<numvins; i++)
|
||||
{
|
||||
if ( IsCCInput(tx.vin[0].scriptSig) == 0 )
|
||||
{
|
||||
return eval->Invalid("illegal normal vini");
|
||||
}
|
||||
}
|
||||
//fprintf(stderr,"check amounts\n");
|
||||
if ( PaymentsExactAmounts(cp,eval,tx,1,10000) == false )
|
||||
{
|
||||
fprintf(stderr,"Paymentsget invalid amount\n");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
txid = tx.GetHash();
|
||||
memcpy(hash,&txid,sizeof(hash));
|
||||
retval = PreventCC(eval,tx,preventCCvins,numvins,preventCCvouts,numvouts);
|
||||
if ( retval != 0 )
|
||||
fprintf(stderr,"Paymentsget validated\n");
|
||||
else fprintf(stderr,"Paymentsget invalid\n");
|
||||
return(retval);
|
||||
}
|
||||
}
|
||||
// one of two addresses
|
||||
// change must go to 1of2 txidaddr
|
||||
// only 'F' or 1of2 txidaddr can be spent
|
||||
// all vouts must match exactly
|
||||
return(true);
|
||||
}
|
||||
// end of consensus code
|
||||
|
||||
// helper functions for rpc calls in rpcwallet.cpp
|
||||
|
||||
int64_t AddPaymentsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk,int64_t total,int32_t maxinputs)
|
||||
int64_t AddPaymentsInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey txidpk,int64_t total,int32_t maxinputs,uint256 createtxid,int32_t latestheight)
|
||||
{
|
||||
// add threshold check
|
||||
char coinaddr[64]; int64_t nValue,price,totalinputs = 0; uint256 txid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx; int32_t vout,n = 0;
|
||||
char coinaddr[64]; CPubKey Paymentspk; int64_t nValue,threshold,price,totalinputs = 0; uint256 txid,checktxid,hashBlock; std::vector<uint8_t> origpubkey; CTransaction vintx,tx; int32_t iter,vout,ht,n = 0;
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
GetCCaddress(cp,coinaddr,pk);
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||
if ( maxinputs > CC_MAXVINS )
|
||||
maxinputs = CC_MAXVINS;
|
||||
if ( maxinputs > 0 )
|
||||
threshold = total/maxinputs;
|
||||
else threshold = total;
|
||||
Paymentspk = GetUnspendable(cp,0);
|
||||
for (iter=0; iter<2; iter++)
|
||||
{
|
||||
txid = it->first.txhash;
|
||||
vout = (int32_t)it->first.index;
|
||||
// no need to prevent dup
|
||||
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
|
||||
if ( iter == 0 )
|
||||
GetCCaddress(cp,coinaddr,Paymentspk);
|
||||
else GetCCaddress1of2(cp,coinaddr,Paymentspk,txidpk);
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||
{
|
||||
if ( (nValue= IsPaymentsvout(cp,vintx,vout)) > 1000000 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
|
||||
txid = it->first.txhash;
|
||||
vout = (int32_t)it->first.index;
|
||||
//fprintf(stderr,"iter.%d %s/v%d %s\n",iter,txid.GetHex().c_str(),vout,coinaddr);
|
||||
if ( vout == 0 && GetTransaction(txid,vintx,hashBlock,false) != 0 )
|
||||
{
|
||||
if ( total != 0 && maxinputs != 0 )
|
||||
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
|
||||
nValue = it->second.satoshis;
|
||||
totalinputs += nValue;
|
||||
n++;
|
||||
if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
|
||||
break;
|
||||
if ( latestheight != 0 )
|
||||
{
|
||||
if ( (ht= komodo_blockheight(hashBlock)) == 0 )
|
||||
{
|
||||
fprintf(stderr,"null ht\n");
|
||||
continue;
|
||||
}
|
||||
else if ( ht > latestheight )
|
||||
{
|
||||
fprintf(stderr,"ht.%d > lastheight.%d\n",ht,latestheight);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ( iter == 0 )
|
||||
{
|
||||
std::vector<uint8_t> scriptPubKey,opret;
|
||||
if ( myGetTransaction(txid,tx,hashBlock) == 0 || tx.vout.size() < 2 || DecodePaymentsFundOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,checktxid) != 'F' || checktxid != createtxid )
|
||||
{
|
||||
fprintf(stderr,"bad opret %s vs %s\n",checktxid.GetHex().c_str(),createtxid.GetHex().c_str());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ( (nValue= IsPaymentsvout(cp,vintx,vout,coinaddr)) > PAYMENTS_TXFEE && nValue >= threshold && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
|
||||
{
|
||||
if ( total != 0 && maxinputs != 0 )
|
||||
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
|
||||
nValue = it->second.satoshis;
|
||||
totalinputs += nValue;
|
||||
n++;
|
||||
if ( (total > 0 && totalinputs >= total) || (maxinputs > 0 && n >= maxinputs) )
|
||||
break;
|
||||
} //else fprintf(stderr,"nValue %.8f vs threshold %.8f\n",(double)nValue/COIN,(double)threshold/COIN);
|
||||
}
|
||||
}
|
||||
}
|
||||
return(totalinputs);
|
||||
}
|
||||
|
||||
std::string PaymentsGet(uint64_t txfee,int64_t nValue)
|
||||
UniValue payments_rawtxresult(UniValue &result,std::string rawtx,int32_t broadcastflag)
|
||||
{
|
||||
CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,Paymentspk; int64_t inputs,CCchange=0; struct CCcontract_info *cp,C; std::string rawhex; uint32_t j; int32_t i,len; uint8_t buf[32768]; bits256 hash;
|
||||
cp = CCinit(&C,EVAL_PAYMENTS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
Paymentspk = GetUnspendable(cp,0);
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
if ( (inputs= AddPaymentsInputs(cp,mtx,Paymentspk,nValue+txfee,60)) > 0 )
|
||||
CTransaction tx;
|
||||
if ( rawtx.size() > 0 )
|
||||
{
|
||||
if ( inputs > nValue )
|
||||
CCchange = (inputs - nValue - txfee);
|
||||
if ( CCchange != 0 )
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_PAYMENTS,CCchange,Paymentspk));
|
||||
mtx.vout.push_back(CTxOut(nValue,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
|
||||
fprintf(stderr,"start at %u\n",(uint32_t)time(NULL));
|
||||
j = rand() & 0xfffffff;
|
||||
for (i=0; i<1000000; i++,j++)
|
||||
result.push_back(Pair("hex",rawtx));
|
||||
if ( DecodeHexTx(tx,rawtx) != 0 )
|
||||
{
|
||||
tmpmtx = mtx;
|
||||
rawhex = FinalizeCCTx(-1LL,cp,tmpmtx,mypk,txfee,CScript() << OP_RETURN << E_MARSHAL(ss << (uint8_t)EVAL_PAYMENTS << (uint8_t)'G' << j));
|
||||
if ( (len= (int32_t)rawhex.size()) > 0 && len < 65536 )
|
||||
{
|
||||
len >>= 1;
|
||||
decode_hex(buf,len,(char *)rawhex.c_str());
|
||||
hash = bits256_doublesha256(0,buf,len);
|
||||
if ( (hash.bytes[0] & 0xff) == 0 && (hash.bytes[31] & 0xff) == 0 )
|
||||
{
|
||||
fprintf(stderr,"found valid txid after %d iterations %u\n",i,(uint32_t)time(NULL));
|
||||
return(rawhex);
|
||||
}
|
||||
//fprintf(stderr,"%02x%02x ",hash.bytes[0],hash.bytes[31]);
|
||||
}
|
||||
}
|
||||
fprintf(stderr,"couldnt generate valid txid %u\n",(uint32_t)time(NULL));
|
||||
return("");
|
||||
} else fprintf(stderr,"cant find Payments inputs\n");
|
||||
return("");
|
||||
}
|
||||
|
||||
std::string PaymentsFund(uint64_t txfee,int64_t funds)
|
||||
{
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey mypk,Paymentspk; CScript opret; struct CCcontract_info *cp,C;
|
||||
cp = CCinit(&C,EVAL_PAYMENTS);
|
||||
if ( txfee == 0 )
|
||||
txfee = 10000;
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
Paymentspk = GetUnspendable(cp,0);
|
||||
if ( AddNormalinputs(mtx,mypk,funds+txfee,64) > 0 )
|
||||
{
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_PAYMENTS,funds,Paymentspk));
|
||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,opret));
|
||||
}
|
||||
return("");
|
||||
}
|
||||
|
||||
UniValue PaymentsInfo()
|
||||
{
|
||||
UniValue result(UniValue::VOBJ); char numstr[64];
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
CPubKey Paymentspk; struct CCcontract_info *cp,C; int64_t funding;
|
||||
result.push_back(Pair("result","success"));
|
||||
result.push_back(Pair("name","Payments"));
|
||||
cp = CCinit(&C,EVAL_PAYMENTS);
|
||||
Paymentspk = GetUnspendable(cp,0);
|
||||
funding = AddPaymentsInputs(cp,mtx,Paymentspk,0,0);
|
||||
sprintf(numstr,"%.8f",(double)funding/COIN);
|
||||
result.push_back(Pair("funding",numstr));
|
||||
if ( broadcastflag != 0 && myAddtomempool(tx) != 0 )
|
||||
RelayTransaction(tx);
|
||||
result.push_back(Pair("txid",tx.GetHash().ToString()));
|
||||
result.push_back(Pair("result","success"));
|
||||
} else result.push_back(Pair("error","decode hex"));
|
||||
} else result.push_back(Pair("error","couldnt finalize payments CCtx"));
|
||||
return(result);
|
||||
}
|
||||
|
||||
cJSON *payments_reparse(int32_t *nump,char *jsonstr)
|
||||
{
|
||||
cJSON *params; char *newstr; int32_t i,j;
|
||||
*nump = 0;
|
||||
if ( jsonstr != 0 )
|
||||
{
|
||||
if ( jsonstr[0] == '"' && jsonstr[strlen(jsonstr)-1] == '"' )
|
||||
{
|
||||
jsonstr[strlen(jsonstr)-1] = 0;
|
||||
jsonstr++;
|
||||
}
|
||||
newstr = (char *)malloc(strlen(jsonstr)+1);
|
||||
for (i=j=0; jsonstr[i]!=0; i++)
|
||||
{
|
||||
if ( jsonstr[i] == '%' && jsonstr[i+1] == '2' && jsonstr[i+2] == '2' )
|
||||
{
|
||||
newstr[j++] = '"';
|
||||
i += 2;
|
||||
}
|
||||
else if ( jsonstr[i] == '\'' )
|
||||
newstr[j++] = '"';
|
||||
else newstr[j++] = jsonstr[i];
|
||||
}
|
||||
newstr[j] = 0;
|
||||
params = cJSON_Parse(newstr);
|
||||
if ( 0 && params != 0 )
|
||||
printf("new.(%s) -> %s\n",newstr,jprint(params,0));
|
||||
free(newstr);
|
||||
*nump = cJSON_GetArraySize(params);
|
||||
} else params = 0;
|
||||
return(params);
|
||||
}
|
||||
|
||||
uint256 payments_juint256(cJSON *obj)
|
||||
{
|
||||
uint256 tmp; bits256 t = jbits256(obj,0);
|
||||
memcpy(&tmp,&t,sizeof(tmp));
|
||||
return(revuint256(tmp));
|
||||
}
|
||||
|
||||
int32_t payments_parsehexdata(std::vector<uint8_t> &hexdata,cJSON *item,int32_t len)
|
||||
{
|
||||
char *hexstr; int32_t val;
|
||||
if ( (hexstr= jstr(item,0)) != 0 && ((val= is_hexstr(hexstr,0)) == len*2 || (val > 0 && len == 0)) )
|
||||
{
|
||||
val >>= 1;
|
||||
hexdata.resize(val);
|
||||
decode_hex(&hexdata[0],val,hexstr);
|
||||
return(0);
|
||||
} else return(-1);
|
||||
}
|
||||
|
||||
UniValue PaymentsRelease(struct CCcontract_info *cp,char *jsonstr)
|
||||
{
|
||||
int32_t latestheight,nextheight = komodo_nextheight();
|
||||
CMutableTransaction tmpmtx,mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),nextheight); UniValue result(UniValue::VOBJ); uint256 createtxid,hashBlock;
|
||||
CTransaction tx,txO; CPubKey mypk,txidpk,Paymentspk; int32_t i,n,numoprets=0,lockedblocks,minrelease,totalallocations,checkallocations=0,allocation; int64_t inputsum,amount,CCchange=0; CTxOut vout; CScript onlyopret; char txidaddr[64],destaddr[64]; std::vector<uint256> txidoprets; std::string rawtx;
|
||||
cJSON *params = payments_reparse(&n,jsonstr);
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
Paymentspk = GetUnspendable(cp,0);
|
||||
if ( params != 0 && n == 2 )
|
||||
{
|
||||
createtxid = payments_juint256(jitem(params,0));
|
||||
amount = jdouble(jitem(params,1),0) * SATOSHIDEN + 0.0000000049;
|
||||
if ( myGetTransaction(createtxid,tx,hashBlock) != 0 )
|
||||
{
|
||||
if ( tx.vout.size() > 0 && DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) != 0 )
|
||||
{
|
||||
if ( lockedblocks < 0 || minrelease < 0 || totalallocations <= 0 || txidoprets.size() < 2 )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","negative parameter"));
|
||||
return(result);
|
||||
}
|
||||
latestheight = (nextheight - lockedblocks - 1);
|
||||
if ( amount < minrelease )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","amount too smal"));
|
||||
result.push_back(Pair("amount",ValueFromAmount(amount)));
|
||||
result.push_back(Pair("minrelease",ValueFromAmount(minrelease)));
|
||||
return(result);
|
||||
}
|
||||
for (i=0; i<txidoprets.size(); i++)
|
||||
{
|
||||
std::vector<uint8_t> scriptPubKey,opret;
|
||||
vout.nValue = 0;
|
||||
if ( myGetTransaction(txidoprets[i],txO,hashBlock) != 0 && txO.vout.size() > 1 && DecodePaymentsTxidOpRet(txO.vout[txO.vout.size()-1].scriptPubKey,allocation,scriptPubKey,opret) == 'T' )
|
||||
{
|
||||
vout.nValue = allocation;
|
||||
vout.scriptPubKey.resize(scriptPubKey.size());
|
||||
memcpy(&vout.scriptPubKey[0],&scriptPubKey[0],scriptPubKey.size());
|
||||
checkallocations += allocation;
|
||||
if ( opret.size() > 0 )
|
||||
{
|
||||
scriptPubKey.resize(opret.size());
|
||||
memcpy(&onlyopret[0],&opret[0],opret.size());
|
||||
numoprets++;
|
||||
}
|
||||
} else break;
|
||||
mtx.vout.push_back(vout);
|
||||
}
|
||||
if ( i != txidoprets.size() )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","invalid txidoprets[i]"));
|
||||
result.push_back(Pair("txi",(int64_t)i));
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
else if ( checkallocations != totalallocations )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","totalallocations mismatch"));
|
||||
result.push_back(Pair("checkallocations",(int64_t)checkallocations));
|
||||
result.push_back(Pair("totalallocations",(int64_t)totalallocations));
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
else if ( numoprets > 1 )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","too many oprets"));
|
||||
result.push_back(Pair("numoprets",(int64_t)numoprets));
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
for (i=0; i<txidoprets.size(); i++)
|
||||
{
|
||||
mtx.vout[i].nValue *= amount;
|
||||
mtx.vout[i].nValue /= totalallocations;
|
||||
}
|
||||
txidpk = CCtxidaddr(txidaddr,createtxid);
|
||||
if ( (inputsum= AddPaymentsInputs(cp,mtx,txidpk,amount+PAYMENTS_TXFEE,60,createtxid,latestheight)) >= amount )
|
||||
{
|
||||
if ( (CCchange= (inputsum - amount)) >= PAYMENTS_TXFEE )
|
||||
mtx.vout.push_back(MakeCC1of2vout(EVAL_PAYMENTS,CCchange,Paymentspk,txidpk));
|
||||
GetCCaddress1of2(cp,destaddr,Paymentspk,txidpk);
|
||||
CCaddr1of2set(cp,Paymentspk,txidpk,cp->CCpriv,destaddr);
|
||||
rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,onlyopret);
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(payments_rawtxresult(result,rawtx,0));
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","couldnt find enough locked funds"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","couldnt decode paymentscreate txid opret"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","couldnt find paymentscreate txid"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","parameters error"));
|
||||
}
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
|
||||
UniValue PaymentsFund(struct CCcontract_info *cp,char *jsonstr)
|
||||
{
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); UniValue result(UniValue::VOBJ);
|
||||
CPubKey Paymentspk,mypk,txidpk; uint256 txid,hashBlock; int64_t amount; CScript opret; CTransaction tx; char txidaddr[64]; std::string rawtx; int32_t n,useopret = 0,lockedblocks,minrelease,totalallocations; std::vector<uint256> txidoprets;
|
||||
cJSON *params = payments_reparse(&n,jsonstr);
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
Paymentspk = GetUnspendable(cp,0);
|
||||
if ( params != 0 && n > 1 && n <= 3 )
|
||||
{
|
||||
txid = payments_juint256(jitem(params,0));
|
||||
amount = jdouble(jitem(params,1),0) * SATOSHIDEN + 0.0000000049;
|
||||
if ( n == 3 )
|
||||
useopret = jint(jitem(params,2),0) != 0;
|
||||
if ( myGetTransaction(txid,tx,hashBlock) == 0 || tx.vout.size() == 1 || DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 0 )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","invalid createtxid"));
|
||||
}
|
||||
else if ( AddNormalinputs(mtx,mypk,amount+PAYMENTS_TXFEE,60) > 0 )
|
||||
{
|
||||
if ( lockedblocks < 0 || minrelease < 0 || totalallocations <= 0 || txidoprets.size() < 2 )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","negative parameter"));
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
if ( useopret == 0 )
|
||||
{
|
||||
txidpk = CCtxidaddr(txidaddr,txid);
|
||||
mtx.vout.push_back(MakeCC1of2vout(EVAL_PAYMENTS,amount,Paymentspk,txidpk));
|
||||
}
|
||||
else
|
||||
{
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_PAYMENTS,amount,Paymentspk));
|
||||
opret = EncodePaymentsFundOpRet(txid);
|
||||
}
|
||||
rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,opret);
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(payments_rawtxresult(result,rawtx,1));
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","couldnt find enough funds"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","parameters error"));
|
||||
}
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
|
||||
UniValue PaymentsTxidopret(struct CCcontract_info *cp,char *jsonstr)
|
||||
{
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight()); UniValue result(UniValue::VOBJ); CPubKey mypk; std::string rawtx;
|
||||
std::vector<uint8_t> scriptPubKey,opret; int32_t allocation,n,retval0,retval1=0;
|
||||
cJSON *params = payments_reparse(&n,jsonstr);
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
if ( params != 0 && n > 1 && n <= 3 )
|
||||
{
|
||||
allocation = juint(jitem(params,0),0);
|
||||
retval0 = payments_parsehexdata(scriptPubKey,jitem(params,1),0);
|
||||
if ( n == 3 )
|
||||
retval1 = payments_parsehexdata(opret,jitem(params,2),0);
|
||||
if ( allocation > 0 && retval0 == 0 && retval1 == 0 && AddNormalinputs(mtx,mypk,PAYMENTS_TXFEE,10) > 0 )
|
||||
{
|
||||
rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,EncodePaymentsTxidOpRet(allocation,scriptPubKey,opret));
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(payments_rawtxresult(result,rawtx,1));
|
||||
}
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","invalid params or cant find txfee"));
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","parameters error"));
|
||||
result.push_back(Pair("n",(int64_t)n));
|
||||
fprintf(stderr,"(%s) %p\n",jsonstr,params);
|
||||
}
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
|
||||
UniValue PaymentsCreate(struct CCcontract_info *cp,char *jsonstr)
|
||||
{
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
UniValue result(UniValue::VOBJ); CTransaction tx; CPubKey Paymentspk,mypk; char markeraddr[64]; std::vector<uint256> txidoprets; uint256 hashBlock; int32_t i,n,numoprets=0,lockedblocks,minrelease,totalallocations=0; std::string rawtx;
|
||||
cJSON *params = payments_reparse(&n,jsonstr);
|
||||
if ( params != 0 && n >= 4 )
|
||||
{
|
||||
lockedblocks = juint(jitem(params,0),0);
|
||||
minrelease = juint(jitem(params,1),0);
|
||||
if ( lockedblocks < 0 || minrelease < 0 )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","negative parameter"));
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
for (i=0; i<n-2; i++)
|
||||
txidoprets.push_back(payments_juint256(jitem(params,2+i)));
|
||||
for (i=0; i<txidoprets.size(); i++)
|
||||
{
|
||||
std::vector<uint8_t> scriptPubKey,opret; int32_t allocation;
|
||||
if ( myGetTransaction(txidoprets[i],tx,hashBlock) != 0 && tx.vout.size() > 1 && DecodePaymentsTxidOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,allocation,scriptPubKey,opret) == 'T' )
|
||||
{
|
||||
totalallocations += allocation;
|
||||
if ( opret.size() > 0 )
|
||||
numoprets++;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","invalid txidopret"));
|
||||
result.push_back(Pair("txid",txidoprets[i].GetHex()));
|
||||
result.push_back(Pair("txi",(int64_t)i));
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
}
|
||||
if ( numoprets > 1 )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","too many opreturns"));
|
||||
result.push_back(Pair("numoprets",(int64_t)numoprets));
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
mypk = pubkey2pk(Mypubkey());
|
||||
Paymentspk = GetUnspendable(cp,0);
|
||||
if ( AddNormalinputs(mtx,mypk,2*PAYMENTS_TXFEE,60) > 0 )
|
||||
{
|
||||
mtx.vout.push_back(MakeCC1of2vout(cp->evalcode,PAYMENTS_TXFEE,Paymentspk,Paymentspk));
|
||||
rawtx = FinalizeCCTx(0,cp,mtx,mypk,PAYMENTS_TXFEE,EncodePaymentsOpRet(lockedblocks,minrelease,totalallocations,txidoprets));
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(payments_rawtxresult(result,rawtx,1));
|
||||
}
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","not enough normal funds"));
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","parameters error"));
|
||||
}
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
|
||||
UniValue PaymentsInfo(struct CCcontract_info *cp,char *jsonstr)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ),a(UniValue::VARR); CTransaction tx,txO; CPubKey Paymentspk,txidpk; int32_t i,j,n,flag=0,allocation,numoprets=0,lockedblocks,minrelease,totalallocations; std::vector<uint256> txidoprets; int64_t funds,fundsopret; char fundsaddr[64],fundsopretaddr[64],txidaddr[64],*outstr; uint256 createtxid,hashBlock;
|
||||
cJSON *params = payments_reparse(&n,jsonstr);
|
||||
if ( params != 0 && n == 1 )
|
||||
{
|
||||
Paymentspk = GetUnspendable(cp,0);
|
||||
createtxid = payments_juint256(jitem(params,0));
|
||||
if ( myGetTransaction(createtxid,tx,hashBlock) != 0 )
|
||||
{
|
||||
if ( tx.vout.size() > 0 && DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) != 0 )
|
||||
{
|
||||
if ( lockedblocks < 0 || minrelease < 0 || totalallocations <= 0 || txidoprets.size() < 2 )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","negative parameter"));
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
result.push_back(Pair("lockedblocks",(int64_t)lockedblocks));
|
||||
result.push_back(Pair("totalallocations",(int64_t)totalallocations));
|
||||
result.push_back(Pair("minrelease",(int64_t)minrelease));
|
||||
for (i=0; i<txidoprets.size(); i++)
|
||||
{
|
||||
UniValue obj(UniValue::VOBJ); std::vector<uint8_t> scriptPubKey,opret;
|
||||
obj.push_back(Pair("txidopret",txidoprets[i].GetHex()));
|
||||
if ( myGetTransaction(txidoprets[i],txO,hashBlock) != 0 && txO.vout.size() > 1 && DecodePaymentsTxidOpRet(txO.vout[txO.vout.size()-1].scriptPubKey,allocation,scriptPubKey,opret) == 'T' )
|
||||
{
|
||||
outstr = (char *)malloc(scriptPubKey.size() + opret.size() + 1);
|
||||
for (j=0; j<scriptPubKey.size(); j++)
|
||||
outstr[j] = scriptPubKey[j];
|
||||
outstr[j] = 0;
|
||||
obj.push_back(Pair("scriptPubKey",outstr));
|
||||
if ( opret.size() != 0 )
|
||||
{
|
||||
for (j=0; j<opret.size(); j++)
|
||||
outstr[j] = opret[j];
|
||||
outstr[j] = 0;
|
||||
obj.push_back(Pair("opreturn",outstr));
|
||||
numoprets++;
|
||||
}
|
||||
free(outstr);
|
||||
}
|
||||
}
|
||||
flag++;
|
||||
if ( numoprets > 1 )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","too many opreturns"));
|
||||
result.push_back(Pair("numoprets",(int64_t)numoprets));
|
||||
}
|
||||
else
|
||||
{
|
||||
txidpk = CCtxidaddr(txidaddr,createtxid);
|
||||
GetCCaddress1of2(cp,fundsaddr,Paymentspk,txidpk);
|
||||
funds = CCaddress_balance(fundsaddr);
|
||||
result.push_back(Pair(fundsaddr,ValueFromAmount(funds)));
|
||||
GetCCaddress(cp,fundsopretaddr,Paymentspk);
|
||||
fundsopret = CCaddress_balance(fundsopretaddr);
|
||||
result.push_back(Pair(fundsopretaddr,ValueFromAmount(fundsopret)));
|
||||
result.push_back(Pair("totalfunds",ValueFromAmount(funds+fundsopret)));
|
||||
result.push_back(Pair("result","success"));
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( flag == 0 )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","couldnt find valid payments create txid"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","parameters error"));
|
||||
}
|
||||
if ( params != 0 )
|
||||
free_json(params);
|
||||
return(result);
|
||||
}
|
||||
|
||||
UniValue PaymentsList(struct CCcontract_info *cp,char *jsonstr)
|
||||
{
|
||||
std::vector<std::pair<CAddressIndexKey, CAmount> > addressIndex; uint256 txid,hashBlock;
|
||||
UniValue result(UniValue::VOBJ),a(UniValue::VARR); char markeraddr[64],str[65]; CPubKey Paymentspk; CTransaction tx; int32_t lockedblocks,minrelease,totalallocations; std::vector<uint256> txidoprets;
|
||||
Paymentspk = GetUnspendable(cp,0);
|
||||
GetCCaddress1of2(cp,markeraddr,Paymentspk,Paymentspk);
|
||||
SetCCtxids(addressIndex,markeraddr);
|
||||
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++)
|
||||
{
|
||||
txid = it->first.txhash;
|
||||
if ( it->first.index == 0 && myGetTransaction(txid,tx,hashBlock) != 0 )
|
||||
{
|
||||
if ( tx.vout.size() > 0 && DecodePaymentsOpRet(tx.vout[tx.vout.size()-1].scriptPubKey,lockedblocks,minrelease,totalallocations,txidoprets) == 'C' )
|
||||
{
|
||||
if ( lockedblocks < 0 || minrelease < 0 || totalallocations <= 0 || txidoprets.size() < 2 )
|
||||
{
|
||||
result.push_back(Pair("result","error"));
|
||||
result.push_back(Pair("error","negative parameter"));
|
||||
return(result);
|
||||
}
|
||||
a.push_back(uint256_str(str,txid));
|
||||
}
|
||||
}
|
||||
}
|
||||
result.push_back(Pair("result","success"));
|
||||
result.push_back(Pair("createtxids",a));
|
||||
return(result);
|
||||
}
|
||||
|
||||
@@ -334,7 +334,7 @@ std::string PricesAddFunding(uint64_t txfee,uint256 refbettoken,uint256 fundingt
|
||||
std::vector<CPubKey> voutTokenPubkeysEmpty; //TODO: add token vout pubkeys
|
||||
return(FinalizeCCTx(0,cp,mtx,mypk,txfee,
|
||||
EncodeTokenOpRet(bettoken, voutTokenPubkeysEmpty,
|
||||
EncodeAssetOpRet('t',/*bettoken,*/zeroid, 0, Mypubkey()))));
|
||||
std::make_pair(OPRETID_ASSETSDATA, EncodeAssetOpRet('t',/*bettoken,*/zeroid, 0, Mypubkey())))));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -333,7 +333,11 @@ int64_t AddRewardsInputs(CScript &scriptPubKey,uint64_t maxseconds,struct CCcont
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
GetCCaddress(cp,coinaddr,pk);
|
||||
SetCCunspents(unspentOutputs,coinaddr);
|
||||
threshold = total/(maxinputs+1);
|
||||
if ( maxinputs > CC_MAXVINS )
|
||||
maxinputs = CC_MAXVINS;
|
||||
if ( maxinputs > 0 )
|
||||
threshold = total/maxinputs;
|
||||
else threshold = total;
|
||||
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
|
||||
{
|
||||
txid = it->first.txhash;
|
||||
|
||||
@@ -26,10 +26,10 @@ O=o
|
||||
CC = x86_64-w64-mingw32-gcc
|
||||
|
||||
#CFLAGS=-O2
|
||||
CFLAGS= -g -O2 -I./ncurses/include -I./ncurses/include/ncursesw -I../../../depends/x86_64-w64-mingw32/include
|
||||
CFLAGS= -g -O2 -I./x86_64-w64-mingw32/include -I./x86_64-w64-mingw32/include/ncursesw
|
||||
|
||||
#LIBS=-lcurses
|
||||
LIBS = -L./ncurses/lib -lncursesw -lcurl
|
||||
LIBS = -L./x86_64-w64-mingw32/lib -lncursesw -lcurl
|
||||
|
||||
#RM=rm -f
|
||||
RM = rm -f
|
||||
|
||||
@@ -25,7 +25,6 @@ command(struct rogue_state *rs)
|
||||
char *fp;
|
||||
THING *mp;
|
||||
static char countch, direction, newcount = FALSE;
|
||||
|
||||
if (on(player, ISHASTE))
|
||||
ntimes++;
|
||||
/*
|
||||
@@ -345,7 +344,7 @@ over:
|
||||
if (wizard)
|
||||
{
|
||||
wizard = FALSE;
|
||||
turn_see(TRUE);
|
||||
turn_see(rs,TRUE);
|
||||
msg(rs,"not wizard any more");
|
||||
}
|
||||
else
|
||||
@@ -354,7 +353,7 @@ over:
|
||||
if (wizard)
|
||||
{
|
||||
noscore = TRUE;
|
||||
turn_see(FALSE);
|
||||
turn_see(rs,FALSE);
|
||||
msg(rs,"you are suddenly as smart as Ken Arnold in dungeon #%d", dnum);
|
||||
}
|
||||
else
|
||||
@@ -404,7 +403,7 @@ over:
|
||||
when CTRL('T'): teleport();
|
||||
when CTRL('E'): msg(rs,"food left: %d", food_left);
|
||||
when CTRL('C'): add_pass();
|
||||
when CTRL('X'): turn_see(on(player, SEEMONST));
|
||||
when CTRL('X'): turn_see(rs,on(player, SEEMONST));
|
||||
when CTRL('~'):
|
||||
{
|
||||
THING *item;
|
||||
@@ -456,7 +455,7 @@ over:
|
||||
if (!running)
|
||||
door_stop = FALSE;
|
||||
}
|
||||
/*
|
||||
/*
|
||||
* If he ran into something to take, let him pick it up.
|
||||
*/
|
||||
if (take != 0)
|
||||
|
||||
@@ -160,10 +160,43 @@ extinguish(void (*func)(struct rogue_state *rs,int))
|
||||
* do_fuses:
|
||||
* Decrement counters and start needed fuses
|
||||
*/
|
||||
|
||||
/*char *actionfunc_str(char *str,void *ptr)
|
||||
{
|
||||
if ( ptr == (void *)runners )
|
||||
strcpy(str,"runners");
|
||||
else if ( ptr == (void *)doctor )
|
||||
strcpy(str,"doctor");
|
||||
else if ( ptr == (void *)stomach )
|
||||
strcpy(str,"stomach");
|
||||
else if ( ptr == (void *)nohaste )
|
||||
strcpy(str,"nohaste");
|
||||
else if ( ptr == (void *)unconfuse )
|
||||
strcpy(str,"unconfuse");
|
||||
else if ( ptr == (void *)swander )
|
||||
strcpy(str,"swander");
|
||||
else if ( ptr == (void *)come_down )
|
||||
strcpy(str,"come_down");
|
||||
else if ( ptr == (void *)unsee )
|
||||
strcpy(str,"unsee");
|
||||
else if ( ptr == (void *)sight )
|
||||
strcpy(str,"sight");
|
||||
else if ( ptr == (void *)land )
|
||||
strcpy(str,"land");
|
||||
else if ( ptr == (void *)rollwand )
|
||||
strcpy(str,"rollwand");
|
||||
else if ( ptr == (void *)visuals )
|
||||
strcpy(str,"visuals");
|
||||
else if ( ptr == (void *)turn_see )
|
||||
strcpy(str,"turn_see");
|
||||
else strcpy(str,"no match");
|
||||
return(str);
|
||||
}*/
|
||||
|
||||
void
|
||||
do_fuses(struct rogue_state *rs,int flag)
|
||||
{
|
||||
register struct delayed_action *wire;
|
||||
register struct delayed_action *wire; char str[64];
|
||||
|
||||
/*
|
||||
* Step though the list
|
||||
@@ -175,6 +208,8 @@ do_fuses(struct rogue_state *rs,int flag)
|
||||
*/
|
||||
if (flag == wire->d_type && wire->d_time > 0 && --wire->d_time == 0)
|
||||
{
|
||||
//if ( fp != 0 )
|
||||
// fprintf(fp,"t.%d %d %s, ",wire->d_type,wire->d_time,actionfunc_str(str,wire->d_func));
|
||||
wire->d_type = EMPTY;
|
||||
(*wire->d_func)(rs,wire->d_arg);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@ void
|
||||
doctor(struct rogue_state *rs,int arg)
|
||||
{
|
||||
register int lv, ohp;
|
||||
if ( rs->logfp != 0 )
|
||||
fprintf(rs->logfp,"doctor\n");
|
||||
|
||||
lv = pstats.s_lvl;
|
||||
ohp = pstats.s_hpt;
|
||||
@@ -52,6 +54,8 @@ doctor(struct rogue_state *rs,int arg)
|
||||
void
|
||||
swander(struct rogue_state *rs,int arg)
|
||||
{
|
||||
if ( rs->logfp != 0 )
|
||||
fprintf(rs->logfp,"swander\n");
|
||||
start_daemon(rollwand, 0, BEFORE);
|
||||
}
|
||||
|
||||
@@ -63,6 +67,8 @@ int between = 0;
|
||||
void
|
||||
rollwand(struct rogue_state *rs,int arg)
|
||||
{
|
||||
if ( rs->logfp != 0 )
|
||||
fprintf(rs->logfp,"rollwand\n");
|
||||
if (++between >= 4)
|
||||
{
|
||||
if (roll(1, 6) == 4)
|
||||
@@ -82,6 +88,8 @@ rollwand(struct rogue_state *rs,int arg)
|
||||
void
|
||||
unconfuse(struct rogue_state *rs,int arg)
|
||||
{
|
||||
if ( rs->logfp != 0 )
|
||||
fprintf(rs->logfp,"unconfuse\n");
|
||||
player.t_flags &= ~ISHUH;
|
||||
msg(rs,"you feel less %s now", choose_str("trippy", "confused"));
|
||||
}
|
||||
@@ -94,6 +102,8 @@ void
|
||||
unsee(struct rogue_state *rs,int arg)
|
||||
{
|
||||
register THING *th;
|
||||
if ( rs->logfp != 0 )
|
||||
fprintf(rs->logfp,"unsee\n");
|
||||
|
||||
for (th = mlist; th != NULL; th = next(th))
|
||||
if (on(*th, ISINVIS) && see_monst(th))
|
||||
@@ -108,6 +118,8 @@ unsee(struct rogue_state *rs,int arg)
|
||||
void
|
||||
sight(struct rogue_state *rs,int arg)
|
||||
{
|
||||
if ( rs->logfp != 0 )
|
||||
fprintf(rs->logfp,"sight\n");
|
||||
if (on(player, ISBLIND))
|
||||
{
|
||||
extinguish(sight);
|
||||
@@ -126,6 +138,8 @@ sight(struct rogue_state *rs,int arg)
|
||||
void
|
||||
nohaste(struct rogue_state *rs,int arg)
|
||||
{
|
||||
if ( rs->logfp != 0 )
|
||||
fprintf(rs->logfp,"nohaste\n");
|
||||
player.t_flags &= ~ISHASTE;
|
||||
msg(rs,"you feel yourself slowing down");
|
||||
}
|
||||
@@ -139,6 +153,8 @@ stomach(struct rogue_state *rs,int arg)
|
||||
{
|
||||
register int oldfood;
|
||||
int orig_hungry = hungry_state;
|
||||
if ( rs->logfp != 0 )
|
||||
fprintf(rs->logfp,"stomach\n");
|
||||
|
||||
if (food_left <= 0)
|
||||
{
|
||||
@@ -194,41 +210,43 @@ come_down(struct rogue_state *rs,int arg)
|
||||
{
|
||||
register THING *tp;
|
||||
register bool seemonst;
|
||||
|
||||
|
||||
if ( rs->logfp != 0 )
|
||||
fprintf(rs->logfp,"come_down\n");
|
||||
if (!on(player, ISHALU))
|
||||
return;
|
||||
|
||||
return;
|
||||
|
||||
kill_daemon(visuals);
|
||||
player.t_flags &= ~ISHALU;
|
||||
|
||||
|
||||
if (on(player, ISBLIND))
|
||||
return;
|
||||
|
||||
return;
|
||||
|
||||
/*
|
||||
* undo the things
|
||||
*/
|
||||
for (tp = lvl_obj; tp != NULL; tp = next(tp))
|
||||
if (cansee(rs,tp->o_pos.y, tp->o_pos.x))
|
||||
mvaddch(tp->o_pos.y, tp->o_pos.x, tp->o_type);
|
||||
|
||||
if (cansee(rs,tp->o_pos.y, tp->o_pos.x))
|
||||
mvaddch(tp->o_pos.y, tp->o_pos.x, tp->o_type);
|
||||
|
||||
/*
|
||||
* undo the monsters
|
||||
*/
|
||||
seemonst = on(player, SEEMONST);
|
||||
for (tp = mlist; tp != NULL; tp = next(tp))
|
||||
{
|
||||
move(tp->t_pos.y, tp->t_pos.x);
|
||||
if (cansee(rs,tp->t_pos.y, tp->t_pos.x))
|
||||
if (!on(*tp, ISINVIS) || on(player, CANSEE))
|
||||
addch(tp->t_disguise);
|
||||
else
|
||||
addch(chat(tp->t_pos.y, tp->t_pos.x));
|
||||
else if (seemonst)
|
||||
{
|
||||
standout();
|
||||
addch(tp->t_type);
|
||||
standend();
|
||||
}
|
||||
move(tp->t_pos.y, tp->t_pos.x);
|
||||
if (cansee(rs,tp->t_pos.y, tp->t_pos.x))
|
||||
if (!on(*tp, ISINVIS) || on(player, CANSEE))
|
||||
addch(tp->t_disguise);
|
||||
else
|
||||
addch(chat(tp->t_pos.y, tp->t_pos.x));
|
||||
else if (seemonst)
|
||||
{
|
||||
standout();
|
||||
addch(tp->t_type);
|
||||
standend();
|
||||
}
|
||||
}
|
||||
msg(rs,"Everything looks SO boring now.");
|
||||
}
|
||||
@@ -242,42 +260,44 @@ visuals(struct rogue_state *rs,int arg)
|
||||
{
|
||||
register THING *tp;
|
||||
register bool seemonst;
|
||||
|
||||
|
||||
if (!after || (running && jump))
|
||||
return;
|
||||
return;
|
||||
if ( rs->logfp != 0 )
|
||||
fprintf(rs->logfp,"visuals\n");
|
||||
/*
|
||||
* change the things
|
||||
*/
|
||||
for (tp = lvl_obj; tp != NULL; tp = next(tp))
|
||||
if (cansee(rs,tp->o_pos.y, tp->o_pos.x))
|
||||
mvaddch(tp->o_pos.y, tp->o_pos.x, rnd_thing());
|
||||
|
||||
if (cansee(rs,tp->o_pos.y, tp->o_pos.x))
|
||||
mvaddch(tp->o_pos.y, tp->o_pos.x, rnd_thing());
|
||||
|
||||
/*
|
||||
* change the stairs
|
||||
*/
|
||||
if (!seenstairs && cansee(rs,stairs.y, stairs.x))
|
||||
mvaddch(stairs.y, stairs.x, rnd_thing());
|
||||
|
||||
mvaddch(stairs.y, stairs.x, rnd_thing());
|
||||
|
||||
/*
|
||||
* change the monsters
|
||||
*/
|
||||
seemonst = on(player, SEEMONST);
|
||||
for (tp = mlist; tp != NULL; tp = next(tp))
|
||||
{
|
||||
move(tp->t_pos.y, tp->t_pos.x);
|
||||
if (see_monst(tp))
|
||||
{
|
||||
if (tp->t_type == 'X' && tp->t_disguise != 'X')
|
||||
addch(rnd_thing());
|
||||
else
|
||||
addch(rnd(26) + 'A');
|
||||
}
|
||||
else if (seemonst)
|
||||
{
|
||||
standout();
|
||||
addch(rnd(26) + 'A');
|
||||
standend();
|
||||
}
|
||||
move(tp->t_pos.y, tp->t_pos.x);
|
||||
if (see_monst(tp))
|
||||
{
|
||||
if (tp->t_type == 'X' && tp->t_disguise != 'X')
|
||||
addch(rnd_thing());
|
||||
else
|
||||
addch(rnd(26) + 'A');
|
||||
}
|
||||
else if (seemonst)
|
||||
{
|
||||
standout();
|
||||
addch(rnd(26) + 'A');
|
||||
standend();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,7 +308,54 @@ visuals(struct rogue_state *rs,int arg)
|
||||
void
|
||||
land(struct rogue_state *rs,int arg)
|
||||
{
|
||||
if ( rs->logfp != 0 )
|
||||
fprintf(rs->logfp,"land\n");
|
||||
player.t_flags &= ~ISLEVIT;
|
||||
msg(rs,choose_str("bummer! You've hit the ground",
|
||||
"you float gently to the ground"));
|
||||
}
|
||||
|
||||
/*
|
||||
* turn_see:
|
||||
* Put on or off seeing monsters on this level
|
||||
*/
|
||||
bool
|
||||
turn_see(struct rogue_state *rs,bool turn_off)
|
||||
{
|
||||
THING *mp;
|
||||
bool can_see, add_new;
|
||||
if ( rs->logfp != 0 )
|
||||
fprintf(rs->logfp,"turn_see\n");
|
||||
|
||||
add_new = FALSE;
|
||||
for (mp = mlist; mp != NULL; mp = next(mp))
|
||||
{
|
||||
move(mp->t_pos.y, mp->t_pos.x);
|
||||
can_see = see_monst(mp);
|
||||
if (turn_off)
|
||||
{
|
||||
if (!can_see)
|
||||
addch(mp->t_oldch);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!can_see)
|
||||
standout();
|
||||
if (!on(player, ISHALU))
|
||||
addch(mp->t_type);
|
||||
else
|
||||
addch(rnd(26) + 'A');
|
||||
if (!can_see)
|
||||
{
|
||||
standend();
|
||||
add_new ^= 1;//add_new++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (turn_off)
|
||||
player.t_flags &= ~SEEMONST;
|
||||
else
|
||||
player.t_flags |= SEEMONST;
|
||||
return add_new;
|
||||
}
|
||||
|
||||
|
||||
@@ -107,6 +107,12 @@
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef _MSC_VER
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#undef SIGTSTP
|
||||
|
||||
#define MAXSTR 1024 /* maximum length of strings */
|
||||
@@ -142,7 +148,8 @@ void leave(int);
|
||||
void my_exit(int st);
|
||||
void playltchars(void);
|
||||
void quit(int);
|
||||
int32_t _quit();
|
||||
int32_t _quit();
|
||||
|
||||
void resetltchars(void);
|
||||
void set_order(int *order, int numthings);
|
||||
void tstp(int ignored);
|
||||
|
||||
@@ -290,27 +290,27 @@ attack(struct rogue_state *rs,THING *mp)
|
||||
}
|
||||
when 'N':
|
||||
{
|
||||
register THING *obj, *steal;
|
||||
register int nobj;
|
||||
|
||||
/*
|
||||
* Nymph's steal a magic item, look through the pack
|
||||
* and pick out one we like.
|
||||
*/
|
||||
steal = NULL;
|
||||
for (nobj = 0, obj = pack; obj != NULL; obj = next(obj))
|
||||
if (obj != cur_armor && obj != cur_weapon
|
||||
&& obj != cur_ring[LEFT] && obj != cur_ring[RIGHT]
|
||||
&& is_magic(obj) && rnd(++nobj) == 0)
|
||||
steal = obj;
|
||||
if (steal != NULL)
|
||||
{
|
||||
remove_mon(rs,&mp->t_pos, moat(mp->t_pos.y, mp->t_pos.x), FALSE);
|
||||
mp=NULL;
|
||||
leave_pack(rs,steal, FALSE, FALSE);
|
||||
msg(rs,"she stole %s!", inv_name(steal, TRUE));
|
||||
discard(steal);
|
||||
}
|
||||
THING *obj, *steal; int nobj;
|
||||
|
||||
/*
|
||||
* Nymph's steal a magic item, look through the pack
|
||||
* and pick out one we like.
|
||||
*/
|
||||
steal = NULL;
|
||||
for (nobj = 0, obj = pack; obj != NULL; obj = next(obj))
|
||||
if (obj != cur_armor && obj != cur_weapon
|
||||
&& obj != cur_ring[LEFT] && obj != cur_ring[RIGHT]
|
||||
&& is_magic(obj) && rnd(++nobj) == 0)
|
||||
steal = obj;
|
||||
if (steal != NULL)
|
||||
{
|
||||
remove_mon(rs,&mp->t_pos, moat(mp->t_pos.y, mp->t_pos.x), FALSE);
|
||||
mp=NULL;
|
||||
leave_pack(rs,steal, FALSE, FALSE);
|
||||
msg(rs,"she stole %s!", inv_name(steal, TRUE));
|
||||
if ( steal->o_count <= 0 )
|
||||
discard(steal);
|
||||
}
|
||||
}
|
||||
otherwise:
|
||||
break;
|
||||
@@ -594,26 +594,24 @@ void
|
||||
remove_mon(struct rogue_state *rs,coord *mp, THING *tp, bool waskill)
|
||||
{
|
||||
register THING *obj, *nexti;
|
||||
|
||||
for (obj = tp->t_pack; obj != NULL; obj = nexti)
|
||||
{
|
||||
nexti = next(obj);
|
||||
obj->o_pos = tp->t_pos;
|
||||
detach(tp->t_pack, obj);
|
||||
if (waskill)
|
||||
fall(rs,obj, FALSE);
|
||||
else
|
||||
discard(obj);
|
||||
nexti = next(obj);
|
||||
obj->o_pos = tp->t_pos;
|
||||
detach(tp->t_pack, obj);
|
||||
if (waskill)
|
||||
fall(rs,obj, FALSE);
|
||||
else discard(obj);
|
||||
}
|
||||
moat(mp->y, mp->x) = NULL;
|
||||
mvaddch(mp->y, mp->x, tp->t_oldch);
|
||||
detach(mlist, tp);
|
||||
if (on(*tp, ISTARGET))
|
||||
{
|
||||
kamikaze = FALSE;
|
||||
to_death = FALSE;
|
||||
if (fight_flush)
|
||||
flush_type();
|
||||
kamikaze = FALSE;
|
||||
to_death = FALSE;
|
||||
if (fight_flush)
|
||||
flush_type();
|
||||
}
|
||||
discard(tp);
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@ readchar(struct rogue_state *rs)
|
||||
fp = fopen("log","wb");
|
||||
if ( fp != 0 )
|
||||
{
|
||||
fprintf(fp,"%d: (%c) hp.%d\n",counter,c,pstats.s_hpt);
|
||||
fprintf(fp,"%d: (%c) hp.%d num.%d gold.%d seed.%llu\n",counter,c,pstats.s_hpt,num_packitems(rs),purse,(long long)seed);
|
||||
fflush(fp);
|
||||
counter++;
|
||||
}
|
||||
|
||||
@@ -19,80 +19,38 @@
|
||||
int total = 0; /* total dynamic memory bytes */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* detach:
|
||||
* takes an item out of whatever linked list it might be in
|
||||
*/
|
||||
|
||||
void
|
||||
_detach(THING **list, THING *item)
|
||||
{
|
||||
if (*list == item)
|
||||
*list = next(item);
|
||||
if (prev(item) != NULL)
|
||||
item->l_prev->l_next = next(item);
|
||||
if (next(item) != NULL)
|
||||
item->l_next->l_prev = prev(item);
|
||||
item->l_next = NULL;
|
||||
item->l_prev = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* _attach:
|
||||
* add an item to the head of a list
|
||||
*/
|
||||
|
||||
void
|
||||
_attach(THING **list, THING *item)
|
||||
{
|
||||
if (*list != NULL)
|
||||
{
|
||||
item->l_next = *list;
|
||||
(*list)->l_prev = item;
|
||||
item->l_prev = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
item->l_next = NULL;
|
||||
item->l_prev = NULL;
|
||||
}
|
||||
*list = item;
|
||||
}
|
||||
|
||||
/*
|
||||
* _free_list:
|
||||
* Throw the whole blamed thing away
|
||||
*/
|
||||
|
||||
void
|
||||
_free_list(THING **ptr)
|
||||
{
|
||||
THING *item;
|
||||
|
||||
while (*ptr != NULL)
|
||||
{
|
||||
item = *ptr;
|
||||
*ptr = next(item);
|
||||
discard(item);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* discard:
|
||||
* Free up an item
|
||||
*/
|
||||
|
||||
//#define ENABLE_DEBUG
|
||||
#define MAX_DEBUGPTRS 100000
|
||||
|
||||
int32_t itemcounter;
|
||||
THING *thingptrs[100000];
|
||||
THING *thingptrs[MAX_DEBUGPTRS];
|
||||
int32_t numptrs;
|
||||
|
||||
int32_t thing_find(THING *item)
|
||||
{
|
||||
#ifdef ENABLE_DEBUG
|
||||
int32_t i;
|
||||
for (i=0; i<numptrs; i++)
|
||||
if ( item == thingptrs[i] )
|
||||
return(i);
|
||||
return(-1);
|
||||
#else
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
discard(THING *item)
|
||||
{
|
||||
#ifdef MASTER
|
||||
total--;
|
||||
#endif
|
||||
if ( 0 )
|
||||
#ifdef ENABLE_DEBUG
|
||||
{
|
||||
int32_t i;
|
||||
for (i=0; i<numptrs; i++)
|
||||
@@ -103,6 +61,17 @@ discard(THING *item)
|
||||
break;
|
||||
}
|
||||
}
|
||||
THING *list = pack;
|
||||
for (; list != NULL; list = next(list))
|
||||
{
|
||||
if ( list == item )
|
||||
{
|
||||
fprintf(stderr,"pack item discarded? (%s)\n",inv_name(list,FALSE));
|
||||
sleep(3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
itemcounter--;
|
||||
free((char *) item);
|
||||
}
|
||||
@@ -121,6 +90,63 @@ void garbage_collect()
|
||||
numptrs = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* detach:
|
||||
* takes an item out of whatever linked list it might be in
|
||||
*/
|
||||
|
||||
void
|
||||
_detach(THING **list, THING *item)
|
||||
{
|
||||
if (*list == item)
|
||||
*list = next(item);
|
||||
if (prev(item) != NULL)
|
||||
item->l_prev->l_next = next(item);
|
||||
if (next(item) != NULL)
|
||||
item->l_next->l_prev = prev(item);
|
||||
item->l_next = NULL;
|
||||
item->l_prev = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* _attach:
|
||||
* add an item to the head of a list
|
||||
*/
|
||||
|
||||
void
|
||||
_attach(THING **list, THING *item)
|
||||
{
|
||||
if (*list != NULL)
|
||||
{
|
||||
item->l_next = *list;
|
||||
(*list)->l_prev = item;
|
||||
item->l_prev = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
item->l_next = NULL;
|
||||
item->l_prev = NULL;
|
||||
}
|
||||
*list = item;
|
||||
}
|
||||
|
||||
/*
|
||||
* _free_list:
|
||||
* Throw the whole blamed thing away
|
||||
*/
|
||||
|
||||
void
|
||||
_free_list(THING **ptr)
|
||||
{
|
||||
THING *item;
|
||||
while (*ptr != NULL)
|
||||
{
|
||||
item = *ptr;
|
||||
*ptr = next(item);
|
||||
discard(item);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* new_item
|
||||
* Get a new item with a specified size
|
||||
@@ -139,12 +165,14 @@ new_item(void)
|
||||
#else
|
||||
item = (THING *)calloc(1, sizeof *item);
|
||||
#endif
|
||||
if ( 0 )
|
||||
#ifdef ENABLE_DEBUG
|
||||
if ( numptrs < MAX_DEBUGPTRS )
|
||||
{
|
||||
thingptrs[numptrs++] = item;
|
||||
if ( (++itemcounter % 100) == 0 )
|
||||
fprintf(stderr,"itemcounter.%d\n",itemcounter);
|
||||
}
|
||||
#endif
|
||||
item->l_next = NULL;
|
||||
item->l_prev = NULL;
|
||||
return item;
|
||||
|
||||
@@ -38,6 +38,31 @@ union _bits256 { uint8_t bytes[32]; uint16_t ushorts[16]; uint32_t uints[8]; uin
|
||||
typedef union _bits256 bits256;
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef _MSC_VER
|
||||
int gettimeofday(struct timeval * tp, struct timezone * tzp)
|
||||
{
|
||||
// Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's
|
||||
static const uint64_t EPOCH = ((uint64_t)116444736000000000ULL);
|
||||
|
||||
SYSTEMTIME system_time;
|
||||
FILETIME file_time;
|
||||
uint64_t time;
|
||||
|
||||
GetSystemTime(&system_time);
|
||||
SystemTimeToFileTime(&system_time, &file_time);
|
||||
time = ((uint64_t)file_time.dwLowDateTime);
|
||||
time += ((uint64_t)file_time.dwHighDateTime) << 32;
|
||||
|
||||
tp->tv_sec = (long)((time - EPOCH) / 10000000L);
|
||||
tp->tv_usec = (long)(system_time.wMilliseconds * 1000);
|
||||
return 0;
|
||||
}
|
||||
#endif // _MSC_VER
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
double OS_milliseconds()
|
||||
{
|
||||
struct timeval tv; double millis;
|
||||
@@ -235,6 +260,7 @@ int32_t safecopy(char *dest,char *src,long len)
|
||||
#endif
|
||||
|
||||
int32_t rogue_replay(uint64_t seed,int32_t sleeptime);
|
||||
char *rogue_keystrokesload(int32_t *numkeysp,uint64_t seed,int32_t counter);
|
||||
int rogue(int argc, char **argv, char **envp);
|
||||
|
||||
void *OS_loadfile(char *fname,uint8_t **bufp,long *lenp,long *allocsizep)
|
||||
@@ -391,6 +417,12 @@ char *post_process_bitcoind_RPC(char *debugstr,char *command,char *rpcstr,char *
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef _MSC_VER
|
||||
#define sleep(x) Sleep(1000*(x))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/************************************************************************
|
||||
*
|
||||
* perform the query
|
||||
@@ -708,11 +740,103 @@ char *komodo_issuemethod(char *userpass,char *method,char *params,uint16_t port)
|
||||
|
||||
#include "rogue.h"
|
||||
|
||||
void rogue_progress(struct rogue_state *rs,uint64_t seed,char *keystrokes,int32_t num)
|
||||
int32_t rogue_sendrawtransaction(char *rawtx)
|
||||
{
|
||||
char cmd[16384],hexstr[16384],params[32768],*retstr; int32_t i;
|
||||
char *params,*retstr,*hexstr; cJSON *retjson,*resobj; int32_t retval = -1;
|
||||
params = (char *)malloc(strlen(rawtx) + 16);
|
||||
sprintf(params,"[\"%s\"]",rawtx);
|
||||
if ( (retstr= komodo_issuemethod(USERPASS,"sendrawtransaction",params,ROGUE_PORT)) != 0 )
|
||||
{
|
||||
if ( 0 ) // causes 4th level crash
|
||||
{
|
||||
static FILE *fp;
|
||||
if ( fp == 0 )
|
||||
fp = fopen("rogue.sendlog","wb");
|
||||
if ( fp != 0 )
|
||||
{
|
||||
fprintf(fp,"%s\n",retstr);
|
||||
fflush(fp);
|
||||
}
|
||||
}
|
||||
if ( (retjson= cJSON_Parse(retstr)) != 0 )
|
||||
{
|
||||
if ( (resobj= jobj(retjson,"result")) != 0 )
|
||||
{
|
||||
if ( (hexstr= jstr(resobj,0)) != 0 && is_hexstr(hexstr,64) == 64 )
|
||||
retval = 0;
|
||||
}
|
||||
free_json(retjson);
|
||||
}
|
||||
|
||||
/* log sendrawtx result in file */
|
||||
|
||||
/*
|
||||
FILE *debug_file;
|
||||
debug_file = fopen("tx_debug.log", "a");
|
||||
fprintf(debug_file, "%s\n", retstr);
|
||||
fflush(debug_file);
|
||||
fclose(debug_file);
|
||||
*/
|
||||
|
||||
free(retstr);
|
||||
}
|
||||
free(params);
|
||||
return(retval);
|
||||
}
|
||||
|
||||
void rogue_progress(struct rogue_state *rs,int32_t waitflag,uint64_t seed,char *keystrokes,int32_t num)
|
||||
{
|
||||
char cmd[16384],hexstr[16384],params[32768],*retstr,*rawtx,*pastkeys,*pastcmp,*keys; int32_t i,len,numpastkeys; cJSON *retjson,*resobj;
|
||||
//fprintf(stderr,"rogue_progress num.%d\n",num);
|
||||
if ( rs->guiflag != 0 && Gametxidstr[0] != 0 )
|
||||
{
|
||||
if ( rs->keystrokeshex != 0 )
|
||||
{
|
||||
if ( rogue_sendrawtransaction(rs->keystrokeshex) == 0 )
|
||||
{
|
||||
if ( waitflag == 0 )
|
||||
return;
|
||||
else if ( 0 )
|
||||
{
|
||||
while ( rogue_sendrawtransaction(rs->keystrokeshex) == 0 )
|
||||
{
|
||||
//fprintf(stderr,"pre-rebroadcast\n");
|
||||
sleep(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
free(rs->keystrokeshex), rs->keystrokeshex = 0;
|
||||
}
|
||||
if ( 0 && (pastkeys= rogue_keystrokesload(&numpastkeys,seed,1)) != 0 )
|
||||
{
|
||||
sprintf(params,"[\"extract\",\"17\",\"[%%22%s%%22]\"]",Gametxidstr);
|
||||
if ( (retstr= komodo_issuemethod(USERPASS,"cclib",params,ROGUE_PORT)) != 0 )
|
||||
{
|
||||
if ( (retjson= cJSON_Parse(retstr)) != 0 )
|
||||
{
|
||||
if ( (resobj= jobj(retjson,"result")) != 0 && (keys= jstr(resobj,"keystrokes")) != 0 )
|
||||
{
|
||||
len = strlen(keys) / 2;
|
||||
pastcmp = (char *)malloc(len + 1);
|
||||
decode_hex(pastcmp,len,keys);
|
||||
fprintf(stderr,"keystrokes.(%s) vs pastkeys\n",keys);
|
||||
for (i=0; i<numpastkeys; i++)
|
||||
fprintf(stderr,"%02x",pastkeys[i]);
|
||||
fprintf(stderr,"\n");
|
||||
if ( len != numpastkeys || memcmp(pastcmp,pastkeys,len) != 0 )
|
||||
{
|
||||
fprintf(stderr,"pastcmp[%d] != pastkeys[%d]?\n",len,numpastkeys);
|
||||
}
|
||||
free(pastcmp);
|
||||
} else fprintf(stderr,"no keystrokes in (%s)\n",retstr);
|
||||
free_json(retjson);
|
||||
} else fprintf(stderr,"error parsing.(%s)\n",retstr);
|
||||
fprintf(stderr,"extracted.(%s)\n",retstr);
|
||||
free(retstr);
|
||||
} else fprintf(stderr,"error extracting game\n");
|
||||
free(pastkeys);
|
||||
} // else fprintf(stderr,"no pastkeys\n");
|
||||
|
||||
for (i=0; i<num; i++)
|
||||
sprintf(&hexstr[i<<1],"%02x",keystrokes[i]&0xff);
|
||||
hexstr[i<<1] = 0;
|
||||
@@ -736,9 +860,29 @@ void rogue_progress(struct rogue_state *rs,uint64_t seed,char *keystrokes,int32_
|
||||
fprintf(fp,"%s\n",retstr);
|
||||
fflush(fp);
|
||||
}
|
||||
if ( (retjson= cJSON_Parse(retstr)) != 0 )
|
||||
{
|
||||
if ( (resobj= jobj(retjson,"result")) != 0 && (rawtx= jstr(resobj,"hex")) != 0 )
|
||||
{
|
||||
if ( rs->keystrokeshex != 0 )
|
||||
free(rs->keystrokeshex);
|
||||
rs->keystrokeshex = (char *)malloc(strlen(rawtx)+1);
|
||||
strcpy(rs->keystrokeshex,rawtx);
|
||||
//fprintf(stderr,"set keystrokestx <- %s\n",rs->keystrokeshex);
|
||||
}
|
||||
free_json(retjson);
|
||||
}
|
||||
free(retstr);
|
||||
}
|
||||
sleep(1);
|
||||
if ( 0 && waitflag != 0 && rs->keystrokeshex != 0 )
|
||||
{
|
||||
while ( rogue_sendrawtransaction(rs->keystrokeshex) == 0 )
|
||||
{
|
||||
//fprintf(stderr,"post-rebroadcast\n");
|
||||
sleep(3);
|
||||
}
|
||||
free(rs->keystrokeshex), rs->keystrokeshex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -797,9 +941,46 @@ int32_t rogue_setplayerdata(struct rogue_state *rs,char *gametxidstr)
|
||||
return(retval);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef _MSC_VER
|
||||
__inline int msver(void) {
|
||||
switch (_MSC_VER) {
|
||||
case 1500: return 2008;
|
||||
case 1600: return 2010;
|
||||
case 1700: return 2012;
|
||||
case 1800: return 2013;
|
||||
case 1900: return 2015;
|
||||
//case 1910: return 2017;
|
||||
default: return (_MSC_VER / 100);
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool is_x64(void) {
|
||||
#if defined(__x86_64__) || defined(_WIN64) || defined(__aarch64__)
|
||||
return 1;
|
||||
#elif defined(__amd64__) || defined(__amd64) || defined(_M_X64) || defined(_M_IA64)
|
||||
return 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define BUILD_DATE __DATE__ " " __TIME__
|
||||
#endif // _WIN32
|
||||
#endif // _MSC_VER
|
||||
|
||||
int main(int argc, char **argv, char **envp)
|
||||
{
|
||||
uint64_t seed; FILE *fp = 0; int32_t i,j,c; char userpass[8192];
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef _MSC_VER
|
||||
printf("*** rogue for Windows [ Build %s ] ***\n", BUILD_DATE);
|
||||
const char* arch = is_x64() ? "64-bits" : "32-bits";
|
||||
printf(" Built with VC++ %d (%ld) %s\n\n", msver(), _MSC_FULL_VER, arch);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
for (i=j=0; argv[0][i]!=0&&j<sizeof(ASSETCHAINS_SYMBOL); i++)
|
||||
{
|
||||
c = argv[0][i];
|
||||
@@ -811,13 +992,34 @@ int main(int argc, char **argv, char **envp)
|
||||
ASSETCHAINS_SYMBOL[j++] = toupper(c);
|
||||
}
|
||||
ASSETCHAINS_SYMBOL[j++] = 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef _MSC_VER
|
||||
if (strncmp(ASSETCHAINS_SYMBOL, "ROGUE.EXE", sizeof(ASSETCHAINS_SYMBOL)) == 0 || strncmp(ASSETCHAINS_SYMBOL, "ROGUE54.EXE", sizeof(ASSETCHAINS_SYMBOL)) == 0) {
|
||||
strcpy(ASSETCHAINS_SYMBOL, "ROGUE"); // accept ROGUE.conf, instead of ROGUE.EXE.conf or ROGUE54.EXE.conf if build with MSVC
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
ROGUE_PORT = komodo_userpass(userpass,ASSETCHAINS_SYMBOL);
|
||||
if ( IPADDRESS[0] == 0 )
|
||||
strcpy(IPADDRESS,"127.0.0.1");
|
||||
printf("ASSETCHAINS_SYMBOL.(%s) port.%u (%s) IPADDRESS.%s \n",ASSETCHAINS_SYMBOL,ROGUE_PORT,USERPASS,IPADDRESS); sleep(1);
|
||||
if ( argc == 2 && (fp=fopen(argv[1],"rb")) == 0 )
|
||||
{
|
||||
seed = atol(argv[1]);
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef _MSC_VER
|
||||
seed = _strtoui64(argv[1], NULL, 10);
|
||||
fprintf(stderr, "replay seed.str(%s) seed.uint64_t(%I64u)", argv[1], seed);
|
||||
#else
|
||||
fprintf(stderr, "replay seed.str(%s) seed.uint64_t(%llu)", argv[1], (long long)seed);
|
||||
seed = atol(argv[1]); // windows, but not MSVC
|
||||
#endif // _MSC_VER
|
||||
#else
|
||||
seed = atol(argv[1]); // non-windows
|
||||
#endif // _WIN32
|
||||
|
||||
//fprintf(stderr,"replay %llu\n",(long long)seed);
|
||||
return(rogue_replay(seed,10));
|
||||
}
|
||||
|
||||
@@ -404,18 +404,18 @@ add_haste(struct rogue_state *rs,bool potion)
|
||||
{
|
||||
if (on(player, ISHASTE))
|
||||
{
|
||||
no_command += rnd(8);
|
||||
player.t_flags &= ~(ISRUN|ISHASTE);
|
||||
extinguish(nohaste);
|
||||
msg(rs,"you faint from exhaustion");
|
||||
return FALSE;
|
||||
no_command += rnd(8);
|
||||
player.t_flags &= ~(ISRUN|ISHASTE);
|
||||
extinguish(nohaste);
|
||||
msg(rs,"you faint from exhaustion");
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
player.t_flags |= ISHASTE;
|
||||
if (potion)
|
||||
fuse(nohaste, 0, rnd(4)+4, AFTER);
|
||||
return TRUE;
|
||||
player.t_flags |= ISHASTE;
|
||||
if (potion)
|
||||
fuse(nohaste, 0, rnd(4)+4, AFTER);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ wanderer(struct rogue_state *rs)
|
||||
tp = new_item();
|
||||
do
|
||||
{
|
||||
find_floor((struct room *) NULL, &cp, FALSE, TRUE);
|
||||
find_floor(rs,(struct room *) NULL, &cp, FALSE, TRUE);
|
||||
} while (roomin(rs,&cp) == proom);
|
||||
new_monster(rs,tp, randmonster(TRUE), &cp);
|
||||
if (on(player, SEEMONST))
|
||||
|
||||
@@ -26,7 +26,17 @@ new_level(struct rogue_state *rs)
|
||||
PLACE *pp;
|
||||
char *sp;
|
||||
int i;
|
||||
|
||||
if ( 0 )
|
||||
{
|
||||
static FILE *fp;
|
||||
if ( fp == 0 )
|
||||
fp = fopen("debug","wb");
|
||||
if ( fp != 0 )
|
||||
{
|
||||
fprintf(fp,"newlevel seed.%llu\n",(long long)seed);
|
||||
fflush(fp);
|
||||
}
|
||||
}
|
||||
player.t_flags &= ~ISHELD; /* unhold when you go down just in case */
|
||||
if (level > max_level)
|
||||
max_level = level;
|
||||
@@ -74,7 +84,7 @@ new_level(struct rogue_state *rs)
|
||||
*/
|
||||
do
|
||||
{
|
||||
find_floor((struct room *) NULL, &stairs, FALSE, FALSE);
|
||||
find_floor(rs,(struct room *) NULL, &stairs, FALSE, FALSE);
|
||||
} while (chat(stairs.y, stairs.x) != FLOOR);
|
||||
sp = &flat(stairs.y, stairs.x);
|
||||
*sp &= ~F_REAL;
|
||||
@@ -84,18 +94,18 @@ new_level(struct rogue_state *rs)
|
||||
/*
|
||||
* Place the staircase down.
|
||||
*/
|
||||
find_floor((struct room *) NULL, &stairs, FALSE, FALSE);
|
||||
find_floor(rs,(struct room *) NULL, &stairs, FALSE, FALSE);
|
||||
chat(stairs.y, stairs.x) = STAIRS;
|
||||
seenstairs = FALSE;
|
||||
|
||||
for (tp = mlist; tp != NULL; tp = next(tp))
|
||||
tp->t_room = roomin(rs,&tp->t_pos);
|
||||
|
||||
find_floor((struct room *) NULL, &hero, FALSE, TRUE);
|
||||
find_floor(rs,(struct room *) NULL, &hero, FALSE, TRUE);
|
||||
enter_room(rs,&hero);
|
||||
mvaddch(hero.y, hero.x, PLAYER);
|
||||
if (on(player, SEEMONST))
|
||||
turn_see(FALSE);
|
||||
turn_see(rs,FALSE);
|
||||
if (on(player, ISHALU))
|
||||
visuals(rs,0);
|
||||
}
|
||||
@@ -153,7 +163,7 @@ put_things(struct rogue_state *rs)
|
||||
/*
|
||||
* Put it somewhere
|
||||
*/
|
||||
find_floor((struct room *) NULL, &obj->o_pos, FALSE, FALSE);
|
||||
find_floor(rs,(struct room *) NULL, &obj->o_pos, FALSE, FALSE);
|
||||
chat(obj->o_pos.y, obj->o_pos.x) = (char) obj->o_type;
|
||||
}
|
||||
/*
|
||||
@@ -173,7 +183,7 @@ put_things(struct rogue_state *rs)
|
||||
/*
|
||||
* Put it somewhere
|
||||
*/
|
||||
find_floor((struct room *) NULL, &obj->o_pos, FALSE, FALSE);
|
||||
find_floor(rs,(struct room *) NULL, &obj->o_pos, FALSE, FALSE);
|
||||
chat(obj->o_pos.y, obj->o_pos.x) = AMULET;
|
||||
}
|
||||
}
|
||||
@@ -201,7 +211,7 @@ treas_room(struct rogue_state *rs)
|
||||
num_monst = nm = rnd(spots) + MINTREAS;
|
||||
while (nm--)
|
||||
{
|
||||
find_floor(rp, &mp, 2 * MAXTRIES, FALSE);
|
||||
find_floor(rs,rp, &mp, 2 * MAXTRIES, FALSE);
|
||||
//fprintf(stderr,"treas_room\n");
|
||||
tp = new_thing(rs);
|
||||
tp->o_pos = mp;
|
||||
@@ -222,7 +232,7 @@ treas_room(struct rogue_state *rs)
|
||||
while (nm--)
|
||||
{
|
||||
spots = 0;
|
||||
if (find_floor(rp, &mp, MAXTRIES, TRUE))
|
||||
if (find_floor(rs,rp, &mp, MAXTRIES, TRUE))
|
||||
{
|
||||
tp = new_item();
|
||||
new_monster(rs,tp, randmonster(FALSE), &mp);
|
||||
|
||||
@@ -163,6 +163,11 @@ int32_t num_packitems(struct rogue_state *rs)
|
||||
int32_t type = 0,n = 0,total = 0;
|
||||
for (; list != NULL; list = next(list))
|
||||
{
|
||||
if ( thing_find(list) < 0 )
|
||||
{
|
||||
fprintf(stderr,"num_packitems cant find %p\n",list);
|
||||
return(-1);
|
||||
}
|
||||
if ( list->o_packch != 0 )
|
||||
{
|
||||
n++;
|
||||
@@ -219,29 +224,29 @@ THING *
|
||||
leave_pack(struct rogue_state *rs,THING *obj, bool newobj, bool all)
|
||||
{
|
||||
THING *nobj;
|
||||
|
||||
|
||||
inpack--;
|
||||
nobj = obj;
|
||||
if (obj->o_count > 1 && !all)
|
||||
{
|
||||
last_pick = obj;
|
||||
obj->o_count--;
|
||||
if (obj->o_group)
|
||||
inpack++;
|
||||
if (newobj)
|
||||
{
|
||||
nobj = new_item();
|
||||
*nobj = *obj;
|
||||
next(nobj) = NULL;
|
||||
prev(nobj) = NULL;
|
||||
nobj->o_count = 1;
|
||||
}
|
||||
last_pick = obj;
|
||||
obj->o_count--;
|
||||
if (obj->o_group)
|
||||
inpack++;
|
||||
if (newobj)
|
||||
{
|
||||
nobj = new_item();
|
||||
*nobj = *obj;
|
||||
next(nobj) = NULL;
|
||||
prev(nobj) = NULL;
|
||||
nobj->o_count = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
last_pick = NULL;
|
||||
pack_used[obj->o_packch - 'a'] = FALSE;
|
||||
detach(pack, obj);
|
||||
last_pick = NULL;
|
||||
pack_used[obj->o_packch - 'a'] = FALSE;
|
||||
detach(pack, obj);
|
||||
}
|
||||
return nobj;
|
||||
}
|
||||
@@ -422,6 +427,8 @@ get_item(struct rogue_state *rs,char *purpose, int type)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if ( rs->replaydone != 0 )
|
||||
return(NULL);
|
||||
if (!terse)
|
||||
addmsg(rs,"which object do you want to ");
|
||||
addmsg(rs,purpose);
|
||||
@@ -464,7 +471,9 @@ get_item(struct rogue_state *rs,char *purpose, int type)
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
||||
@@ -27,31 +27,31 @@ do_passages(struct rogue_state *rs)
|
||||
int roomcount;
|
||||
static struct rdes
|
||||
{
|
||||
bool conn[MAXROOMS]; /* possible to connect to room i? */
|
||||
bool isconn[MAXROOMS]; /* connection been made to room i? */
|
||||
bool ingraph; /* this room in graph already? */
|
||||
bool conn[MAXROOMS]; /* possible to connect to room i? */
|
||||
bool isconn[MAXROOMS]; /* connection been made to room i? */
|
||||
bool ingraph; /* this room in graph already? */
|
||||
} rdes[MAXROOMS] = {
|
||||
{ { 0, 1, 0, 1, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||
{ { 1, 0, 1, 0, 1, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||
{ { 0, 1, 0, 0, 0, 1, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||
{ { 1, 0, 0, 0, 1, 0, 1, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||
{ { 0, 1, 0, 1, 0, 1, 0, 1, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||
{ { 0, 0, 1, 0, 1, 0, 0, 0, 1 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||
{ { 0, 0, 0, 1, 0, 0, 0, 1, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||
{ { 0, 0, 0, 0, 1, 0, 1, 0, 1 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||
{ { 0, 0, 0, 0, 0, 1, 0, 1, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||
{ { 0, 1, 0, 1, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||
{ { 1, 0, 1, 0, 1, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||
{ { 0, 1, 0, 0, 0, 1, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||
{ { 1, 0, 0, 0, 1, 0, 1, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||
{ { 0, 1, 0, 1, 0, 1, 0, 1, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||
{ { 0, 0, 1, 0, 1, 0, 0, 0, 1 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||
{ { 0, 0, 0, 1, 0, 0, 0, 1, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||
{ { 0, 0, 0, 0, 1, 0, 1, 0, 1 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||
{ { 0, 0, 0, 0, 0, 1, 0, 1, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* reinitialize room graph description
|
||||
*/
|
||||
for (r1 = rdes; r1 <= &rdes[MAXROOMS-1]; r1++)
|
||||
{
|
||||
for (j = 0; j < MAXROOMS; j++)
|
||||
r1->isconn[j] = FALSE;
|
||||
r1->ingraph = FALSE;
|
||||
for (j = 0; j < MAXROOMS; j++)
|
||||
r1->isconn[j] = FALSE;
|
||||
r1->ingraph = FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* starting with one room, connect it to a random adjacent room and
|
||||
* then pick a new room to start with.
|
||||
@@ -61,65 +61,65 @@ do_passages(struct rogue_state *rs)
|
||||
r1->ingraph = TRUE;
|
||||
do
|
||||
{
|
||||
/*
|
||||
* find a room to connect with
|
||||
*/
|
||||
j = 0;
|
||||
for (i = 0; i < MAXROOMS; i++)
|
||||
if (r1->conn[i] && !rdes[i].ingraph && rnd(++j) == 0)
|
||||
r2 = &rdes[i];
|
||||
/*
|
||||
* if no adjacent rooms are outside the graph, pick a new room
|
||||
* to look from
|
||||
*/
|
||||
if (j == 0)
|
||||
{
|
||||
do
|
||||
r1 = &rdes[rnd(MAXROOMS)];
|
||||
until (r1->ingraph);
|
||||
}
|
||||
/*
|
||||
* otherwise, connect new room to the graph, and draw a tunnel
|
||||
* to it
|
||||
*/
|
||||
else
|
||||
{
|
||||
r2->ingraph = TRUE;
|
||||
i = (int)(r1 - rdes);
|
||||
j = (int)(r2 - rdes);
|
||||
conn(rs,i, j);
|
||||
r1->isconn[j] = TRUE;
|
||||
r2->isconn[i] = TRUE;
|
||||
roomcount++;
|
||||
}
|
||||
/*
|
||||
* find a room to connect with
|
||||
*/
|
||||
j = 0;
|
||||
for (i = 0; i < MAXROOMS; i++)
|
||||
if (r1->conn[i] && !rdes[i].ingraph && rnd(++j) == 0)
|
||||
r2 = &rdes[i];
|
||||
/*
|
||||
* if no adjacent rooms are outside the graph, pick a new room
|
||||
* to look from
|
||||
*/
|
||||
if (j == 0)
|
||||
{
|
||||
do
|
||||
r1 = &rdes[rnd(MAXROOMS)];
|
||||
until (r1->ingraph);
|
||||
}
|
||||
/*
|
||||
* otherwise, connect new room to the graph, and draw a tunnel
|
||||
* to it
|
||||
*/
|
||||
else
|
||||
{
|
||||
r2->ingraph = TRUE;
|
||||
i = (int)(r1 - rdes);
|
||||
j = (int)(r2 - rdes);
|
||||
conn(rs,i, j);
|
||||
r1->isconn[j] = TRUE;
|
||||
r2->isconn[i] = TRUE;
|
||||
roomcount++;
|
||||
}
|
||||
} while (roomcount < MAXROOMS);
|
||||
|
||||
|
||||
/*
|
||||
* attempt to add passages to the graph a random number of times so
|
||||
* that there isn't always just one unique passage through it.
|
||||
*/
|
||||
for (roomcount = rnd(5); roomcount > 0; roomcount--)
|
||||
{
|
||||
r1 = &rdes[rnd(MAXROOMS)]; /* a random room to look from */
|
||||
/*
|
||||
* find an adjacent room not already connected
|
||||
*/
|
||||
j = 0;
|
||||
for (i = 0; i < MAXROOMS; i++)
|
||||
if (r1->conn[i] && !r1->isconn[i] && rnd(++j) == 0)
|
||||
r2 = &rdes[i];
|
||||
/*
|
||||
* if there is one, connect it and look for the next added
|
||||
* passage
|
||||
*/
|
||||
if (j != 0)
|
||||
{
|
||||
i = (int)(r1 - rdes);
|
||||
j = (int)(r2 - rdes);
|
||||
conn(rs,i, j);
|
||||
r1->isconn[j] = TRUE;
|
||||
r2->isconn[i] = TRUE;
|
||||
}
|
||||
r1 = &rdes[rnd(MAXROOMS)]; /* a random room to look from */
|
||||
/*
|
||||
* find an adjacent room not already connected
|
||||
*/
|
||||
j = 0;
|
||||
for (i = 0; i < MAXROOMS; i++)
|
||||
if (r1->conn[i] && !r1->isconn[i] && rnd(++j) == 0)
|
||||
r2 = &rdes[i];
|
||||
/*
|
||||
* if there is one, connect it and look for the next added
|
||||
* passage
|
||||
*/
|
||||
if (j != 0)
|
||||
{
|
||||
i = (int)(r1 - rdes);
|
||||
j = (int)(r2 - rdes);
|
||||
conn(rs,i, j);
|
||||
r1->isconn[j] = TRUE;
|
||||
r2->isconn[i] = TRUE;
|
||||
}
|
||||
}
|
||||
passnum();
|
||||
}
|
||||
@@ -138,22 +138,22 @@ conn(struct rogue_state *rs,int r1, int r2)
|
||||
int rm;
|
||||
char direc;
|
||||
static coord del, curr, turn_delta, spos, epos;
|
||||
|
||||
|
||||
if (r1 < r2)
|
||||
{
|
||||
rm = r1;
|
||||
if (r1 + 1 == r2)
|
||||
direc = 'r';
|
||||
else
|
||||
direc = 'd';
|
||||
rm = r1;
|
||||
if (r1 + 1 == r2)
|
||||
direc = 'r';
|
||||
else
|
||||
direc = 'd';
|
||||
}
|
||||
else
|
||||
{
|
||||
rm = r2;
|
||||
if (r2 + 1 == r1)
|
||||
direc = 'r';
|
||||
else
|
||||
direc = 'd';
|
||||
rm = r2;
|
||||
if (r2 + 1 == r1)
|
||||
direc = 'r';
|
||||
else
|
||||
direc = 'd';
|
||||
}
|
||||
rpf = &rooms[rm];
|
||||
/*
|
||||
@@ -162,75 +162,75 @@ conn(struct rogue_state *rs,int r1, int r2)
|
||||
*/
|
||||
if (direc == 'd')
|
||||
{
|
||||
rmt = rm + 3; /* room # of dest */
|
||||
rpt = &rooms[rmt]; /* room pointer of dest */
|
||||
del.x = 0; /* direction of move */
|
||||
del.y = 1;
|
||||
spos.x = rpf->r_pos.x; /* start of move */
|
||||
spos.y = rpf->r_pos.y;
|
||||
epos.x = rpt->r_pos.x; /* end of move */
|
||||
epos.y = rpt->r_pos.y;
|
||||
if (!(rpf->r_flags & ISGONE)) /* if not gone pick door pos */
|
||||
do
|
||||
{
|
||||
spos.x = rpf->r_pos.x + rnd(rpf->r_max.x - 2) + 1;
|
||||
spos.y = rpf->r_pos.y + rpf->r_max.y - 1;
|
||||
} while ((rpf->r_flags&ISMAZE) && !(flat(spos.y, spos.x)&F_PASS));
|
||||
if (!(rpt->r_flags & ISGONE))
|
||||
do
|
||||
{
|
||||
epos.x = rpt->r_pos.x + rnd(rpt->r_max.x - 2) + 1;
|
||||
} while ((rpt->r_flags&ISMAZE) && !(flat(epos.y, epos.x)&F_PASS));
|
||||
distance = abs(spos.y - epos.y) - 1; /* distance to move */
|
||||
turn_delta.y = 0; /* direction to turn */
|
||||
turn_delta.x = (spos.x < epos.x ? 1 : -1);
|
||||
turn_distance = abs(spos.x - epos.x); /* how far to turn */
|
||||
rmt = rm + 3; /* room # of dest */
|
||||
rpt = &rooms[rmt]; /* room pointer of dest */
|
||||
del.x = 0; /* direction of move */
|
||||
del.y = 1;
|
||||
spos.x = rpf->r_pos.x; /* start of move */
|
||||
spos.y = rpf->r_pos.y;
|
||||
epos.x = rpt->r_pos.x; /* end of move */
|
||||
epos.y = rpt->r_pos.y;
|
||||
if (!(rpf->r_flags & ISGONE)) /* if not gone pick door pos */
|
||||
do
|
||||
{
|
||||
spos.x = rpf->r_pos.x + rnd(rpf->r_max.x - 2) + 1;
|
||||
spos.y = rpf->r_pos.y + rpf->r_max.y - 1;
|
||||
} while ((rpf->r_flags&ISMAZE) && !(flat(spos.y, spos.x)&F_PASS));
|
||||
if (!(rpt->r_flags & ISGONE))
|
||||
do
|
||||
{
|
||||
epos.x = rpt->r_pos.x + rnd(rpt->r_max.x - 2) + 1;
|
||||
} while ((rpt->r_flags&ISMAZE) && !(flat(epos.y, epos.x)&F_PASS));
|
||||
distance = abs(spos.y - epos.y) - 1; /* distance to move */
|
||||
turn_delta.y = 0; /* direction to turn */
|
||||
turn_delta.x = (spos.x < epos.x ? 1 : -1);
|
||||
turn_distance = abs(spos.x - epos.x); /* how far to turn */
|
||||
}
|
||||
else if (direc == 'r') /* setup for moving right */
|
||||
{
|
||||
rmt = rm + 1;
|
||||
rpt = &rooms[rmt];
|
||||
del.x = 1;
|
||||
del.y = 0;
|
||||
spos.x = rpf->r_pos.x;
|
||||
spos.y = rpf->r_pos.y;
|
||||
epos.x = rpt->r_pos.x;
|
||||
epos.y = rpt->r_pos.y;
|
||||
if (!(rpf->r_flags & ISGONE))
|
||||
do
|
||||
{
|
||||
spos.x = rpf->r_pos.x + rpf->r_max.x - 1;
|
||||
spos.y = rpf->r_pos.y + rnd(rpf->r_max.y - 2) + 1;
|
||||
} while ((rpf->r_flags&ISMAZE) && !(flat(spos.y, spos.x)&F_PASS));
|
||||
if (!(rpt->r_flags & ISGONE))
|
||||
do
|
||||
{
|
||||
epos.y = rpt->r_pos.y + rnd(rpt->r_max.y - 2) + 1;
|
||||
} while ((rpt->r_flags&ISMAZE) && !(flat(epos.y, epos.x)&F_PASS));
|
||||
distance = abs(spos.x - epos.x) - 1;
|
||||
turn_delta.y = (spos.y < epos.y ? 1 : -1);
|
||||
turn_delta.x = 0;
|
||||
turn_distance = abs(spos.y - epos.y);
|
||||
rmt = rm + 1;
|
||||
rpt = &rooms[rmt];
|
||||
del.x = 1;
|
||||
del.y = 0;
|
||||
spos.x = rpf->r_pos.x;
|
||||
spos.y = rpf->r_pos.y;
|
||||
epos.x = rpt->r_pos.x;
|
||||
epos.y = rpt->r_pos.y;
|
||||
if (!(rpf->r_flags & ISGONE))
|
||||
do
|
||||
{
|
||||
spos.x = rpf->r_pos.x + rpf->r_max.x - 1;
|
||||
spos.y = rpf->r_pos.y + rnd(rpf->r_max.y - 2) + 1;
|
||||
} while ((rpf->r_flags&ISMAZE) && !(flat(spos.y, spos.x)&F_PASS));
|
||||
if (!(rpt->r_flags & ISGONE))
|
||||
do
|
||||
{
|
||||
epos.y = rpt->r_pos.y + rnd(rpt->r_max.y - 2) + 1;
|
||||
} while ((rpt->r_flags&ISMAZE) && !(flat(epos.y, epos.x)&F_PASS));
|
||||
distance = abs(spos.x - epos.x) - 1;
|
||||
turn_delta.y = (spos.y < epos.y ? 1 : -1);
|
||||
turn_delta.x = 0;
|
||||
turn_distance = abs(spos.y - epos.y);
|
||||
}
|
||||
#ifdef MASTER
|
||||
else
|
||||
debug("error in connection tables");
|
||||
debug("error in connection tables");
|
||||
#endif
|
||||
|
||||
|
||||
turn_spot = rnd(distance - 1) + 1; /* where turn starts */
|
||||
|
||||
|
||||
/*
|
||||
* Draw in the doors on either side of the passage or just put #'s
|
||||
* if the rooms are gone.
|
||||
*/
|
||||
if (!(rpf->r_flags & ISGONE))
|
||||
door(rpf, &spos);
|
||||
door(rpf, &spos);
|
||||
else
|
||||
putpass(&spos);
|
||||
putpass(&spos);
|
||||
if (!(rpt->r_flags & ISGONE))
|
||||
door(rpt, &epos);
|
||||
door(rpt, &epos);
|
||||
else
|
||||
putpass(&epos);
|
||||
putpass(&epos);
|
||||
/*
|
||||
* Get ready to move...
|
||||
*/
|
||||
@@ -238,31 +238,31 @@ conn(struct rogue_state *rs,int r1, int r2)
|
||||
curr.y = spos.y;
|
||||
while (distance > 0)
|
||||
{
|
||||
/*
|
||||
* Move to new position
|
||||
*/
|
||||
curr.x += del.x;
|
||||
curr.y += del.y;
|
||||
/*
|
||||
* Check if we are at the turn place, if so do the turn
|
||||
*/
|
||||
if (distance == turn_spot)
|
||||
while (turn_distance--)
|
||||
{
|
||||
putpass(&curr);
|
||||
curr.x += turn_delta.x;
|
||||
curr.y += turn_delta.y;
|
||||
}
|
||||
/*
|
||||
* Continue digging along
|
||||
*/
|
||||
putpass(&curr);
|
||||
distance--;
|
||||
/*
|
||||
* Move to new position
|
||||
*/
|
||||
curr.x += del.x;
|
||||
curr.y += del.y;
|
||||
/*
|
||||
* Check if we are at the turn place, if so do the turn
|
||||
*/
|
||||
if (distance == turn_spot)
|
||||
while (turn_distance--)
|
||||
{
|
||||
putpass(&curr);
|
||||
curr.x += turn_delta.x;
|
||||
curr.y += turn_delta.y;
|
||||
}
|
||||
/*
|
||||
* Continue digging along
|
||||
*/
|
||||
putpass(&curr);
|
||||
distance--;
|
||||
}
|
||||
curr.x += del.x;
|
||||
curr.y += del.y;
|
||||
if (!ce(curr, epos))
|
||||
msg(rs,"warning, connectivity problem on this level");
|
||||
msg(rs,"warning, connectivity problem on this level");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -274,13 +274,13 @@ void
|
||||
putpass(coord *cp)
|
||||
{
|
||||
PLACE *pp;
|
||||
|
||||
|
||||
pp = INDEX(cp->y, cp->x);
|
||||
pp->p_flags |= F_PASS;
|
||||
if (rnd(10) + 1 < level && rnd(40) == 0)
|
||||
pp->p_flags &= ~F_REAL;
|
||||
pp->p_flags &= ~F_REAL;
|
||||
else
|
||||
pp->p_ch = PASSAGE;
|
||||
pp->p_ch = PASSAGE;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -293,23 +293,23 @@ void
|
||||
door(struct room *rm, coord *cp)
|
||||
{
|
||||
PLACE *pp;
|
||||
|
||||
|
||||
rm->r_exit[rm->r_nexits++] = *cp;
|
||||
|
||||
|
||||
if (rm->r_flags & ISMAZE)
|
||||
return;
|
||||
|
||||
return;
|
||||
|
||||
pp = INDEX(cp->y, cp->x);
|
||||
if (rnd(10) + 1 < level && rnd(5) == 0)
|
||||
{
|
||||
if (cp->y == rm->r_pos.y || cp->y == rm->r_pos.y + rm->r_max.y - 1)
|
||||
pp->p_ch = '-';
|
||||
else
|
||||
pp->p_ch = '|';
|
||||
pp->p_flags &= ~F_REAL;
|
||||
if (cp->y == rm->r_pos.y || cp->y == rm->r_pos.y + rm->r_max.y - 1)
|
||||
pp->p_ch = '-';
|
||||
else
|
||||
pp->p_ch = '|';
|
||||
pp->p_flags &= ~F_REAL;
|
||||
}
|
||||
else
|
||||
pp->p_ch = DOOR;
|
||||
pp->p_ch = DOOR;
|
||||
}
|
||||
|
||||
#ifdef MASTER
|
||||
@@ -324,31 +324,31 @@ add_pass()
|
||||
PLACE *pp;
|
||||
int y, x;
|
||||
char ch;
|
||||
|
||||
|
||||
for (y = 1; y < NUMLINES - 1; y++)
|
||||
for (x = 0; x < NUMCOLS; x++)
|
||||
{
|
||||
pp = INDEX(y, x);
|
||||
if ((pp->p_flags & F_PASS) || pp->p_ch == DOOR ||
|
||||
(!(pp->p_flags&F_REAL) && (pp->p_ch == '|' || pp->p_ch == '-')))
|
||||
{
|
||||
ch = pp->p_ch;
|
||||
if (pp->p_flags & F_PASS)
|
||||
ch = PASSAGE;
|
||||
pp->p_flags |= F_SEEN;
|
||||
move(y, x);
|
||||
if (pp->p_monst != NULL)
|
||||
pp->p_monst->t_oldch = pp->p_ch;
|
||||
else if (pp->p_flags & F_REAL)
|
||||
addch(ch);
|
||||
else
|
||||
{
|
||||
standout();
|
||||
addch((pp->p_flags & F_PASS) ? PASSAGE : DOOR);
|
||||
standend();
|
||||
}
|
||||
}
|
||||
}
|
||||
for (x = 0; x < NUMCOLS; x++)
|
||||
{
|
||||
pp = INDEX(y, x);
|
||||
if ((pp->p_flags & F_PASS) || pp->p_ch == DOOR ||
|
||||
(!(pp->p_flags&F_REAL) && (pp->p_ch == '|' || pp->p_ch == '-')))
|
||||
{
|
||||
ch = pp->p_ch;
|
||||
if (pp->p_flags & F_PASS)
|
||||
ch = PASSAGE;
|
||||
pp->p_flags |= F_SEEN;
|
||||
move(y, x);
|
||||
if (pp->p_monst != NULL)
|
||||
pp->p_monst->t_oldch = pp->p_ch;
|
||||
else if (pp->p_flags & F_REAL)
|
||||
addch(ch);
|
||||
else
|
||||
{
|
||||
standout();
|
||||
addch((pp->p_flags & F_PASS) ? PASSAGE : DOOR);
|
||||
standend();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -365,17 +365,17 @@ passnum()
|
||||
{
|
||||
struct room *rp;
|
||||
int i;
|
||||
|
||||
|
||||
pnum = 0;
|
||||
newpnum = FALSE;
|
||||
for (rp = passages; rp < &passages[MAXPASS]; rp++)
|
||||
rp->r_nexits = 0;
|
||||
rp->r_nexits = 0;
|
||||
for (rp = rooms; rp < &rooms[MAXROOMS]; rp++)
|
||||
for (i = 0; i < rp->r_nexits; i++)
|
||||
{
|
||||
newpnum ^= 1;//newpnum++;
|
||||
numpass(rp->r_exit[i].y, rp->r_exit[i].x);
|
||||
}
|
||||
for (i = 0; i < rp->r_nexits; i++)
|
||||
{
|
||||
newpnum ^= 1;//newpnum++;
|
||||
numpass(rp->r_exit[i].y, rp->r_exit[i].x);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -389,30 +389,30 @@ numpass(int y, int x)
|
||||
char *fp;
|
||||
struct room *rp;
|
||||
char ch;
|
||||
|
||||
|
||||
if (x >= NUMCOLS || x < 0 || y >= NUMLINES || y <= 0)
|
||||
return;
|
||||
return;
|
||||
fp = &flat(y, x);
|
||||
if (*fp & F_PNUM)
|
||||
return;
|
||||
return;
|
||||
if (newpnum)
|
||||
{
|
||||
pnum++;
|
||||
newpnum = FALSE;
|
||||
pnum++;
|
||||
newpnum = FALSE;
|
||||
}
|
||||
/*
|
||||
* check to see if it is a door or secret door, i.e., a new exit,
|
||||
* or a numerable type of place
|
||||
*/
|
||||
if ((ch = chat(y, x)) == DOOR ||
|
||||
(!(*fp & F_REAL) && (ch == '|' || ch == '-')))
|
||||
(!(*fp & F_REAL) && (ch == '|' || ch == '-')))
|
||||
{
|
||||
rp = &passages[pnum];
|
||||
rp->r_exit[rp->r_nexits].y = y;
|
||||
rp->r_exit[rp->r_nexits++].x = x;
|
||||
rp = &passages[pnum];
|
||||
rp->r_exit[rp->r_nexits].y = y;
|
||||
rp->r_exit[rp->r_nexits++].x = x;
|
||||
}
|
||||
else if (!(*fp & F_PASS))
|
||||
return;
|
||||
return;
|
||||
*fp |= pnum;
|
||||
/*
|
||||
* recurse on the surrounding places
|
||||
|
||||
@@ -78,7 +78,6 @@ quaff(struct rogue_state *rs)
|
||||
}
|
||||
if (obj == cur_weapon)
|
||||
cur_weapon = NULL;
|
||||
|
||||
/*
|
||||
* Calculate the effect it has on the poor guy.
|
||||
*/
|
||||
@@ -91,7 +90,7 @@ quaff(struct rogue_state *rs)
|
||||
do_pot(rs,P_CONFUSE, !trip);
|
||||
when P_POISON:
|
||||
pot_info[P_POISON].oi_know = TRUE;
|
||||
if (ISWEARING(R_SUSTSTR))
|
||||
if (ISWEARING(R_SUSTSTR))
|
||||
msg(rs,"you feel momentarily sick");
|
||||
else
|
||||
{
|
||||
@@ -112,7 +111,7 @@ quaff(struct rogue_state *rs)
|
||||
when P_MFIND:
|
||||
player.t_flags |= SEEMONST;
|
||||
fuse((void(*)(struct rogue_state *rs,int))turn_see, TRUE, HUHDURATION, AFTER);
|
||||
if (!turn_see(FALSE))
|
||||
if (!turn_see(rs,FALSE))
|
||||
msg(rs,"you have a %s feeling for a moment, then it passes",
|
||||
choose_str("normal", "strange"));
|
||||
when P_TFIND:
|
||||
@@ -158,7 +157,7 @@ quaff(struct rogue_state *rs)
|
||||
if (!trip)
|
||||
{
|
||||
if (on(player, SEEMONST))
|
||||
turn_see(FALSE);
|
||||
turn_see(rs,FALSE);
|
||||
start_daemon(visuals, 0, BEFORE);
|
||||
seenstairs = seen_stairs();
|
||||
}
|
||||
@@ -220,7 +219,7 @@ quaff(struct rogue_state *rs)
|
||||
call_it(rs,&pot_info[obj->o_which]);
|
||||
|
||||
if (discardit)
|
||||
discard(obj);
|
||||
discard(obj);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -263,47 +262,6 @@ invis_on()
|
||||
mvaddch(mp->t_pos.y, mp->t_pos.x, mp->t_disguise);
|
||||
}
|
||||
|
||||
/*
|
||||
* turn_see:
|
||||
* Put on or off seeing monsters on this level
|
||||
*/
|
||||
bool
|
||||
turn_see(bool turn_off)
|
||||
{
|
||||
THING *mp;
|
||||
bool can_see, add_new;
|
||||
|
||||
add_new = FALSE;
|
||||
for (mp = mlist; mp != NULL; mp = next(mp))
|
||||
{
|
||||
move(mp->t_pos.y, mp->t_pos.x);
|
||||
can_see = see_monst(mp);
|
||||
if (turn_off)
|
||||
{
|
||||
if (!can_see)
|
||||
addch(mp->t_oldch);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!can_see)
|
||||
standout();
|
||||
if (!on(player, ISHALU))
|
||||
addch(mp->t_type);
|
||||
else
|
||||
addch(rnd(26) + 'A');
|
||||
if (!can_see)
|
||||
{
|
||||
standend();
|
||||
add_new ^= 1;//add_new++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (turn_off)
|
||||
player.t_flags &= ~SEEMONST;
|
||||
else
|
||||
player.t_flags |= SEEMONST;
|
||||
return add_new;
|
||||
}
|
||||
|
||||
/*
|
||||
* seen_stairs:
|
||||
@@ -358,18 +316,18 @@ do_pot(struct rogue_state *rs,int type, bool knowit)
|
||||
{
|
||||
PACT *pp;
|
||||
int t;
|
||||
|
||||
|
||||
pp = &p_actions[type];
|
||||
if (!pot_info[type].oi_know)
|
||||
pot_info[type].oi_know = knowit;
|
||||
pot_info[type].oi_know = knowit;
|
||||
t = spread(pp->pa_time);
|
||||
if (!on(player, pp->pa_flags))
|
||||
{
|
||||
player.t_flags |= pp->pa_flags;
|
||||
fuse(pp->pa_daemon, 0, t, AFTER);
|
||||
look(rs,FALSE);
|
||||
player.t_flags |= pp->pa_flags;
|
||||
fuse(pp->pa_daemon, 0, t, AFTER);
|
||||
look(rs,FALSE);
|
||||
}
|
||||
else
|
||||
lengthen(pp->pa_daemon, t);
|
||||
lengthen(pp->pa_daemon, t);
|
||||
msg(rs,choose_str(pp->pa_high, pp->pa_straight));
|
||||
}
|
||||
|
||||
@@ -23,65 +23,65 @@ ring_on(struct rogue_state *rs)
|
||||
{
|
||||
THING *obj;
|
||||
int ring;
|
||||
|
||||
|
||||
obj = get_item(rs,"put on", RING);
|
||||
/*
|
||||
* Make certain that it is somethings that we want to wear
|
||||
*/
|
||||
if (obj == NULL)
|
||||
return;
|
||||
return;
|
||||
if (obj->o_type != RING)
|
||||
{
|
||||
if (!terse)
|
||||
msg(rs,"it would be difficult to wrap that around a finger");
|
||||
else
|
||||
msg(rs,"not a ring");
|
||||
return;
|
||||
if (!terse)
|
||||
msg(rs,"it would be difficult to wrap that around a finger");
|
||||
else
|
||||
msg(rs,"not a ring");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* find out which hand to put it on
|
||||
*/
|
||||
if (is_current(rs,obj))
|
||||
return;
|
||||
|
||||
return;
|
||||
|
||||
if (cur_ring[LEFT] == NULL && cur_ring[RIGHT] == NULL)
|
||||
{
|
||||
if ((ring = gethand(rs)) < 0)
|
||||
return;
|
||||
if ((ring = gethand(rs)) < 0)
|
||||
return;
|
||||
}
|
||||
else if (cur_ring[LEFT] == NULL)
|
||||
ring = LEFT;
|
||||
ring = LEFT;
|
||||
else if (cur_ring[RIGHT] == NULL)
|
||||
ring = RIGHT;
|
||||
ring = RIGHT;
|
||||
else
|
||||
{
|
||||
if (!terse)
|
||||
msg(rs,"you already have a ring on each hand");
|
||||
else
|
||||
msg(rs,"wearing two");
|
||||
return;
|
||||
if (!terse)
|
||||
msg(rs,"you already have a ring on each hand");
|
||||
else
|
||||
msg(rs,"wearing two");
|
||||
return;
|
||||
}
|
||||
cur_ring[ring] = obj;
|
||||
|
||||
|
||||
/*
|
||||
* Calculate the effect it has on the poor guy.
|
||||
*/
|
||||
switch (obj->o_which)
|
||||
{
|
||||
case R_ADDSTR:
|
||||
chg_str(obj->o_arm);
|
||||
break;
|
||||
case R_SEEINVIS:
|
||||
invis_on();
|
||||
break;
|
||||
case R_AGGR:
|
||||
aggravate(rs);
|
||||
break;
|
||||
case R_ADDSTR:
|
||||
chg_str(obj->o_arm);
|
||||
break;
|
||||
case R_SEEINVIS:
|
||||
invis_on();
|
||||
break;
|
||||
case R_AGGR:
|
||||
aggravate(rs);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (!terse)
|
||||
addmsg(rs,"you are now wearing ");
|
||||
addmsg(rs,"you are now wearing ");
|
||||
msg(rs,"%s (%c)", inv_name(obj, TRUE), obj->o_packch);
|
||||
}
|
||||
|
||||
@@ -95,31 +95,31 @@ ring_off(struct rogue_state *rs)
|
||||
{
|
||||
int ring;
|
||||
THING *obj;
|
||||
|
||||
|
||||
if (cur_ring[LEFT] == NULL && cur_ring[RIGHT] == NULL)
|
||||
{
|
||||
if (terse)
|
||||
msg(rs,"no rings");
|
||||
else
|
||||
msg(rs,"you aren't wearing any rings");
|
||||
return;
|
||||
if (terse)
|
||||
msg(rs,"no rings");
|
||||
else
|
||||
msg(rs,"you aren't wearing any rings");
|
||||
return;
|
||||
}
|
||||
else if (cur_ring[LEFT] == NULL)
|
||||
ring = RIGHT;
|
||||
ring = RIGHT;
|
||||
else if (cur_ring[RIGHT] == NULL)
|
||||
ring = LEFT;
|
||||
ring = LEFT;
|
||||
else
|
||||
if ((ring = gethand(rs)) < 0)
|
||||
return;
|
||||
if ((ring = gethand(rs)) < 0)
|
||||
return;
|
||||
mpos = 0;
|
||||
obj = cur_ring[ring];
|
||||
if (obj == NULL)
|
||||
{
|
||||
msg(rs,"not wearing such a ring");
|
||||
return;
|
||||
msg(rs,"not wearing such a ring");
|
||||
return;
|
||||
}
|
||||
if (dropcheck(rs,obj))
|
||||
msg(rs,"was wearing %s(%c)", inv_name(obj, TRUE), obj->o_packch);
|
||||
msg(rs,"was wearing %s(%c)", inv_name(obj, TRUE), obj->o_packch);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -130,24 +130,26 @@ int
|
||||
gethand(struct rogue_state *rs)
|
||||
{
|
||||
int c;
|
||||
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (terse)
|
||||
msg(rs,"left or right ring? ");
|
||||
else
|
||||
msg(rs,"left hand or right hand? ");
|
||||
if ((c = readchar(rs)) == ESCAPE)
|
||||
return -1;
|
||||
mpos = 0;
|
||||
if (c == 'l' || c == 'L')
|
||||
return LEFT;
|
||||
else if (c == 'r' || c == 'R')
|
||||
return RIGHT;
|
||||
if (terse)
|
||||
msg(rs,"L or R");
|
||||
else
|
||||
msg(rs,"please type L or R");
|
||||
if ( rs->replaydone != 0 )
|
||||
return(-1);
|
||||
if (terse)
|
||||
msg(rs,"left or right ring? ");
|
||||
else
|
||||
msg(rs,"left hand or right hand? ");
|
||||
if ((c = readchar(rs)) == ESCAPE)
|
||||
return -1;
|
||||
mpos = 0;
|
||||
if (c == 'l' || c == 'L')
|
||||
return LEFT;
|
||||
else if (c == 'r' || c == 'R')
|
||||
return RIGHT;
|
||||
if (terse)
|
||||
msg(rs,"L or R");
|
||||
else
|
||||
msg(rs,"please type L or R");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,21 +163,21 @@ ring_eat(int hand)
|
||||
THING *ring;
|
||||
int eat;
|
||||
static int uses[] = {
|
||||
1, /* R_PROTECT */ 1, /* R_ADDSTR */
|
||||
1, /* R_SUSTSTR */ -3, /* R_SEARCH */
|
||||
-5, /* R_SEEINVIS */ 0, /* R_NOP */
|
||||
0, /* R_AGGR */ -3, /* R_ADDHIT */
|
||||
-3, /* R_ADDDAM */ 2, /* R_REGEN */
|
||||
-2, /* R_DIGEST */ 0, /* R_TELEPORT */
|
||||
1, /* R_STEALTH */ 1 /* R_SUSTARM */
|
||||
1, /* R_PROTECT */ 1, /* R_ADDSTR */
|
||||
1, /* R_SUSTSTR */ -3, /* R_SEARCH */
|
||||
-5, /* R_SEEINVIS */ 0, /* R_NOP */
|
||||
0, /* R_AGGR */ -3, /* R_ADDHIT */
|
||||
-3, /* R_ADDDAM */ 2, /* R_REGEN */
|
||||
-2, /* R_DIGEST */ 0, /* R_TELEPORT */
|
||||
1, /* R_STEALTH */ 1 /* R_SUSTARM */
|
||||
};
|
||||
|
||||
|
||||
if ((ring = cur_ring[hand]) == NULL)
|
||||
return 0;
|
||||
return 0;
|
||||
if ((eat = uses[ring->o_which]) < 0)
|
||||
eat = (rnd(-eat) == 0);
|
||||
eat = (rnd(-eat) == 0);
|
||||
if (ring->o_which == R_DIGEST)
|
||||
eat = -eat;
|
||||
eat = -eat;
|
||||
return eat;
|
||||
}
|
||||
|
||||
@@ -187,18 +189,18 @@ char *
|
||||
ring_num(THING *obj)
|
||||
{
|
||||
static char buf[10];
|
||||
|
||||
|
||||
if (!(obj->o_flags & ISKNOW))
|
||||
return "";
|
||||
return "";
|
||||
switch (obj->o_which)
|
||||
{
|
||||
case R_PROTECT:
|
||||
case R_ADDSTR:
|
||||
case R_ADDDAM:
|
||||
case R_ADDHIT:
|
||||
sprintf(buf, " [%s]", num(obj->o_arm, 0, RING));
|
||||
otherwise:
|
||||
return "";
|
||||
case R_PROTECT:
|
||||
case R_ADDSTR:
|
||||
case R_ADDDAM:
|
||||
case R_ADDHIT:
|
||||
sprintf(buf, " [%s]", num(obj->o_arm, 0, RING));
|
||||
otherwise:
|
||||
return "";
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
@@ -238,7 +238,7 @@ death(struct rogue_state *rs,char monst)
|
||||
//struct tm *localtime(const time_t *);
|
||||
if ( rs->guiflag == 0 )
|
||||
{
|
||||
fprintf(stderr,"death during replay by (%c)\n",monst); //sleep(3);
|
||||
//fprintf(stderr,"death during replay by (%c)\n",monst); //sleep(3);
|
||||
rs->replaydone = (uint32_t)time(NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <signal.h>
|
||||
//#include <unistd.h>
|
||||
//#include <curses.h>
|
||||
|
||||
#include "rogue.h"
|
||||
#ifdef STANDALONE
|
||||
#include "../komodo/src/komodo_cJSON.h"
|
||||
@@ -118,20 +119,20 @@ int32_t roguefname(char *fname,uint64_t seed,int32_t counter)
|
||||
return(0);
|
||||
}
|
||||
|
||||
#ifdef test
|
||||
int32_t flushkeystrokes(struct rogue_state *rs)
|
||||
int32_t flushkeystrokes_local(struct rogue_state *rs,int32_t waitflag)
|
||||
{
|
||||
#ifndef BUILD_ROGUE
|
||||
char fname[1024]; FILE *fp; int32_t i,retflag = -1;
|
||||
rs->counter++;
|
||||
roguefname(fname,rs->seed,rs->counter);
|
||||
if ( (fp= fopen(fname,"wb")) != 0 )
|
||||
{
|
||||
if ( fwrite(rs->buffered,1,rs->num,fp) == rs->num )
|
||||
{
|
||||
rs->counter++;
|
||||
rs->num = 0;
|
||||
retflag = 0;
|
||||
fclose(fp);
|
||||
if ( (fp= fopen("savefile","wb")) != 0 )
|
||||
/*if ( (fp= fopen("savefile","wb")) != 0 )
|
||||
{
|
||||
save_file(rs,fp,0);
|
||||
if ( 0 && (fp= fopen("savefile","rb")) != 0 )
|
||||
@@ -140,22 +141,24 @@ int32_t flushkeystrokes(struct rogue_state *rs)
|
||||
fprintf(stderr,"%02x",fgetc(fp));
|
||||
fprintf(stderr," first part rnd.%d\n",rnd(1000));
|
||||
fclose(fp);
|
||||
}
|
||||
roguefname(fname,rs->seed,rs->counter);
|
||||
}*/
|
||||
roguefname(fname,rs->seed,rs->counter+1);
|
||||
if ( (fp= fopen(fname,"wb")) != 0 ) // truncate next file
|
||||
fclose(fp);
|
||||
//fprintf(stderr,"savefile <- %s retflag.%d\n",fname,retflag);
|
||||
}
|
||||
//}
|
||||
} else fprintf(stderr,"error writing (%s)\n",fname);
|
||||
} else fprintf(stderr,"error creating (%s)\n",fname);
|
||||
return(retflag);
|
||||
}
|
||||
#else
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef BUILD_ROGUE
|
||||
// stubs for inside daemon
|
||||
|
||||
void rogue_progress(struct rogue_state *rs,uint64_t seed,char *keystrokes,int32_t num)
|
||||
void rogue_progress(struct rogue_state *rs,int32_t waitflag,uint64_t seed,char *keystrokes,int32_t num)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -165,14 +168,19 @@ int32_t rogue_setplayerdata(struct rogue_state *rs,char *gametxidstr)
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t flushkeystrokes(struct rogue_state *rs)
|
||||
int32_t flushkeystrokes(struct rogue_state *rs,int32_t waitflag)
|
||||
{
|
||||
if ( rs->num > 0 )
|
||||
{
|
||||
rogue_progress(rs,rs->seed,rs->buffered,rs->num);
|
||||
// need to get existing keystrokes including mempool
|
||||
// create keystrokes that are not saved
|
||||
//rs->keytxid = rogue_progress(rs,waitflag,rs->seed,&rs->buffered[rs->lastnum],rs->num - rs->lastnum);
|
||||
//rs->lastnum = rs->num;
|
||||
rogue_progress(rs,waitflag,rs->seed,rs->buffered,rs->num);
|
||||
flushkeystrokes_local(rs,waitflag);
|
||||
memset(rs->buffered,0,sizeof(rs->buffered));
|
||||
rs->counter++;
|
||||
rs->num = 0;
|
||||
//rs->num = 0;
|
||||
//rs->counter++;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
@@ -180,7 +188,7 @@ int32_t flushkeystrokes(struct rogue_state *rs)
|
||||
void rogue_bailout(struct rogue_state *rs)
|
||||
{
|
||||
char cmd[512];
|
||||
flushkeystrokes(rs);
|
||||
flushkeystrokes(rs,1);
|
||||
//sleep(5);
|
||||
return;
|
||||
/*fprintf(stderr,"bailing out\n");
|
||||
@@ -189,6 +197,12 @@ void rogue_bailout(struct rogue_state *rs)
|
||||
fprintf(stderr,"error issuing (%s)\n",cmd);*/
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef _MSC_VER
|
||||
#define sleep(x) Sleep(1000*(x))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int32_t rogue_replay2(uint8_t *newdata,uint64_t seed,char *keystrokes,int32_t num,struct rogue_player *player,int32_t sleepmillis)
|
||||
{
|
||||
struct rogue_state *rs; FILE *fp; int32_t i,n;
|
||||
@@ -208,6 +222,14 @@ int32_t rogue_replay2(uint8_t *newdata,uint64_t seed,char *keystrokes,int32_t nu
|
||||
globalR = *rs;
|
||||
uint32_t starttime = (uint32_t)time(NULL);
|
||||
rogueiterate(rs);
|
||||
|
||||
/*
|
||||
// keypress after replay
|
||||
printf("[Press return to continue]");
|
||||
fflush(stdout);
|
||||
if (fgets(prbuf, 10, stdin) != 0);
|
||||
*/
|
||||
|
||||
if ( 0 )
|
||||
{
|
||||
fprintf(stderr,"elapsed %d seconds\n",(uint32_t)time(NULL) - starttime);
|
||||
@@ -229,7 +251,7 @@ int32_t rogue_replay2(uint8_t *newdata,uint64_t seed,char *keystrokes,int32_t nu
|
||||
if ( (fp= fopen("checkfile","wb")) != 0 )
|
||||
{
|
||||
save_file(rs,fp,0);
|
||||
fprintf(stderr,"gold.%d hp.%d strength.%d/%d level.%d exp.%d dungeon.%d data[%d]\n",rs->P.gold,rs->P.hitpoints,rs->P.strength&0xffff,rs->P.strength>>16,rs->P.level,rs->P.experience,rs->P.dungeonlevel,rs->playersize);
|
||||
//fprintf(stderr,"gold.%d hp.%d strength.%d/%d level.%d exp.%d dungeon.%d data[%d]\n",rs->P.gold,rs->P.hitpoints,rs->P.strength&0xffff,rs->P.strength>>16,rs->P.level,rs->P.experience,rs->P.dungeonlevel,rs->playersize);
|
||||
if ( newdata != 0 && rs->playersize > 0 )
|
||||
memcpy(newdata,rs->playerdata,rs->playersize);
|
||||
}
|
||||
@@ -237,7 +259,6 @@ int32_t rogue_replay2(uint8_t *newdata,uint64_t seed,char *keystrokes,int32_t nu
|
||||
free(rs);
|
||||
return(n);
|
||||
}
|
||||
#endif
|
||||
|
||||
long get_filesize(FILE *fp)
|
||||
{
|
||||
@@ -248,11 +269,10 @@ long get_filesize(FILE *fp)
|
||||
return(fsize);
|
||||
}
|
||||
|
||||
int32_t rogue_replay(uint64_t seed,int32_t sleeptime)
|
||||
char *rogue_keystrokesload(int32_t *numkeysp,uint64_t seed,int32_t counter)
|
||||
{
|
||||
FILE *fp; char fname[1024]; char *keystrokes = 0; long num=0,fsize; int32_t i,counter = 0; struct rogue_state *rs; struct rogue_player P,*player = 0;
|
||||
if ( seed == 0 )
|
||||
seed = 777;
|
||||
char fname[1024],*keystrokes = 0; FILE *fp; long fsize; int32_t num = 0;
|
||||
*numkeysp = 0;
|
||||
while ( 1 )
|
||||
{
|
||||
roguefname(fname,seed,counter);
|
||||
@@ -262,26 +282,37 @@ int32_t rogue_replay(uint64_t seed,int32_t sleeptime)
|
||||
if ( (fsize= get_filesize(fp)) <= 0 )
|
||||
{
|
||||
fclose(fp);
|
||||
printf("fsize.%ld\n",fsize);
|
||||
//printf("fsize.%ld\n",fsize);
|
||||
break;
|
||||
}
|
||||
if ( (keystrokes= (char *)realloc(keystrokes,num+fsize)) == 0 )
|
||||
{
|
||||
fprintf(stderr,"error reallocating keystrokes\n");
|
||||
fclose(fp);
|
||||
return(-1);
|
||||
return(0);
|
||||
}
|
||||
if ( fread(&keystrokes[num],1,fsize,fp) != fsize )
|
||||
{
|
||||
fprintf(stderr,"error reading keystrokes from (%s)\n",fname);
|
||||
fclose(fp);
|
||||
return(-1);
|
||||
free(keystrokes);
|
||||
return(0);
|
||||
}
|
||||
fclose(fp);
|
||||
num += fsize;
|
||||
counter++;
|
||||
fprintf(stderr,"loaded %ld from (%s) total %ld\n",fsize,fname,num);
|
||||
//fprintf(stderr,"loaded %ld from (%s) total %d\n",fsize,fname,num);
|
||||
}
|
||||
*numkeysp = num;
|
||||
return(keystrokes);
|
||||
}
|
||||
|
||||
int32_t rogue_replay(uint64_t seed,int32_t sleeptime)
|
||||
{
|
||||
FILE *fp; char fname[1024]; char *keystrokes = 0; long fsize; int32_t i,num=0,counter = 0; struct rogue_state *rs; struct rogue_player P,*player = 0;
|
||||
if ( seed == 0 )
|
||||
seed = 777;
|
||||
keystrokes = rogue_keystrokesload(&num,seed,counter);
|
||||
if ( num > 0 )
|
||||
{
|
||||
sprintf(fname,"rogue.%llu.player",(long long)seed);
|
||||
@@ -295,7 +326,6 @@ int32_t rogue_replay(uint64_t seed,int32_t sleeptime)
|
||||
fclose(fp);
|
||||
}
|
||||
rogue_replay2(0,seed,keystrokes,num,player,sleeptime);
|
||||
|
||||
mvaddstr(LINES - 2, 0, (char *)"replay completed");
|
||||
endwin();
|
||||
my_exit(0);
|
||||
@@ -313,8 +343,17 @@ int rogue(int argc, char **argv, char **envp)
|
||||
rs->sleeptime = 1; // non-zero to allow refresh()
|
||||
if ( argc == 3 && strlen(argv[2]) == 64 )
|
||||
{
|
||||
rs->seed = atol(argv[1]);
|
||||
#ifdef _WIN32
|
||||
#ifdef _MSC_VER
|
||||
rs->seed = _strtoui64(argv[1], NULL, 10);
|
||||
#else
|
||||
rs->seed = atol(argv[1]); // windows, but not MSVC
|
||||
#endif // _MSC_VER
|
||||
#else
|
||||
rs->seed = atol(argv[1]); // non-windows
|
||||
#endif // _WIN32
|
||||
strcpy(Gametxidstr,argv[2]);
|
||||
fprintf(stderr,"setplayerdata\n");
|
||||
if ( rogue_setplayerdata(rs,Gametxidstr) < 0 )
|
||||
{
|
||||
fprintf(stderr,"invalid gametxid, or already started\n");
|
||||
@@ -410,7 +449,7 @@ int rogue(int argc, char **argv, char **envp)
|
||||
#endif
|
||||
printf("Hello %s, just a moment while I dig the dungeon... seed.%llu", whoami,(long long)rs->seed);
|
||||
fflush(stdout);
|
||||
|
||||
fprintf(stderr,"rogueiterate\n");
|
||||
rogueiterate(rs);
|
||||
return(0);
|
||||
}
|
||||
@@ -510,6 +549,18 @@ tstp(int ignored)
|
||||
#endif*/
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef _MSC_VER
|
||||
void usleep(int32_t micros)
|
||||
{
|
||||
if (micros < 1000)
|
||||
Sleep(1);
|
||||
else Sleep(micros / 1000);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* playit:
|
||||
* The main loop of the program. Loop until the game is over,
|
||||
@@ -560,15 +611,15 @@ playit(struct rogue_state *rs)
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( rs->needflush != 0 && rs->num > 1000 )
|
||||
if ( rs->needflush != 0 )
|
||||
{
|
||||
if ( flushkeystrokes(rs) == 0 )
|
||||
if ( flushkeystrokes(rs,0) == 0 )
|
||||
rs->needflush = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( rs->guiflag != 0 )
|
||||
flushkeystrokes(rs);
|
||||
flushkeystrokes(rs,1);
|
||||
endit(0);
|
||||
}
|
||||
|
||||
@@ -593,13 +644,13 @@ int32_t _quit()
|
||||
if ( rs->sleeptime != 0 )
|
||||
refresh();
|
||||
score(rs,purse, 1, 0);
|
||||
flushkeystrokes(rs);
|
||||
flushkeystrokes(rs,1);
|
||||
my_exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
//score(rs,purse, 1, 0);
|
||||
fprintf(stderr,"done! (%c)\n",c);
|
||||
//fprintf(stderr,"done! (%c)\n",c);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
@@ -362,11 +362,12 @@ typedef union _bits256 bits256;
|
||||
struct rogue_state
|
||||
{
|
||||
uint64_t seed;
|
||||
char *keystrokes;
|
||||
char *keystrokes,*keystrokeshex;
|
||||
uint32_t needflush,replaydone;
|
||||
int32_t numkeys,ind,num,guiflag,counter,sleeptime,playersize,restoring;
|
||||
int32_t numkeys,ind,num,guiflag,counter,sleeptime,playersize,restoring,lastnum;
|
||||
FILE *logfp;
|
||||
struct rogue_player P;
|
||||
char buffered[8192];
|
||||
char buffered[10000];
|
||||
uint8_t playerdata[10000];
|
||||
};
|
||||
extern struct rogue_state globalR;
|
||||
@@ -374,12 +375,12 @@ extern struct rogue_state globalR;
|
||||
int rogue(int argc, char **argv, char **envp);
|
||||
void rogueiterate(struct rogue_state *rs);
|
||||
int32_t roguefname(char *fname,uint64_t seed,int32_t counter);
|
||||
int32_t flushkeystrokes(struct rogue_state *rs);
|
||||
int32_t flushkeystrokes(struct rogue_state *rs,int32_t waitflag);
|
||||
int32_t rogue_restorepack(struct rogue_state *rs);
|
||||
void restore_player(struct rogue_state *rs);
|
||||
int32_t rogue_replay2(uint8_t *newdata,uint64_t seed,char *keystrokes,int32_t num,struct rogue_player *player,int32_t sleepmillis);
|
||||
void rogue_bailout(struct rogue_state *rs);
|
||||
void rogue_progress(struct rogue_state *rs,uint64_t seed,char *keystrokes,int32_t num);
|
||||
void rogue_progress(struct rogue_state *rs,int32_t waitflag,uint64_t seed,char *keystrokes,int32_t num);
|
||||
int32_t rogue_setplayerdata(struct rogue_state *rs,char *gametxidstr);
|
||||
|
||||
#define ROGUE_MAXTOTAL (pstats.s_str*2)
|
||||
@@ -612,7 +613,7 @@ void current(struct rogue_state *rs,THING *cur, char *how, char *where);
|
||||
void d_level(struct rogue_state *rs);
|
||||
void death(struct rogue_state *rs,char monst);
|
||||
char death_monst(void);
|
||||
void dig(int y, int x);
|
||||
void dig(struct rogue_state *rs,int y, int x);
|
||||
void discard(THING *item);
|
||||
void discovered(struct rogue_state *rs);
|
||||
int dist(int y1, int x1, int y2, int x2);
|
||||
@@ -620,7 +621,7 @@ int dist_cp(coord *c1, coord *c2);
|
||||
int do_chase(struct rogue_state *rs,THING *th);
|
||||
void do_daemons(struct rogue_state *rs,int flag);
|
||||
void do_fuses(struct rogue_state *rs,int flag);
|
||||
void do_maze(struct room *rp);
|
||||
void do_maze(struct rogue_state *rs,struct room *rp);
|
||||
void do_motion(struct rogue_state *rs,THING *obj, int ydelta, int xdelta);
|
||||
void do_move(struct rogue_state *rs,int dy, int dx);
|
||||
void do_passages(struct rogue_state *rs);
|
||||
@@ -632,7 +633,7 @@ void doadd(struct rogue_state *rs,char *fmt, va_list args);
|
||||
void door(struct room *rm, coord *cp);
|
||||
void door_open(struct rogue_state *rs,struct room *rp);
|
||||
void drain(struct rogue_state *rs);
|
||||
void draw_room(struct room *rp);
|
||||
void draw_room(struct rogue_state *rs,struct room *rp);
|
||||
void drop(struct rogue_state *rs);
|
||||
void eat(struct rogue_state *rs);
|
||||
size_t encread(char *start, size_t size, FILE *inf);
|
||||
@@ -761,7 +762,7 @@ bool chase(THING *tp, coord *ee);
|
||||
bool diag_ok(coord *sp, coord *ep);
|
||||
bool dropcheck(struct rogue_state *rs,THING *obj);
|
||||
bool fallpos(coord *pos, coord *newpos);
|
||||
bool find_floor(struct room *rp, coord *cp, int limit, bool monst);
|
||||
bool find_floor(struct rogue_state *rs,struct room *rp, coord *cp, int limit, bool monst);
|
||||
bool is_magic(THING *obj);
|
||||
bool is_symlink(char *sp);
|
||||
bool levit_check(struct rogue_state *rs);
|
||||
@@ -770,7 +771,7 @@ bool roll_em(THING *thatt, THING *thdef, THING *weap, bool hurl);
|
||||
bool see_monst(THING *mp);
|
||||
bool seen_stairs(void);
|
||||
bool turn_ok(int y, int x);
|
||||
bool turn_see(bool turn_off);
|
||||
bool turn_see(struct rogue_state *rs,bool turn_off);
|
||||
bool is_current(struct rogue_state *rs,THING *obj);
|
||||
int passwd(void);
|
||||
|
||||
@@ -824,6 +825,7 @@ void doctor(struct rogue_state *rs,int);
|
||||
void playit(struct rogue_state *rs);
|
||||
|
||||
struct room *roomin(struct rogue_state *rs,coord *cp);
|
||||
int32_t thing_find(THING *ptr);
|
||||
|
||||
#define MAXDAEMONS 20
|
||||
|
||||
|
||||
@@ -1,17 +1,25 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||
# Visual C++ Express 2005
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rogue54", "rogue54.vcproj", "{9EA0D326-8097-4ADA-82EA-4DB1F5CAA8F6}"
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rogue54", "rogue54.vcxproj", "{9EA0D326-8097-4ADA-82EA-4DB1F5CAA8F6}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{9EA0D326-8097-4ADA-82EA-4DB1F5CAA8F6}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{9EA0D326-8097-4ADA-82EA-4DB1F5CAA8F6}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{9EA0D326-8097-4ADA-82EA-4DB1F5CAA8F6}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{9EA0D326-8097-4ADA-82EA-4DB1F5CAA8F6}.Debug|x64.Build.0 = Debug|x64
|
||||
{9EA0D326-8097-4ADA-82EA-4DB1F5CAA8F6}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{9EA0D326-8097-4ADA-82EA-4DB1F5CAA8F6}.Release|Win32.Build.0 = Release|Win32
|
||||
{9EA0D326-8097-4ADA-82EA-4DB1F5CAA8F6}.Release|x64.ActiveCfg = Release|x64
|
||||
{9EA0D326-8097-4ADA-82EA-4DB1F5CAA8F6}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
257
src/cc/rogue/rogue54.vcxproj
Normal file
257
src/cc/rogue/rogue54.vcxproj
Normal file
@@ -0,0 +1,257 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{9EA0D326-8097-4ADA-82EA-4DB1F5CAA8F6}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC70.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC70.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC70.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC70.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>14.0.25431.1</_ProjectFileVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>Debug\</OutDir>
|
||||
<IntDir>Debug\</IntDir>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>Release\</OutDir>
|
||||
<IntDir>Release\</IntDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
|
||||
<AdditionalIncludeDirectories>../pdcurses;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;ALLSCORES;MASTER;SCOREFILE="rogue54.scr";LOCKFILE="rogue54.lck";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<ExceptionHandling />
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
||||
<PrecompiledHeader />
|
||||
<BrowseInformation />
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>Ws2_32.lib;pdcurses.lib;advapi32.lib;shfolder.lib;user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)rogue54.exe</OutputFile>
|
||||
<AdditionalLibraryDirectories>..\pdcurses;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(OutDir)rogue54.pdb</ProgramDatabaseFile>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)x86_64-w64-msvc\deps\install\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;PDC_DLL_BUILD;PDC_WIDE;PDCDEBUG;_CRT_SECURE_NO_DEPRECATE;ALLSCORES;SCOREFILE="rogue54.scr";LOCKFILE="rogue54.lck";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<ExceptionHandling>
|
||||
</ExceptionHandling>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<BrowseInformation>
|
||||
</BrowseInformation>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>Ws2_32.lib;wincon\pdcurses.lib;libcurl_imp.lib;advapi32.lib;shfolder.lib;user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)rogue54.exe</OutputFile>
|
||||
<AdditionalLibraryDirectories>$(ProjectDir)x86_64-w64-msvc\deps\install\lib;$(ProjectDir)x86_64-w64-msvc\deps\install\Release\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(OutDir)rogue54.pdb</ProgramDatabaseFile>
|
||||
<SubSystem>Console</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)\x86_64-w64-msvc\include\ncursesw;$(ProjectDir)\x86_64-w64-msvc\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<OutputFile>$(OutDir)rogue54.exe</OutputFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;PDC_DLL_BUILD;PDC_WIDE;PDCDEBUG;_CRT_SECURE_NO_DEPRECATE;ALLSCORES;SCOREFILE="rogue54.scr";LOCKFILE="rogue54.lck";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>$(ProjectDir)x86_64-w64-msvc\deps\install\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
<ExceptionHandling />
|
||||
<BrowseInformation />
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<OutputFile>$(OutDir)rogue54.exe</OutputFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<AdditionalLibraryDirectories>$(ProjectDir)x86_64-w64-msvc\deps\install\lib;$(ProjectDir)x86_64-w64-msvc\deps\install\Release\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>Ws2_32.lib;wincon\pdcurses.lib;libcurl_imp.lib;advapi32.lib;shfolder.lib;user32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||
<ForceSymbolReferences>%(ForceSymbolReferences)</ForceSymbolReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="armor.c" />
|
||||
<ClCompile Include="chase.c" />
|
||||
<ClCompile Include="command.c" />
|
||||
<ClCompile Include="daemon.c" />
|
||||
<ClCompile Include="daemons.c" />
|
||||
<ClCompile Include="extern.c" />
|
||||
<ClCompile Include="fight.c" />
|
||||
<ClCompile Include="init.c" />
|
||||
<ClCompile Include="io.c" />
|
||||
<ClCompile Include="list.c" />
|
||||
<ClCompile Include="mach_dep.c" />
|
||||
<ClCompile Include="main.c" />
|
||||
<ClCompile Include="mdport.c" />
|
||||
<ClCompile Include="misc.c" />
|
||||
<ClCompile Include="monsters.c" />
|
||||
<ClCompile Include="move.c" />
|
||||
<ClCompile Include="new_level.c" />
|
||||
<ClCompile Include="options.c" />
|
||||
<ClCompile Include="pack.c" />
|
||||
<ClCompile Include="passages.c" />
|
||||
<ClCompile Include="potions.c" />
|
||||
<ClCompile Include="rings.c" />
|
||||
<ClCompile Include="rip.c" />
|
||||
<ClCompile Include="rogue.c" />
|
||||
<ClCompile Include="rooms.c" />
|
||||
<ClCompile Include="save.c" />
|
||||
<ClCompile Include="scrolls.c" />
|
||||
<ClCompile Include="state.c" />
|
||||
<ClCompile Include="sticks.c" />
|
||||
<ClCompile Include="things.c" />
|
||||
<ClCompile Include="vers.c" />
|
||||
<ClCompile Include="weapons.c" />
|
||||
<ClCompile Include="wizard.c" />
|
||||
<ClCompile Include="xcrypt.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="extern.h" />
|
||||
<ClInclude Include="rogue.h" />
|
||||
<ClInclude Include="score.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="LICENSE.TXT" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
64
src/cc/rogue/rogue_build_msvc.cmd
Normal file
64
src/cc/rogue/rogue_build_msvc.cmd
Normal file
@@ -0,0 +1,64 @@
|
||||
@echo off
|
||||
echo Rogue Build Script by Decker (c) 2019
|
||||
|
||||
@REM Check for Visual Studio
|
||||
call set "VSPATH="
|
||||
if defined VS140COMNTOOLS ( if not defined VSPATH (
|
||||
call set "VSPATH=%%VS140COMNTOOLS%%"
|
||||
) )
|
||||
|
||||
@REM check if we already have the tools in the environment
|
||||
if exist "%VCINSTALLDIR%" (
|
||||
goto compile
|
||||
)
|
||||
|
||||
if not defined VSPATH (
|
||||
echo You need Microsoft Visual Studio 15 installed
|
||||
pause
|
||||
exit
|
||||
)
|
||||
|
||||
@REM set up the environment
|
||||
if exist "%VSPATH%..\..\vc\vcvarsall.bat" (
|
||||
call "%%VSPATH%%..\..\vc\vcvarsall.bat" amd64
|
||||
goto compile
|
||||
)
|
||||
|
||||
echo Unable to set up the environment
|
||||
pause
|
||||
exit
|
||||
|
||||
:compile
|
||||
|
||||
mkdir x86_64-w64-msvc\deps
|
||||
mkdir x86_64-w64-msvc\deps\install
|
||||
|
||||
pushd x86_64-w64-msvc\deps
|
||||
|
||||
:compile_pdcurses
|
||||
rem git clone https://github.com/wmcbrine/PDCurses PDCurses.org
|
||||
git clone https://github.com/Bill-Gray/PDCurses
|
||||
|
||||
set PREFIX_DIR=%CD%\install
|
||||
|
||||
pushd PDCurses
|
||||
mkdir build64 & pushd build64
|
||||
rem cmake -G"Visual Studio 14 2015 Win64" -DPDC_WIDE=ON -DCMAKE_INSTALL_PREFIX=%PREFIX_DIR% -DCMAKE_BUILD_TYPE=Debug -DPDCDEBUG=ON ..
|
||||
cmake -G"Visual Studio 14 2015 Win64" -DPDC_WIDE=ON -DCMAKE_INSTALL_PREFIX=%PREFIX_DIR% -DCMAKE_BUILD_TYPE=Release ..
|
||||
popd
|
||||
rem cmake --build build64 --config Debug --target install
|
||||
cmake --build build64 --config Release --target install
|
||||
popd
|
||||
|
||||
:compile_curl
|
||||
|
||||
git clone https://github.com/curl/curl
|
||||
pushd curl
|
||||
|
||||
mkdir build64 & pushd build64
|
||||
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_INSTALL_PREFIX=%PREFIX_DIR% -DCMAKE_USE_WINSSL:BOOL=ON ..
|
||||
cmake --build . --config Release --target libcurl
|
||||
cmake --build . --config Release --target install
|
||||
popd
|
||||
popd
|
||||
|
||||
@@ -112,7 +112,7 @@ do_rooms(struct rogue_state *rs)
|
||||
rp->r_pos.x = top.x + rnd(bsze.x - rp->r_max.x);
|
||||
rp->r_pos.y = top.y + rnd(bsze.y - rp->r_max.y);
|
||||
} until (rp->r_pos.y != 0);
|
||||
draw_room(rp);
|
||||
draw_room(rs,rp);
|
||||
/*
|
||||
* Put the gold in
|
||||
*/
|
||||
@@ -122,7 +122,7 @@ do_rooms(struct rogue_state *rs)
|
||||
|
||||
gold = new_item();
|
||||
gold->o_goldval = rp->r_goldval = GOLDCALC;
|
||||
find_floor(rp, &rp->r_gold, FALSE, FALSE);
|
||||
find_floor(rs,rp, &rp->r_gold, FALSE, FALSE);
|
||||
gold->o_pos = rp->r_gold;
|
||||
chat(rp->r_gold.y, rp->r_gold.x) = GOLD;
|
||||
gold->o_flags = ISMANY;
|
||||
@@ -136,7 +136,7 @@ do_rooms(struct rogue_state *rs)
|
||||
if (rnd(100) < (rp->r_goldval > 0 ? 80 : 25))
|
||||
{
|
||||
tp = new_item();
|
||||
find_floor(rp, &mp, FALSE, TRUE);
|
||||
find_floor(rs,rp, &mp, FALSE, TRUE);
|
||||
new_monster(rs,tp, randmonster(FALSE), &mp);
|
||||
give_pack(rs,tp);
|
||||
}
|
||||
@@ -150,12 +150,12 @@ do_rooms(struct rogue_state *rs)
|
||||
*/
|
||||
|
||||
void
|
||||
draw_room(struct room *rp)
|
||||
draw_room(struct rogue_state *rs,struct room *rp)
|
||||
{
|
||||
int y, x;
|
||||
|
||||
if (rp->r_flags & ISMAZE)
|
||||
do_maze(rp);
|
||||
do_maze(rs,rp);
|
||||
else
|
||||
{
|
||||
vert(rp, rp->r_pos.x); /* Draw left side */
|
||||
@@ -211,7 +211,7 @@ static SPOT maze[NUMLINES/3+1][NUMCOLS/3+1];
|
||||
|
||||
|
||||
void
|
||||
do_maze(struct room *rp)
|
||||
do_maze(struct rogue_state *rs,struct room *rp)
|
||||
{
|
||||
SPOT *sp;
|
||||
int starty, startx;
|
||||
@@ -232,7 +232,7 @@ do_maze(struct room *rp)
|
||||
pos.y = starty + Starty;
|
||||
pos.x = startx + Startx;
|
||||
putpass(&pos);
|
||||
dig(starty, startx);
|
||||
dig(rs,starty, startx);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -241,7 +241,7 @@ do_maze(struct room *rp)
|
||||
*/
|
||||
|
||||
void
|
||||
dig(int y, int x)
|
||||
dig(struct rogue_state *rs,int y, int x)
|
||||
{
|
||||
coord *cp;
|
||||
int cnt, newy, newx, nexty = 0, nextx = 0;
|
||||
@@ -252,6 +252,8 @@ dig(int y, int x)
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if ( rs->replaydone != 0 )
|
||||
return;
|
||||
cnt = 0;
|
||||
for (cp = del; cp <= &del[3]; cp++)
|
||||
{
|
||||
@@ -291,7 +293,7 @@ dig(int y, int x)
|
||||
pos.y = nexty + Starty;
|
||||
pos.x = nextx + Startx;
|
||||
putpass(&pos);
|
||||
dig(nexty, nextx);
|
||||
dig(rs,nexty, nextx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,7 +334,7 @@ rnd_pos(struct room *rp, coord *cp)
|
||||
* pick a new room each time around the loop.
|
||||
*/
|
||||
bool
|
||||
find_floor(struct room *rp, coord *cp, int limit, bool monst)
|
||||
find_floor(struct rogue_state *rs,struct room *rp, coord *cp, int limit, bool monst)
|
||||
{
|
||||
PLACE *pp;
|
||||
int cnt;
|
||||
@@ -346,6 +348,8 @@ find_floor(struct room *rp, coord *cp, int limit, bool monst)
|
||||
cnt = limit;
|
||||
for (;;)
|
||||
{
|
||||
if ( rs->replaydone != 0 )
|
||||
return(FALSE);
|
||||
if (limit && cnt-- == 0)
|
||||
return FALSE;
|
||||
if (pickroom)
|
||||
|
||||
@@ -313,7 +313,7 @@ def:
|
||||
call_it(rs,&scr_info[obj->o_which]);
|
||||
|
||||
if (discardit)
|
||||
discard(obj);
|
||||
discard(obj);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1429,6 +1429,11 @@ rs_write_object(struct rogue_state *rs,FILE *savef, THING *o)
|
||||
struct rogue_packitem *item;
|
||||
if (write_error)
|
||||
return(WRITESTAT);
|
||||
if ( thing_find(o) < 0 )
|
||||
{
|
||||
fprintf(stderr,"cant find thing.%p (%s) in list\n",o,inv_name(o,FALSE)); //sleep(3);
|
||||
return(0);
|
||||
}
|
||||
if ( o->_o._o_packch != 0 )
|
||||
{
|
||||
item = &rs->P.roguepack[rs->P.packsize];
|
||||
|
||||
@@ -158,7 +158,7 @@ do_zap(struct rogue_state *rs)
|
||||
{
|
||||
do
|
||||
{
|
||||
find_floor(NULL, &new_pos, FALSE, TRUE);
|
||||
find_floor(rs,NULL, &new_pos, FALSE, TRUE);
|
||||
} while (ce(new_pos, hero));
|
||||
}
|
||||
else
|
||||
|
||||
@@ -81,6 +81,8 @@ do_motion(struct rogue_state *rs,THING *obj, int ydelta, int xdelta)
|
||||
obj->o_pos = hero;
|
||||
for (;;)
|
||||
{
|
||||
if ( rs->replaydone != 0 )
|
||||
return;
|
||||
/*
|
||||
* Erase the old one
|
||||
*/
|
||||
@@ -127,28 +129,28 @@ fall(struct rogue_state *rs,THING *obj, bool pr)
|
||||
|
||||
if (fallpos(&obj->o_pos, &fpos))
|
||||
{
|
||||
pp = INDEX(fpos.y, fpos.x);
|
||||
pp->p_ch = (char) obj->o_type;
|
||||
obj->o_pos = fpos;
|
||||
if (cansee(rs,fpos.y, fpos.x))
|
||||
{
|
||||
if (pp->p_monst != NULL)
|
||||
pp->p_monst->t_oldch = (char) obj->o_type;
|
||||
else
|
||||
mvaddch(fpos.y, fpos.x, obj->o_type);
|
||||
}
|
||||
attach(lvl_obj, obj);
|
||||
return;
|
||||
pp = INDEX(fpos.y, fpos.x);
|
||||
pp->p_ch = (char) obj->o_type;
|
||||
obj->o_pos = fpos;
|
||||
if (cansee(rs,fpos.y, fpos.x))
|
||||
{
|
||||
if (pp->p_monst != NULL)
|
||||
pp->p_monst->t_oldch = (char) obj->o_type;
|
||||
else
|
||||
mvaddch(fpos.y, fpos.x, obj->o_type);
|
||||
}
|
||||
attach(lvl_obj, obj);
|
||||
return;
|
||||
}
|
||||
if (pr)
|
||||
{
|
||||
if (has_hit)
|
||||
{
|
||||
endmsg(rs);
|
||||
has_hit = FALSE;
|
||||
}
|
||||
msg(rs,"the %s vanishes as it hits the ground",
|
||||
weap_info[obj->o_which].oi_name);
|
||||
if (has_hit)
|
||||
{
|
||||
endmsg(rs);
|
||||
has_hit = FALSE;
|
||||
}
|
||||
msg(rs,"the %s vanishes as it hits the ground",
|
||||
weap_info[obj->o_which].oi_name);
|
||||
}
|
||||
discard(obj);
|
||||
}
|
||||
|
||||
@@ -35,19 +35,21 @@ whatis(struct rogue_state *rs,bool insist, int type)
|
||||
|
||||
for (;;)
|
||||
{
|
||||
obj = get_item(rs,"identify", type);
|
||||
if (insist)
|
||||
{
|
||||
if (n_objs == 0)
|
||||
return;
|
||||
else if (obj == NULL)
|
||||
msg(rs,"you must identify something");
|
||||
else if (type && obj->o_type != type &&
|
||||
!(type == R_OR_S && (obj->o_type == RING || obj->o_type == STICK)) )
|
||||
msg(rs,"you must identify a %s", type_name(type));
|
||||
else
|
||||
break;
|
||||
}
|
||||
if ( rs->replaydone != 0 )
|
||||
return;
|
||||
obj = get_item(rs,"identify", type);
|
||||
if (insist)
|
||||
{
|
||||
if (n_objs == 0)
|
||||
return;
|
||||
else if (obj == NULL)
|
||||
msg(rs,"you must identify something");
|
||||
else if (type && obj->o_type != type &&
|
||||
!(type == R_OR_S && (obj->o_type == RING || obj->o_type == STICK)) )
|
||||
msg(rs,"you must identify a %s", type_name(type));
|
||||
else
|
||||
break;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
@@ -202,7 +204,7 @@ teleport(struct rogue_state *rs)
|
||||
static coord c;
|
||||
|
||||
mvaddch(hero.y, hero.x, floor_at());
|
||||
find_floor((struct room *) NULL, &c, FALSE, TRUE);
|
||||
find_floor(rs,(struct room *) NULL, &c, FALSE, TRUE);
|
||||
if (roomin(rs,&c) != proom)
|
||||
{
|
||||
leave_room(rs,&hero);
|
||||
|
||||
265
src/cc/rogue/x86_64-w64-msvc/deps/install/include/acs_defs.h
Normal file
265
src/cc/rogue/x86_64-w64-msvc/deps/install/include/acs_defs.h
Normal file
@@ -0,0 +1,265 @@
|
||||
/* Many of the following #defines are completely unused for the
|
||||
nonce. For each character, its code point in code page 437,
|
||||
Unicode, and page 8859-1 are given. The first is used for
|
||||
non-wide builds in Win32 console, DOS, SDL, and OS/2.
|
||||
Unicode is used for all wide builds, and for the non-wide
|
||||
build of WinGUI. Code page 8859-1 is used for non-wide X11.
|
||||
|
||||
All of these characters exist in CP437 and Unicode. Some
|
||||
don't exist in 8859-1, in which case the last column is 'TBD'.
|
||||
Only 32 are used in ncurses. So caution is advised. */
|
||||
|
||||
#ifdef USE_ISO8859_CHARSET
|
||||
#define CHOOSE( A, B, C) (C)
|
||||
#define TBD '!'
|
||||
#else
|
||||
#define CHOOSE( A, B, C) (USE_UNICODE_ACS_CHARS ? B : A)
|
||||
#endif
|
||||
|
||||
/* Codes found from https://en.wikipedia.org/wiki/Code_page_437 */
|
||||
|
||||
#define SMILE CHOOSE( 0x01, 0x263a, 'O')
|
||||
#define REV_SMILE CHOOSE( 0x02, 0x263b, 'O')
|
||||
#define HEART CHOOSE( 0x03, 0x2665, 'H')
|
||||
#define DIAMOND CHOOSE( 0x04, 0x2666, 0x01)
|
||||
#define CLUB CHOOSE( 0x05, 0x2663, 'C')
|
||||
#define SPADE CHOOSE( 0x06, 0x2660, 'S')
|
||||
#define MEDIUM_BULLET CHOOSE( 0x07, 0x2022, 0xb7)
|
||||
#define REV_BULLET CHOOSE( 0x08, 0x2508, 0xb7)
|
||||
#define WHITE_BULLET CHOOSE( 0x09, 0x25cb, 7)
|
||||
#define REV_WHITE_BULLET CHOOSE( 0x0a, 0x25D9, 7)
|
||||
#define MALE_SYM CHOOSE( 0x0b, 0x2642, 'm')
|
||||
#define FEMALE_SYM CHOOSE( 0x0c, 0x2640, 'f')
|
||||
#define QTR_NOTE CHOOSE( 0x0d, 0x266a, 0xbc)
|
||||
#define EIGHTH_NOTE CHOOSE( 0x0e, 0x266b, 0xbd)
|
||||
#define SPLAT CHOOSE( 0x0f, 0xa4 , 0xa4)
|
||||
#define RIGHT_TRIANGLE CHOOSE( 0x10, 0x25b6, '>')
|
||||
#define LEFT_TRIANGLE CHOOSE( 0x11, 0x25c0, '<')
|
||||
#define UP_DOWN_ARROW CHOOSE( 0x12, 0x2195, 0x19)
|
||||
#define DBL_BANG CHOOSE( 0x13, 0x203c, '!')
|
||||
#define PILCROW CHOOSE( 0x14, 0xb6 , 0xb6)
|
||||
#define SECTION_SIGN CHOOSE( 0x15, 0xa7 , 0xa7)
|
||||
#define LOW_QTR_BLOCK CHOOSE( 0x16, 0x25b2, '_')
|
||||
#define UP_DOWN_ARROW_UNDERSCORED CHOOSE( 0x17, 0x21ab, 0x19)
|
||||
#define UP_ARROW CHOOSE( 0x18, 0x2191, '^')
|
||||
#define DOWN_ARROW CHOOSE( 0x19, 0x2193, 'v')
|
||||
#define RIGHT_ARROW CHOOSE( 0x1a, 0x2192, '>')
|
||||
#define LEFT_ARROW CHOOSE( 0x1b, 0x2190, '<')
|
||||
#define RIGHT_ANGLE CHOOSE( 0x1c, 0x221f, 0xe)
|
||||
#define LEFT_RIGHT_ARROW CHOOSE( 0x1d, 0x2194, '-')
|
||||
#define UP_TRIANGLE CHOOSE( 0x1e, 0x25b2, '^')
|
||||
#define DOWN_TRIANGLE CHOOSE( 0x1f, 0x25bc, 'v')
|
||||
|
||||
#define UPPERCASE_C_CEDILLA CHOOSE( 0x80, 0xc7 , 0xc7)
|
||||
#define LOWERCASE_U_UMLAUT CHOOSE( 0x81, 0xfc , 0xfc)
|
||||
#define LOWERCASE_E_ACUTE CHOOSE( 0x82, 0xe9 , 0xe9)
|
||||
#define LOWERCASE_A_CIRCUMFLEX CHOOSE( 0x83, 0xe2 , 0xe2)
|
||||
#define LOWERCASE_A_UMLAUT CHOOSE( 0x84, 0xe4 , 0xe4)
|
||||
#define LOWERCASE_A_GRAVE CHOOSE( 0x85, 0xe0 , 0xea)
|
||||
#define LOWERCASE_A_RING CHOOSE( 0x86, 0xe5 , 0xe5)
|
||||
#define LOWERCASE_C_CEDILLA CHOOSE( 0x87, 0xe7 , 0xe7)
|
||||
#define LOWERCASE_E_CIRCUMFLEX CHOOSE( 0x88, 0xea , 0xea)
|
||||
#define LOWERCASE_E_UMLAUT CHOOSE( 0x89, 0xeb , 0xeb)
|
||||
#define LOWERCASE_E_GRAVE CHOOSE( 0x8a, 0xe8 , 0xe8)
|
||||
#define LOWERCASE_I_UMLAUT CHOOSE( 0x8b, 0xef , 0xef)
|
||||
#define LOWERCASE_I_CIRCUMFLEX CHOOSE( 0x8c, 0xee , 0xee)
|
||||
#define LOWERCASE_I_GRAVE CHOOSE( 0x8d, 0xec , 0xce)
|
||||
#define UPPERCASE_A_UMLAUT CHOOSE( 0x8e, 0xc4 , 0xc4)
|
||||
#define UPPERCASE_A_RING CHOOSE( 0x8f, 0xc5 , 0xc5)
|
||||
|
||||
#define UPPERCASE_E_ACUTE CHOOSE( 0x90, 0xc9 , 0xc9)
|
||||
#define LOWERCASE_AE_LIGATURE CHOOSE( 0x91, 0xe6 , 0xe6)
|
||||
#define UPPERCASE_AE_LIGATURE CHOOSE( 0x92, 0xc6 , 0xc6)
|
||||
#define LOWERCASE_O_CIRCUMFLEX CHOOSE( 0x93, 0xf4 , 0xf4)
|
||||
#define LOWERCASE_O_UMLAUT CHOOSE( 0x94, 0xf6 , 0xf6)
|
||||
#define LOWERCASE_O_GRAVE CHOOSE( 0x95, 0xf2 , 0xf2)
|
||||
#define LOWERCASE_U_CIRCUMFLEX CHOOSE( 0x96, 0xfb , 0xfb)
|
||||
#define LOWERCASE_U_GRAVE CHOOSE( 0x97, 0xf9 , 0xf9)
|
||||
#define LOWERCASE_Y_UMLAUT CHOOSE( 0x98, 0xff , 0xff)
|
||||
#define UPPERCASE_O_UMLAUT CHOOSE( 0x99, 0xd6 , 0xd6)
|
||||
#define UPPERCASE_U_UMLAUT CHOOSE( 0x9a, 0xdc , 0xdc)
|
||||
#define CENT_SIGN CHOOSE( 0x9b, 0xa2 , 0xa2)
|
||||
#define STERLING_SIGN CHOOSE( 0x9c, 0xa3 , 30)
|
||||
#define YEN_SIGN CHOOSE( 0x9d, 0xa5 , 0xa5)
|
||||
#define PESETA_SIGN CHOOSE( 0x9e, 0x20a7, TBD)
|
||||
#define F_WITH_HOOK CHOOSE( 0x9f, 0x0192, TBD)
|
||||
|
||||
#define LOWERCASE_A_ACUTE CHOOSE( 0xa0, 0xe1 , 0xe1)
|
||||
#define LOWERCASE_I_ACUTE CHOOSE( 0xa1, 0xed , 0xed)
|
||||
#define LOWERCASE_O_ACUTE CHOOSE( 0xa2, 0xf3 , 0xf3)
|
||||
#define LOWERCASE_U_ACUTE CHOOSE( 0xa3, 0xfa , 0xfa)
|
||||
#define LOWERCASE_N_TILDE CHOOSE( 0xa4, 0xf1 , 0xf1)
|
||||
#define UPPERCASE_N_TILDE CHOOSE( 0xa5, 0xd1 , 0xd1)
|
||||
#define A_ORDINAL CHOOSE( 0xa6, 0xaa , 0xaa)
|
||||
#define O_ORDINAL CHOOSE( 0xa7, 0xba , 0xba)
|
||||
#define INVERTED_QUESTION_MARK CHOOSE( 0xa8, 0xbf , 0xbf)
|
||||
#define REVERSED_NOT_SIGN CHOOSE( 0xa9, 0x2310, TBD)
|
||||
#define NOT_SIGN CHOOSE( 0xaa, 0xac , 0xac)
|
||||
#define VULGAR_HALF CHOOSE( 0xab, 0xbd , 0xbd)
|
||||
#define VULGAR_QUARTER CHOOSE( 0xac, 0xbc , 0xbc)
|
||||
#define INVERTED_EXCLAMATION_MARK CHOOSE( 0xad, 0xa1 , 0xa1)
|
||||
#define LEFT_ANGLE_QUOTE_MARK CHOOSE( 0xae, 0xab , 0xab)
|
||||
#define RIGHT_ANGLE_QUOTE_MARK CHOOSE( 0xaf, 0xbb , 0xbb)
|
||||
|
||||
#define LIGHT_SHADE CHOOSE( 0xb0, 0x2591, '#' )
|
||||
#define MEDIUM_SHADE CHOOSE( 0xb1, 0x2592, 2)
|
||||
#define DARK_SHADE CHOOSE( 0xb2, 0x2593, TBD)
|
||||
#define BOX_VLINE CHOOSE( 0xb3, 0x2502, 25)
|
||||
#define BOX_RTEE CHOOSE( 0xb4, 0x2524, 22)
|
||||
#define BOX_SD_RTEE CHOOSE( 0xb5, 0x2561, 22)
|
||||
#define BOX_DS_RTEE CHOOSE( 0xb6, 0x2562, 22)
|
||||
#define BOX_DS_URCORNER CHOOSE( 0xb7, 0x2556, 12)
|
||||
#define BOX_SD_URCORNER CHOOSE( 0xb8, 0x2555, 12)
|
||||
#define BOX_D_RTEE CHOOSE( 0xb9, 0x2563, 22)
|
||||
#define BOX_D_VLINE CHOOSE( 0xba, 0x2551, 25)
|
||||
#define BOX_D_URCORNER CHOOSE( 0xbb, 0x2557, 12)
|
||||
#define BOX_D_LRCORNER CHOOSE( 0xbc, 0x255D, 11)
|
||||
#define BOX_DS_LRCORNER CHOOSE( 0xbd, 0x255c, 11)
|
||||
#define BOX_SD_LRCORNER CHOOSE( 0xbe, 0x255b, 11)
|
||||
#define BOX_URCORNER CHOOSE( 0xbf, 0x2510, 12)
|
||||
|
||||
#define BOX_LLCORNER CHOOSE( 0xc0, 0x2514, 14)
|
||||
#define BOX_BTEE CHOOSE( 0xc1, 0x2534, 23)
|
||||
#define BOX_TTEE CHOOSE( 0xc2, 0x252c, 24)
|
||||
#define BOX_LTEE CHOOSE( 0xc3, 0x251c, 21)
|
||||
#define BOX_HLINE CHOOSE( 0xc4, 0x2500, 18)
|
||||
#define BOX_PLUS CHOOSE( 0xc5, 0x253c, 15)
|
||||
#define BOX_SD_LTEE CHOOSE( 0xc6, 0x255e, 21)
|
||||
#define BOX_DS_LTEE CHOOSE( 0xc7, 0x255f, 21)
|
||||
#define BOX_D_LLCORNER CHOOSE( 0xc8, 0x255A, 14)
|
||||
#define BOX_D_ULCORNER CHOOSE( 0xc9, 0x2554, 13)
|
||||
#define BOX_D_BTEE CHOOSE( 0xca, 0x2569, 23)
|
||||
#define BOX_D_TTEE CHOOSE( 0xcb, 0x2566, 24)
|
||||
#define BOX_D_LTEE CHOOSE( 0xcc, 0x2560, 21)
|
||||
#define BOX_D_HLINE CHOOSE( 0xcd, 0x2550, 18)
|
||||
#define BOX_D_PLUS CHOOSE( 0xce, 0x256C, 15)
|
||||
#define BOX_SD_BTEE CHOOSE( 0xcf, 0x2567, 23)
|
||||
|
||||
#define BOX_DS_BTEE CHOOSE( 0xd0, 0x2568, 23)
|
||||
#define BOX_SD_TTEE CHOOSE( 0xd1, 0x2564, 24)
|
||||
#define BOX_DS_TTEE CHOOSE( 0xd2, 0x2565, 24)
|
||||
#define BOX_DS_LLCORNER CHOOSE( 0xd3, 0x2559, 14)
|
||||
#define BOX_SD_LLCORNER CHOOSE( 0xd4, 0x2558, 14)
|
||||
#define BOX_SD_ULCORNER CHOOSE( 0xd5, 0x2552, 13)
|
||||
#define BOX_DS_ULCORNER CHOOSE( 0xd6, 0x2553, 13)
|
||||
#define BOX_DS_PLUS CHOOSE( 0xd7, 0x256b, 15)
|
||||
#define BOX_SD_PLUS CHOOSE( 0xd8, 0x256a, 15)
|
||||
#define BOX_LRCORNER CHOOSE( 0xd9, 0x2518, 11)
|
||||
#define BOX_ULCORNER CHOOSE( 0xda, 0x250c, 13)
|
||||
#define FULL_BLOCK CHOOSE( 0xdb, 0x2588, 0)
|
||||
#define LOWER_HALF_BLOCK CHOOSE( 0xdc, 0x2584, TBD)
|
||||
#define LEFT_HALF_BLOCK CHOOSE( 0xdd, 0x258c, TBD)
|
||||
#define RIGHT_HALF_BLOCK CHOOSE( 0xde, 0x2590, TBD)
|
||||
#define UPPER_HALF_BLOCK CHOOSE( 0xdf, 0x2580, TBD)
|
||||
|
||||
#define ALPHA CHOOSE( 0xe0, 0x03b1, TBD)
|
||||
#define BETA CHOOSE( 0xe1, 0x00df, TBD)
|
||||
#define GAMMA CHOOSE( 0xe2, 0x0393, TBD)
|
||||
#define PI CHOOSE( 0xe3, 0x03c0, 28)
|
||||
#define UPPERCASE_SIGMA CHOOSE( 0xe4, 0x03a3, TBD)
|
||||
#define LOWERCASE_SIGMA CHOOSE( 0xe5, 0x03c3, TBD)
|
||||
#define MU CHOOSE( 0xe6, 0x00b5, 0xb5)
|
||||
#define TAU CHOOSE( 0xe7, 0x03c4, TBD)
|
||||
#define UPPERCASE_PHI CHOOSE( 0xe8, 0x03a6, TBD)
|
||||
#define THETA CHOOSE( 0xe9, 0x0398, TBD)
|
||||
#define OMEGA CHOOSE( 0xea, 0x03a9, TBD)
|
||||
#define DELTA CHOOSE( 0xeb, 0x03b4, TBD)
|
||||
#define INFINITY_SIGN CHOOSE( 0xec, 0x221e, TBD)
|
||||
#define LOWERCASE_PHI CHOOSE( 0xed, 0x03c6, TBD)
|
||||
#define EPSILON CHOOSE( 0xee, 0x03b5, TBD)
|
||||
#define INTERSECTION CHOOSE( 0xef, 0x2229, TBD)
|
||||
|
||||
#define TRIPLE_BAR CHOOSE( 0xf0, 0x2261, TBD)
|
||||
#define PLUS_OR_MINUS CHOOSE( 0xf1, 0x00b1, 8)
|
||||
#define GREATER_THAN_OR_EQUAL_TO CHOOSE( 0xf2, 0x2265, 27)
|
||||
#define LESSER_THAN_OR_EQUAL_TO CHOOSE( 0xf3, 0x2264, 26)
|
||||
#define UPPER_HALF_INTEGRAL_SIGN CHOOSE( 0xf4, 0x2320, TBD)
|
||||
#define LOWER_HALF_INTEGRAL_SIGN CHOOSE( 0xf5, 0x2321, TBD)
|
||||
#define DIVISION_SIGN CHOOSE( 0xf6, 0x00f7, 0xf7)
|
||||
#define APPROXIMATELY_EQUALS_SIGN CHOOSE( 0xf7, 0x2248, TBD)
|
||||
#define DEGREE_SIGN CHOOSE( 0xf8, 0x00b0, 0xb0)
|
||||
#define LARGE_BULLET CHOOSE( 0xf9, 0x2219, 7)
|
||||
#define SMALL_BULLET CHOOSE( 0xfa, 0x00b7, 0xb7)
|
||||
#define SQUARE_ROOT CHOOSE( 0xfb, 0x221a, TBD)
|
||||
#define SUPERSCRIPT_N CHOOSE( 0xfc, 0x207f, TBD)
|
||||
#define SUPERSCRIPT_2 CHOOSE( 0xfd, 0x00b2, 0xb2)
|
||||
#define CENTERED_SQUARE CHOOSE( 0xfe, 0x25a0, TBD)
|
||||
#define NON_BREAKING_SPACE CHOOSE( 0xff, 0x00a0, TBD)
|
||||
|
||||
|
||||
|
||||
/* It says at http://unicode.org/charts/PDF/U2300.pdf */
|
||||
/* that '...the scan line numbers here refer to old, */
|
||||
/* low-resolution technology for terminals, with only */
|
||||
/* nine scan lines per fixed-size character glyph. */
|
||||
/* Even-numbered scan lines are unified with box */
|
||||
/* drawing graphics." */
|
||||
/* The utility of these is questionable; they'd */
|
||||
/* work Just Fine in wingdi (_if_ the appropriate */
|
||||
/* glyphs are available), but not elsewhere. */
|
||||
#define HORIZ_SCAN_LINE_1 CHOOSE( 0x2d, 0x23ba, 16)
|
||||
#define HORIZ_SCAN_LINE_3 CHOOSE( 0x2d, 0x23bb, 17)
|
||||
#define HORIZ_SCAN_LINE_7 CHOOSE( 0x2d, 0x23bc, 19)
|
||||
#define HORIZ_SCAN_LINE_9 CHOOSE( '_', 0x23bd, 20)
|
||||
|
||||
/* Code page 437 lacks a 'for real' not-equals, so for that, */
|
||||
/* we use the double-horizontal single-vertical box drawing : */
|
||||
#define NOT_EQUALS_SIGN CHOOSE( 0xd8, 0x2260, 29)
|
||||
|
||||
# define A(x) ((chtype)x | A_ALTCHARSET)
|
||||
|
||||
chtype acs_map[128] =
|
||||
{
|
||||
A(0), A(1), A(2), A(3), A(4), A(5), A(6), A(7), A(8),
|
||||
A(9), A(10),
|
||||
CLUB, HEART, SPADE, SMILE, REV_SMILE, /* 11 12 13 14 15 */
|
||||
MEDIUM_BULLET, WHITE_BULLET, PILCROW, SECTION_SIGN, /* 16 17 18 19 */
|
||||
A_ORDINAL, O_ORDINAL, LOWERCASE_PHI, /* 20 21 22 */
|
||||
INVERTED_EXCLAMATION_MARK, INVERTED_QUESTION_MARK, /* 23 24 */
|
||||
REVERSED_NOT_SIGN, NOT_SIGN, /* 25 26 */
|
||||
UPPER_HALF_INTEGRAL_SIGN, LOWER_HALF_INTEGRAL_SIGN, /* 27 28 */
|
||||
SUPERSCRIPT_N, CENTERED_SQUARE, F_WITH_HOOK, /* 29 30 31 */
|
||||
|
||||
RIGHT_ARROW, LEFT_ARROW, UP_ARROW, DOWN_ARROW, /* 32 !"# */
|
||||
|
||||
PI, NOT_EQUALS_SIGN, VULGAR_HALF, VULGAR_QUARTER, /* $%&' */
|
||||
'(',
|
||||
LEFT_ANGLE_QUOTE_MARK, RIGHT_ANGLE_QUOTE_MARK, /* )* */
|
||||
DARK_SHADE, SUPERSCRIPT_2, INFINITY_SIGN, /* +,- */
|
||||
ALPHA, BETA, GAMMA, UPPERCASE_SIGMA, LOWERCASE_SIGMA, /* ./012 */
|
||||
'3',
|
||||
MU, TAU, UPPERCASE_PHI, THETA, OMEGA, DELTA, EPSILON, /* 456789: */
|
||||
|
||||
BOX_SD_LRCORNER, BOX_SD_URCORNER, BOX_SD_ULCORNER, /* ;<= */
|
||||
BOX_SD_LLCORNER, BOX_SD_PLUS, /* >? */
|
||||
BOX_SD_LTEE, BOX_SD_RTEE, BOX_SD_BTEE, BOX_SD_TTEE, /* @ABC */
|
||||
|
||||
BOX_D_LRCORNER, BOX_D_URCORNER, BOX_D_ULCORNER, /* DEF */
|
||||
BOX_D_LLCORNER, BOX_D_PLUS, /* GH */
|
||||
BOX_D_LTEE, BOX_D_RTEE, BOX_D_BTEE, BOX_D_TTEE, /* IJKL */
|
||||
|
||||
BOX_DS_LRCORNER, BOX_DS_URCORNER, BOX_DS_ULCORNER, /* MNO */
|
||||
BOX_DS_LLCORNER, BOX_DS_PLUS, /* PQ */
|
||||
BOX_DS_LTEE, BOX_DS_RTEE, BOX_DS_BTEE, BOX_DS_TTEE, /* RSTU */
|
||||
|
||||
BOX_LRCORNER, BOX_URCORNER, BOX_ULCORNER, /* VWX */
|
||||
BOX_LLCORNER, BOX_PLUS, /* YZ */
|
||||
BOX_LTEE, BOX_RTEE, BOX_BTEE, BOX_TTEE, /* [\]^ */
|
||||
|
||||
BOX_HLINE, BOX_VLINE, BOX_D_HLINE, BOX_D_VLINE, /* _`ab */
|
||||
|
||||
DIVISION_SIGN, APPROXIMATELY_EQUALS_SIGN, /* cd */
|
||||
INTERSECTION, TRIPLE_BAR, /* ef */
|
||||
SMALL_BULLET, LARGE_BULLET, SQUARE_ROOT, /* ghi */
|
||||
DIAMOND, MEDIUM_SHADE, /* jk */
|
||||
HORIZ_SCAN_LINE_1, HORIZ_SCAN_LINE_3, /* lm */
|
||||
HORIZ_SCAN_LINE_7, HORIZ_SCAN_LINE_9, /* no */
|
||||
UPPER_HALF_BLOCK, LOWER_HALF_BLOCK, /* pq */
|
||||
LEFT_HALF_BLOCK, RIGHT_HALF_BLOCK, FULL_BLOCK, /* rst */
|
||||
LESSER_THAN_OR_EQUAL_TO, GREATER_THAN_OR_EQUAL_TO, /* uv */
|
||||
DEGREE_SIGN, PLUS_OR_MINUS, LIGHT_SHADE, SPLAT, /* wxyz */
|
||||
CENT_SIGN, YEN_SIGN, PESETA_SIGN, STERLING_SIGN, /* {|}~ */
|
||||
A(127)
|
||||
};
|
||||
|
||||
# undef A
|
||||
1846
src/cc/rogue/x86_64-w64-msvc/deps/install/include/curses.h
Normal file
1846
src/cc/rogue/x86_64-w64-msvc/deps/install/include/curses.h
Normal file
File diff suppressed because it is too large
Load Diff
134
src/cc/rogue/x86_64-w64-msvc/deps/install/include/curspriv.h
Normal file
134
src/cc/rogue/x86_64-w64-msvc/deps/install/include/curspriv.h
Normal file
@@ -0,0 +1,134 @@
|
||||
/* Public Domain Curses */
|
||||
|
||||
/* Private definitions and declarations for use within PDCurses.
|
||||
These should generally not be referenced by applications. */
|
||||
|
||||
#ifndef __CURSES_INTERNALS__
|
||||
#define __CURSES_INTERNALS__ 1
|
||||
|
||||
#define CURSES_LIBRARY
|
||||
#include <curses.h>
|
||||
|
||||
#if defined(__TURBOC__) || defined(__EMX__) || defined(__DJGPP__) || \
|
||||
defined(__CYGWIN__) || defined(__MINGW32__) || \
|
||||
defined(__WATCOMC__) || defined(__PACIFIC__)
|
||||
# ifndef HAVE_VSSCANF
|
||||
# define HAVE_VSSCANF /* have vsscanf() */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__CYGWIN__) || defined(__MINGW32__) || \
|
||||
defined(__LCC__) || defined(__WATCOMC__)
|
||||
# ifndef HAVE_VSNPRINTF
|
||||
# define HAVE_VSNPRINTF /* have vsnprintf() */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && defined(_WIN32) && !defined(_CRT_SECURE_NO_DEPRECATE)
|
||||
# define _CRT_SECURE_NO_DEPRECATE 1 /* kill nonsense warnings */
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
typedef struct /* structure for ripped off lines */
|
||||
{
|
||||
int line;
|
||||
int (*init)(WINDOW *, int);
|
||||
} RIPPEDOFFLINE;
|
||||
|
||||
/* Window properties */
|
||||
|
||||
#define _SUBWIN 0x01 /* window is a subwindow */
|
||||
#define _PAD 0x10 /* X/Open Pad. */
|
||||
#define _SUBPAD 0x20 /* X/Open subpad. */
|
||||
|
||||
/* Miscellaneous */
|
||||
|
||||
#define _NO_CHANGE -1 /* flags line edge unchanged */
|
||||
|
||||
#define _ECHAR 0x08 /* Erase char (^H) */
|
||||
#define _DWCHAR 0x17 /* Delete Word char (^W) */
|
||||
#define _DLCHAR 0x15 /* Delete Line char (^U) */
|
||||
|
||||
extern WINDOW *pdc_lastscr;
|
||||
extern FILE *pdc_dbfp; /* tracing file pointer (NULL = off) */
|
||||
extern bool pdc_color_started;
|
||||
extern unsigned long pdc_key_modifiers;
|
||||
extern MOUSE_STATUS pdc_mouse_status;
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/* Platform implementation functions */
|
||||
|
||||
void PDC_beep(void);
|
||||
bool PDC_can_change_color(void);
|
||||
int PDC_color_content(short, short *, short *, short *);
|
||||
bool PDC_check_key(void);
|
||||
int PDC_curs_set(int);
|
||||
void PDC_flushinp(void);
|
||||
int PDC_get_columns(void);
|
||||
int PDC_get_cursor_mode(void);
|
||||
int PDC_get_key(void);
|
||||
int PDC_get_rows(void);
|
||||
void PDC_gotoyx(int, int);
|
||||
int PDC_init_color(short, short, short, short);
|
||||
void PDC_init_pair(short, short, short);
|
||||
int PDC_modifiers_set(void);
|
||||
int PDC_mouse_set(void);
|
||||
void PDC_napms(int);
|
||||
int PDC_pair_content(short, short *, short *);
|
||||
void PDC_reset_prog_mode(void);
|
||||
void PDC_reset_shell_mode(void);
|
||||
int PDC_resize_screen(int, int);
|
||||
void PDC_restore_screen_mode(int);
|
||||
void PDC_save_screen_mode(int);
|
||||
void PDC_scr_close(void);
|
||||
void PDC_scr_free(void);
|
||||
int PDC_scr_open(int, char **);
|
||||
void PDC_set_keyboard_binary(bool);
|
||||
void PDC_transform_line(int, int, int, const chtype *);
|
||||
const char *PDC_sysname(void);
|
||||
|
||||
/* Internal cross-module functions */
|
||||
|
||||
void PDC_init_atrtab(void);
|
||||
WINDOW *PDC_makelines(WINDOW *);
|
||||
WINDOW *PDC_makenew(int, int, int, int);
|
||||
int PDC_mouse_in_slk(int, int);
|
||||
void PDC_slk_free(void);
|
||||
void PDC_slk_initialize(void);
|
||||
void PDC_sync(WINDOW *);
|
||||
|
||||
#ifdef PDC_WIDE
|
||||
int PDC_mbtowc(wchar_t *, const char *, size_t);
|
||||
size_t PDC_mbstowcs(wchar_t *, const char *, size_t);
|
||||
size_t PDC_wcstombs(char *, const wchar_t *, size_t);
|
||||
#endif
|
||||
|
||||
#ifdef PDCDEBUG
|
||||
# define PDC_LOG(x) if (pdc_dbfp) PDC_debug x
|
||||
#else
|
||||
# define PDC_LOG(x)
|
||||
#endif
|
||||
|
||||
/* Internal macros for attributes */
|
||||
|
||||
#ifdef CHTYPE_LONG
|
||||
# define PDC_COLOR_PAIRS 256
|
||||
#else
|
||||
# define PDC_COLOR_PAIRS 32
|
||||
#endif
|
||||
|
||||
#ifndef max
|
||||
# define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef min
|
||||
# define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#define DIVROUND(num, divisor) (((num) + ((divisor) >> 1)) / (divisor))
|
||||
|
||||
#define PDC_CLICK_PERIOD 150 /* time to wait for a click, if
|
||||
not set by mouseinterval() */
|
||||
|
||||
#endif /* __CURSES_INTERNALS__*/
|
||||
93
src/cc/rogue/x86_64-w64-msvc/deps/install/include/getopt.h
Normal file
93
src/cc/rogue/x86_64-w64-msvc/deps/install/include/getopt.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/* $Id: getopt.h,v 1.1 2009/10/16 19:50:28 rodney Exp rodney $ */
|
||||
/* $OpenBSD: getopt.h,v 1.1 2002/12/03 20:24:29 millert Exp $ */
|
||||
/* $NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Dieter Baron and Thomas Klausner.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _GETOPT_H_
|
||||
#define _GETOPT_H_
|
||||
|
||||
#if 0
|
||||
#include <sys/cdefs.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* GNU-like getopt_long() and 4.4BSD getsubopt()/optreset extensions
|
||||
*/
|
||||
#define no_argument 0
|
||||
#define required_argument 1
|
||||
#define optional_argument 2
|
||||
|
||||
struct option {
|
||||
/* name of long option */
|
||||
const char *name;
|
||||
/*
|
||||
* one of no_argument, required_argument, and optional_argument:
|
||||
* whether option takes an argument
|
||||
*/
|
||||
int has_arg;
|
||||
/* if not NULL, set *flag to val when option found */
|
||||
int *flag;
|
||||
/* if flag not NULL, value to set *flag to; else return value */
|
||||
int val;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int getopt_long(int, char * const *, const char *,
|
||||
const struct option *, int *);
|
||||
int getopt_long_only(int, char * const *, const char *,
|
||||
const struct option *, int *);
|
||||
#ifndef _GETOPT_DEFINED
|
||||
#define _GETOPT_DEFINED
|
||||
int getopt(int, char * const *, const char *);
|
||||
int getsubopt(char **, char * const *, char **);
|
||||
|
||||
extern char *optarg; /* getopt(3) external variables */
|
||||
extern int opterr;
|
||||
extern int optind;
|
||||
extern int optopt;
|
||||
extern int optreset;
|
||||
extern char *suboptarg; /* getsubopt(3) external variable */
|
||||
#endif /* _GETOPT_DEFINED */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !_GETOPT_H_ */
|
||||
56
src/cc/rogue/x86_64-w64-msvc/deps/install/include/panel.h
Normal file
56
src/cc/rogue/x86_64-w64-msvc/deps/install/include/panel.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/* Public Domain Curses */
|
||||
|
||||
/*----------------------------------------------------------------------*
|
||||
* Panels for PDCurses *
|
||||
*----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __PDCURSES_PANEL_H__
|
||||
#define __PDCURSES_PANEL_H__ 1
|
||||
|
||||
#include <curses.h>
|
||||
|
||||
#if defined(__cplusplus) || defined(__cplusplus__) || defined(__CPLUSPLUS)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef struct panelobs
|
||||
{
|
||||
struct panelobs *above;
|
||||
struct panel *pan;
|
||||
} PANELOBS;
|
||||
|
||||
typedef struct panel
|
||||
{
|
||||
WINDOW *win;
|
||||
int wstarty;
|
||||
int wendy;
|
||||
int wstartx;
|
||||
int wendx;
|
||||
struct panel *below;
|
||||
struct panel *above;
|
||||
const void *user;
|
||||
struct panelobs *obscure;
|
||||
} PANEL;
|
||||
|
||||
PDCEX int bottom_panel(PANEL *pan);
|
||||
PDCEX int del_panel(PANEL *pan);
|
||||
PDCEX int hide_panel(PANEL *pan);
|
||||
PDCEX int move_panel(PANEL *pan, int starty, int startx);
|
||||
PDCEX PANEL *new_panel(WINDOW *win);
|
||||
PDCEX PANEL *panel_above(const PANEL *pan);
|
||||
PDCEX PANEL *panel_below(const PANEL *pan);
|
||||
PDCEX int panel_hidden(const PANEL *pan);
|
||||
PDCEX const void *panel_userptr(const PANEL *pan);
|
||||
PDCEX WINDOW *panel_window(const PANEL *pan);
|
||||
PDCEX int replace_panel(PANEL *pan, WINDOW *win);
|
||||
PDCEX int set_panel_userptr(PANEL *pan, const void *uptr);
|
||||
PDCEX int show_panel(PANEL *pan);
|
||||
PDCEX int top_panel(PANEL *pan);
|
||||
PDCEX void update_panels(void);
|
||||
|
||||
#if defined(__cplusplus) || defined(__cplusplus__) || defined(__CPLUSPLUS)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __PDCURSES_PANEL_H__ */
|
||||
48
src/cc/rogue/x86_64-w64-msvc/deps/install/include/term.h
Normal file
48
src/cc/rogue/x86_64-w64-msvc/deps/install/include/term.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/* Public Domain Curses */
|
||||
|
||||
/* PDCurses doesn't operate with terminfo, but we need these functions for
|
||||
compatibility, to allow some things (notably, interface libraries for
|
||||
other languages) to be compiled. Anyone who tries to actually _use_
|
||||
them will be disappointed, since they only return ERR. */
|
||||
|
||||
#ifndef __PDCURSES_TERM_H__
|
||||
#define __PDCURSES_TERM_H__ 1
|
||||
|
||||
#include <curses.h>
|
||||
|
||||
#if defined(__cplusplus) || defined(__cplusplus__) || defined(__CPLUSPLUS)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char *_termname;
|
||||
} TERMINAL;
|
||||
|
||||
/* PDCEX is defined in curses.h */
|
||||
PDCEX TERMINAL *cur_term;
|
||||
|
||||
int del_curterm(TERMINAL *);
|
||||
int putp(const char *);
|
||||
int restartterm(const char *, int, int *);
|
||||
TERMINAL *set_curterm(TERMINAL *);
|
||||
int setterm(const char *);
|
||||
int setupterm(const char *, int, int *);
|
||||
int tgetent(char *, const char *);
|
||||
int tgetflag(const char *);
|
||||
int tgetnum(const char *);
|
||||
char *tgetstr(const char *, char **);
|
||||
char *tgoto(const char *, int, int);
|
||||
int tigetflag(const char *);
|
||||
int tigetnum(const char *);
|
||||
char *tigetstr(const char *);
|
||||
char *tparm(const char *, long, long, long, long, long,
|
||||
long, long, long, long);
|
||||
int tputs(const char *, int, int (*)(int));
|
||||
|
||||
#if defined(__cplusplus) || defined(__cplusplus__) || defined(__CPLUSPLUS)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __PDCURSES_TERM_H__ */
|
||||
56
src/cc/rogue/x86_64-w64-msvc/deps/install/include/unistd.h
Normal file
56
src/cc/rogue/x86_64-w64-msvc/deps/install/include/unistd.h
Normal file
@@ -0,0 +1,56 @@
|
||||
#ifndef _UNISTD_H
|
||||
#define _UNISTD_H 1
|
||||
|
||||
/* This is intended as a drop-in replacement for unistd.h on Windows.
|
||||
* Please add functionality as neeeded.
|
||||
* https://stackoverflow.com/a/826027/1202830
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <io.h>
|
||||
#include <getopt.h> /* getopt at: https://gist.github.com/ashelly/7776712 */
|
||||
#include <process.h> /* for getpid() and the exec..() family */
|
||||
#include <direct.h> /* for _getcwd() and _chdir() */
|
||||
|
||||
#define srandom srand
|
||||
#define random rand
|
||||
|
||||
/* Values for the second argument to access.
|
||||
These may be OR'd together. */
|
||||
#define R_OK 4 /* Test for read permission. */
|
||||
#define W_OK 2 /* Test for write permission. */
|
||||
//#define X_OK 1 /* execute permission - unsupported in windows*/
|
||||
#define F_OK 0 /* Test for existence. */
|
||||
|
||||
#define access _access
|
||||
#define dup2 _dup2
|
||||
#define execve _execve
|
||||
#define ftruncate _chsize
|
||||
#define unlink _unlink
|
||||
#define fileno _fileno
|
||||
#define getcwd _getcwd
|
||||
#define chdir _chdir
|
||||
#define isatty _isatty
|
||||
#define lseek _lseek
|
||||
/* read, write, and close are NOT being #defined here, because while there are file handle specific versions for Windows, they probably don't work for sockets. You need to look at your app and consider whether to call e.g. closesocket(). */
|
||||
|
||||
#ifdef _WIN64
|
||||
#define ssize_t __int64
|
||||
#else
|
||||
#define ssize_t long
|
||||
#endif
|
||||
|
||||
#define STDIN_FILENO 0
|
||||
#define STDOUT_FILENO 1
|
||||
#define STDERR_FILENO 2
|
||||
/* should be in some equivalent to <sys/types.h> */
|
||||
typedef __int8 int8_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef __int32 int32_t;
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
|
||||
#endif /* unistd.h */
|
||||
@@ -169,16 +169,18 @@ CScript rogue_highlanderopret(uint8_t funcid,uint256 gametxid,int32_t regslot,CP
|
||||
uint8_t rogue_highlanderopretdecode(uint256 &gametxid, uint256 &tokenid, int32_t ®slot, CPubKey &pk, std::vector<uint8_t> &playerdata, std::string &symbol, std::string &pname,CScript scriptPubKey)
|
||||
{
|
||||
std::string name, description; std::vector<uint8_t> vorigPubkey;
|
||||
std::vector<std::pair<uint8_t, vscript_t>> oprets, opretsDummy;
|
||||
std::vector<uint8_t> vopretNonfungible, vopret, vopretDummy,origpubkey;
|
||||
uint8_t e, f,*script; std::vector<CPubKey> voutPubkeys;
|
||||
tokenid = zeroid;
|
||||
GetOpReturnData(scriptPubKey, vopret);
|
||||
script = (uint8_t *)vopret.data();
|
||||
if ( script[1] == 'c' && (f= DecodeTokenCreateOpRet(scriptPubKey,origpubkey,name,description,vopretNonfungible)) == 'c' )
|
||||
if ( script[1] == 'c' && (f= DecodeTokenCreateOpRet(scriptPubKey,origpubkey,name,description, oprets)) == 'c' )
|
||||
{
|
||||
GetOpretBlob(oprets, OPRETID_NONFUNGIBLEDATA, vopretNonfungible);
|
||||
vopret = vopretNonfungible;
|
||||
}
|
||||
else if ( script[1] != 'H' && script[1] != 'Q' && (f= DecodeTokenOpRet(scriptPubKey, e, tokenid, voutPubkeys, vopretDummy)) != 0 )
|
||||
else if ( script[1] != 'H' && script[1] != 'Q' && (f= DecodeTokenOpRet(scriptPubKey, e, tokenid, voutPubkeys, opretsDummy)) != 0 )
|
||||
{
|
||||
//fprintf(stderr,"decode opret %c tokenid.%s\n",script[1],tokenid.GetHex().c_str());
|
||||
GetNonfungibleData(tokenid, vopretNonfungible); //load nonfungible data from the 'tokenbase' tx
|
||||
@@ -206,17 +208,20 @@ uint8_t rogue_keystrokesopretdecode(uint256 &gametxid,uint256 &batontxid,CPubKey
|
||||
uint8_t rogue_registeropretdecode(uint256 &gametxid,uint256 &tokenid,uint256 &playertxid,CScript scriptPubKey)
|
||||
{
|
||||
std::string name, description; std::vector<uint8_t> vorigPubkey;
|
||||
std::vector<std::pair<uint8_t, vscript_t>> oprets;
|
||||
std::vector<uint8_t> vopretNonfungible, vopret, vopretDummy,origpubkey;
|
||||
uint8_t e, f,*script; std::vector<CPubKey> voutPubkeys;
|
||||
tokenid = zeroid;
|
||||
GetOpReturnData(scriptPubKey, vopret);
|
||||
script = (uint8_t *)vopret.data();
|
||||
if ( script[1] == 'c' && (f= DecodeTokenCreateOpRet(scriptPubKey,origpubkey,name,description,vopretNonfungible)) == 'c' )
|
||||
if ( script[1] == 'c' && (f= DecodeTokenCreateOpRet(scriptPubKey,origpubkey,name,description,oprets)) == 'c' )
|
||||
{
|
||||
GetOpretBlob(oprets, OPRETID_NONFUNGIBLEDATA, vopretNonfungible);
|
||||
vopret = vopretNonfungible;
|
||||
}
|
||||
else if ( script[1] != 'R' && (f= DecodeTokenOpRet(scriptPubKey, e, tokenid, voutPubkeys, vopretDummy)) != 0 )
|
||||
else if ( script[1] != 'R' && (f= DecodeTokenOpRet(scriptPubKey, e, tokenid, voutPubkeys, oprets)) != 0 )
|
||||
{
|
||||
GetOpretBlob(oprets, OPRETID_ROGUEGAMEDATA, vopretDummy); // blob from non-creation tx opret
|
||||
vopret = vopretDummy;
|
||||
}
|
||||
if ( vopret.size() > 2 && E_UNMARSHAL(vopret,ss >> e; ss >> f; ss >> gametxid; ss >> playertxid) != 0 && e == EVAL_ROGUE && f == 'R' )
|
||||
@@ -277,54 +282,6 @@ int32_t rogue_iamregistered(int32_t maxplayers,uint256 gametxid,CTransaction tx,
|
||||
return(0);
|
||||
}
|
||||
|
||||
int32_t rogue_playersalive(int32_t &numplayers,uint256 gametxid,int32_t maxplayers)
|
||||
{
|
||||
int32_t i,alive = 0; uint64_t txfee = 10000;
|
||||
numplayers = 0;
|
||||
for (i=0; i<maxplayers; i++)
|
||||
{
|
||||
if ( CCgettxout(gametxid,1+i,1) < 0 )
|
||||
{
|
||||
numplayers++;
|
||||
if (CCgettxout(gametxid,1+maxplayers+i,1) == txfee )
|
||||
alive++;
|
||||
}
|
||||
}
|
||||
return(alive);
|
||||
}
|
||||
|
||||
uint64_t rogue_gamefields(UniValue &obj,int64_t maxplayers,int64_t buyin,uint256 gametxid,char *myrogueaddr)
|
||||
{
|
||||
CBlockIndex *pindex; int32_t ht,delay,numplayers; uint256 hashBlock; uint64_t seed=0; char cmd[512]; CTransaction tx;
|
||||
if ( myGetTransaction(gametxid,tx,hashBlock) != 0 && (pindex= komodo_blockindex(hashBlock)) != 0 )
|
||||
{
|
||||
ht = pindex->GetHeight();
|
||||
delay = ROGUE_REGISTRATION * (maxplayers > 1);
|
||||
obj.push_back(Pair("height",ht));
|
||||
obj.push_back(Pair("start",ht+delay));
|
||||
if ( komodo_nextheight() > ht+delay )
|
||||
{
|
||||
if ( (pindex= komodo_chainactive(ht+delay)) != 0 )
|
||||
{
|
||||
hashBlock = pindex->GetBlockHash();
|
||||
obj.push_back(Pair("starthash",hashBlock.ToString()));
|
||||
memcpy(&seed,&hashBlock,sizeof(seed));
|
||||
seed &= (1LL << 62) - 1;
|
||||
obj.push_back(Pair("seed",(int64_t)seed));
|
||||
if ( rogue_iamregistered(maxplayers,gametxid,tx,myrogueaddr) > 0 )
|
||||
sprintf(cmd,"cc/rogue/rogue %llu %s",(long long)seed,gametxid.ToString().c_str());
|
||||
else sprintf(cmd,"./komodo-cli -ac_name=%s cclib register %d \"[%%22%s%%22]\"",ASSETCHAINS_SYMBOL,EVAL_ROGUE,gametxid.ToString().c_str());
|
||||
obj.push_back(Pair("run",cmd));
|
||||
}
|
||||
}
|
||||
}
|
||||
obj.push_back(Pair("alive",rogue_playersalive(numplayers,gametxid,maxplayers)));
|
||||
obj.push_back(Pair("numplayers",numplayers));
|
||||
obj.push_back(Pair("maxplayers",maxplayers));
|
||||
obj.push_back(Pair("buyin",ValueFromAmount(buyin)));
|
||||
return(seed);
|
||||
}
|
||||
|
||||
int32_t rogue_isvalidgame(struct CCcontract_info *cp,int32_t &gameheight,CTransaction &tx,int64_t &buyin,int32_t &maxplayers,uint256 txid,int32_t unspentv0)
|
||||
{
|
||||
uint256 hashBlock; int32_t i,numvouts; char coinaddr[64]; CPubKey roguepk; uint64_t txfee = 10000;
|
||||
@@ -338,7 +295,7 @@ int32_t rogue_isvalidgame(struct CCcontract_info *cp,int32_t &gameheight,CTransa
|
||||
txid = tx.GetHash();
|
||||
//fprintf(stderr,"set txid %s %llu\n",txid.GetHex().c_str(),(long long)CCgettxout(txid,0,1));
|
||||
}
|
||||
if ( IsCClibvout(cp,tx,0,cp->unspendableCCaddr) == txfee && (unspentv0 == 0 || CCgettxout(txid,0,1) == txfee) )
|
||||
if ( IsCClibvout(cp,tx,0,cp->unspendableCCaddr) == txfee && (unspentv0 == 0 || CCgettxout(txid,0,1,0) == txfee) )
|
||||
{
|
||||
if ( rogue_newgameopreturndecode(buyin,maxplayers,tx.vout[numvouts-1].scriptPubKey) == 'G' )
|
||||
{
|
||||
@@ -364,9 +321,29 @@ int32_t rogue_isvalidgame(struct CCcontract_info *cp,int32_t &gameheight,CTransa
|
||||
} else return(-1);
|
||||
}
|
||||
|
||||
UniValue rogue_playerobj(std::vector<uint8_t> playerdata,uint256 playertxid,uint256 tokenid,std::string symbol,std::string pname)
|
||||
void disp_playerdata(std::vector<uint8_t> playerdata)
|
||||
{
|
||||
int32_t i; struct rogue_player P; char packitemstr[512],*datastr=0; UniValue obj(UniValue::VOBJ),a(UniValue::VARR);
|
||||
struct rogue_player P; int32_t i; char packitemstr[512];
|
||||
if ( playerdata.size() > 0 )
|
||||
{
|
||||
for (i=0; i<playerdata.size(); i++)
|
||||
{
|
||||
((uint8_t *)&P)[i] = playerdata[i];
|
||||
fprintf(stderr,"%02x",playerdata[i]);
|
||||
}
|
||||
fprintf(stderr," <- playerdata: gold.%d hp.%d strength.%d/%d level.%d exp.%d dl.%d\n",P.gold,P.hitpoints,P.strength&0xffff,P.strength>>16,P.level,P.experience,P.dungeonlevel);
|
||||
for (i=0; i<P.packsize&&i<MAXPACK; i++)
|
||||
{
|
||||
rogue_packitemstr(packitemstr,&P.roguepack[i]);
|
||||
fprintf(stderr,"%d: %s\n",i,packitemstr);
|
||||
}
|
||||
fprintf(stderr,"\n");
|
||||
}
|
||||
}
|
||||
|
||||
UniValue rogue_playerobj(std::vector<uint8_t> playerdata,uint256 playertxid,uint256 tokenid,std::string symbol,std::string pname,uint256 gametxid)
|
||||
{
|
||||
int32_t i,vout,spentvini,numvouts,n=0; uint256 txid,spenttxid,hashBlock; struct rogue_player P; char packitemstr[512],*datastr=0; UniValue obj(UniValue::VOBJ),a(UniValue::VARR); CTransaction tx;
|
||||
memset(&P,0,sizeof(P));
|
||||
if ( playerdata.size() > 0 )
|
||||
{
|
||||
@@ -384,6 +361,37 @@ UniValue rogue_playerobj(std::vector<uint8_t> playerdata,uint256 playertxid,uint
|
||||
rogue_packitemstr(packitemstr,&P.roguepack[i]);
|
||||
a.push_back(packitemstr);
|
||||
}
|
||||
txid = playertxid;
|
||||
vout = 1;
|
||||
while ( CCgettxout(txid,vout,1,0) < 0 )
|
||||
{
|
||||
spenttxid = zeroid;
|
||||
spentvini = -1;
|
||||
if ( (spentvini= myIsutxo_spent(spenttxid,txid,vout)) >= 0 )
|
||||
txid = spenttxid;
|
||||
else if ( myIsutxo_spentinmempool(spenttxid,spentvini,txid,vout) == 0 || spenttxid == zeroid )
|
||||
{
|
||||
fprintf(stderr,"mempool tracking error %s/v0\n",txid.ToString().c_str());
|
||||
break;
|
||||
}
|
||||
txid = spenttxid;
|
||||
vout = 0;
|
||||
if ( myGetTransaction(txid,tx,hashBlock) != 0 && (numvouts= tx.vout.size()) > 1 )
|
||||
{
|
||||
for (i=0; i<numvouts; i++)
|
||||
if ( tx.vout[i].nValue == 1 )
|
||||
{
|
||||
vout = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//fprintf(stderr,"trace spend to %s/v%d\n",txid.GetHex().c_str(),vout);
|
||||
if ( n++ > ROGUE_MAXITERATIONS )
|
||||
break;
|
||||
}
|
||||
obj.push_back(Pair("gametxid",gametxid.GetHex()));
|
||||
if ( txid != playertxid )
|
||||
obj.push_back(Pair("batontxid",txid.GetHex()));
|
||||
obj.push_back(Pair("playertxid",playertxid.GetHex()));
|
||||
if ( tokenid != zeroid )
|
||||
obj.push_back(Pair("tokenid",tokenid.GetHex()));
|
||||
@@ -447,6 +455,7 @@ int32_t rogue_playerdata(struct CCcontract_info *cp,uint256 &origplayergame,uint
|
||||
{
|
||||
if ( (f= rogue_highlanderopretdecode(gametxid,tokenid,regslot,pk,playerdata,symbol,pname,playertx.vout[numvouts-1].scriptPubKey)) == 'H' || f == 'Q' )
|
||||
{
|
||||
origplayergame = gametxid;
|
||||
if ( tokenid != zeroid )
|
||||
{
|
||||
playertxid = tokenid;
|
||||
@@ -472,19 +481,34 @@ int32_t rogue_playerdata(struct CCcontract_info *cp,uint256 &origplayergame,uint
|
||||
|
||||
int32_t rogue_playerdataspend(CMutableTransaction &mtx,uint256 playertxid,int32_t vout,uint256 origplayergame)
|
||||
{
|
||||
int64_t txfee = 10000;
|
||||
if ( CCgettxout(playertxid,vout,1) == 1 ) // not sure if this is enough validation
|
||||
int64_t txfee = 10000; CTransaction tx; uint256 hashBlock;
|
||||
if ( CCgettxout(playertxid,vout,1,0) == 1 ) // not sure if this is enough validation
|
||||
{
|
||||
mtx.vin.push_back(CTxIn(playertxid,vout,CScript()));
|
||||
return(0);
|
||||
} else return(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
vout = 0;
|
||||
if ( myGetTransaction(playertxid,tx,hashBlock) != 0 && tx.vout[vout].nValue == 1 && tx.vout[vout].scriptPubKey.IsPayToCryptoCondition() != 0 )
|
||||
{
|
||||
if ( CCgettxout(playertxid,vout,1,0) == 1 ) // not sure if this is enough validation
|
||||
{
|
||||
mtx.vin.push_back(CTxIn(playertxid,vout,CScript()));
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t rogue_findbaton(struct CCcontract_info *cp,uint256 &playertxid,char **keystrokesp,int32_t &numkeys,int32_t ®slot,std::vector<uint8_t> &playerdata,uint256 &batontxid,int32_t &batonvout,int64_t &batonvalue,int32_t &batonht,uint256 gametxid,CTransaction gametx,int32_t maxplayers,char *destaddr,int32_t &numplayers,std::string &symbol,std::string &pname)
|
||||
{
|
||||
int32_t i,numvouts,spentvini,n,matches = 0; CPubKey pk; uint256 tid,active,spenttxid,tokenid,hashBlock,txid,origplayergame; CTransaction spenttx,matchtx,batontx; std::vector<uint8_t> checkdata; CBlockIndex *pindex; char ccaddr[64],*keystrokes=0;
|
||||
numkeys = numplayers = 0;
|
||||
playertxid = zeroid;
|
||||
batonvalue = numkeys = numplayers = batonht = 0;
|
||||
playertxid = batontxid = zeroid;
|
||||
if ( keystrokesp != 0 )
|
||||
*keystrokesp = 0;
|
||||
for (i=0; i<maxplayers; i++)
|
||||
{
|
||||
//fprintf(stderr,"findbaton.%d of %d\n",i,maxplayers);
|
||||
@@ -505,82 +529,172 @@ int32_t rogue_findbaton(struct CCcontract_info *cp,uint256 &playertxid,char **ke
|
||||
}
|
||||
if ( matches == 1 )
|
||||
{
|
||||
if ( myIsutxo_spent(spenttxid,gametxid,maxplayers+i+1) < 0 )
|
||||
numvouts = matchtx.vout.size();
|
||||
//fprintf(stderr,"matchtxid.%s matches.%d numvouts.%d\n",matchtx.GetHash().GetHex().c_str(),matches,numvouts);
|
||||
if ( rogue_registeropretdecode(txid,tokenid,playertxid,matchtx.vout[numvouts-1].scriptPubKey) == 'R' )//&& txid == gametxid )
|
||||
{
|
||||
numvouts = matchtx.vout.size();
|
||||
//fprintf(stderr,"matchtxid.%s matches.%d numvouts.%d\n",matchtx.GetHash().GetHex().c_str(),matches,numvouts);
|
||||
if ( rogue_registeropretdecode(txid,tokenid,playertxid,matchtx.vout[numvouts-1].scriptPubKey) == 'R' )//&& txid == gametxid )
|
||||
//fprintf(stderr,"tokenid.%s txid.%s vs gametxid.%s player.%s\n",tokenid.GetHex().c_str(),txid.GetHex().c_str(),gametxid.GetHex().c_str(),playertxid.GetHex().c_str());
|
||||
if ( tokenid != zeroid )
|
||||
active = tokenid;
|
||||
else active = playertxid;
|
||||
if ( active == zeroid || rogue_playerdata(cp,origplayergame,tid,pk,playerdata,symbol,pname,active) == 0 )
|
||||
{
|
||||
//fprintf(stderr,"tokenid.%s txid.%s vs gametxid.%s player.%s\n",tokenid.GetHex().c_str(),txid.GetHex().c_str(),gametxid.GetHex().c_str(),playertxid.GetHex().c_str());
|
||||
if ( tokenid != zeroid )
|
||||
active = tokenid;
|
||||
else active = playertxid;
|
||||
if ( active == zeroid || rogue_playerdata(cp,origplayergame,tid,pk,playerdata,symbol,pname,active) == 0 )
|
||||
txid = matchtx.GetHash();
|
||||
//fprintf(stderr,"scan forward active.%s spenttxid.%s\n",active.GetHex().c_str(),txid.GetHex().c_str());
|
||||
n = 0;
|
||||
while ( CCgettxout(txid,0,1,0) < 0 )
|
||||
{
|
||||
txid = matchtx.GetHash();
|
||||
//fprintf(stderr,"scan forward active.%s spenttxid.%s\n",active.GetHex().c_str(),txid.GetHex().c_str());
|
||||
n = 0;
|
||||
while ( CCgettxout(txid,0,1) < 0 )
|
||||
spenttxid = zeroid;
|
||||
spentvini = -1;
|
||||
if ( (spentvini= myIsutxo_spent(spenttxid,txid,0)) >= 0 )
|
||||
txid = spenttxid;
|
||||
else
|
||||
{
|
||||
spenttxid = zeroid;
|
||||
spentvini = -1;
|
||||
if ( (spentvini= myIsutxo_spent(spenttxid,txid,0)) >= 0 )
|
||||
txid = spenttxid;
|
||||
else if ( myIsutxo_spentinmempool(spenttxid,spentvini,txid,0) == 0 || spenttxid == zeroid )
|
||||
if ( myIsutxo_spentinmempool(spenttxid,spentvini,txid,0) == 0 || spenttxid == zeroid )
|
||||
{
|
||||
fprintf(stderr,"mempool tracking error %s/v0\n",txid.ToString().c_str());
|
||||
return(-2);
|
||||
}
|
||||
txid = spenttxid;
|
||||
if ( spentvini != 0 )
|
||||
return(-3);
|
||||
if ( keystrokesp != 0 && myGetTransaction(spenttxid,spenttx,hashBlock) != 0 && spenttx.vout.size() >= 2 )
|
||||
{
|
||||
uint256 g,b; CPubKey p; std::vector<uint8_t> k;
|
||||
if ( rogue_keystrokesopretdecode(g,b,p,k,spenttx.vout[spenttx.vout.size()-1].scriptPubKey) == 'K' )
|
||||
{
|
||||
keystrokes = (char *)realloc(keystrokes,numkeys + (int32_t)k.size());
|
||||
for (i=0; i<k.size(); i++)
|
||||
keystrokes[numkeys+i] = (char)k[i];
|
||||
numkeys += (int32_t)k.size();
|
||||
(*keystrokesp) = keystrokes;
|
||||
}
|
||||
}
|
||||
if ( ++n >= ROGUE_MAXITERATIONS )
|
||||
{
|
||||
fprintf(stderr,"rogue_findbaton n.%d, seems something is wrong\n",n);
|
||||
return(-5);
|
||||
}
|
||||
//fprintf(stderr,"n.%d txid.%s\n",n,txid.GetHex().c_str());
|
||||
}
|
||||
//fprintf(stderr,"set baton %s\n",txid.GetHex().c_str());
|
||||
batontxid = txid;
|
||||
batonvout = 0; // not vini
|
||||
// how to detect timeout, bailedout, highlander
|
||||
hashBlock = zeroid;
|
||||
if ( myGetTransaction(batontxid,batontx,hashBlock) != 0 && batontx.vout.size() > 0 )
|
||||
txid = spenttxid;
|
||||
//fprintf(stderr,"n.%d next txid.%s/v%d\n",n,txid.GetHex().c_str(),spentvini);
|
||||
if ( spentvini != 0 ) // game is over?
|
||||
{
|
||||
if ( hashBlock == zeroid )
|
||||
batonht = komodo_nextheight();
|
||||
else if ( (pindex= komodo_blockindex(hashBlock)) == 0 )
|
||||
return(-4);
|
||||
else batonht = pindex->GetHeight();
|
||||
batonvalue = batontx.vout[0].nValue;
|
||||
//printf("batonht.%d keystrokes[%d]\n",batonht,numkeys);
|
||||
return(0);
|
||||
} else fprintf(stderr,"couldnt find baton\n");
|
||||
} else fprintf(stderr,"error with playerdata\n");
|
||||
} else fprintf(stderr,"findbaton opret error\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"already played\n");
|
||||
return(-5);
|
||||
}
|
||||
}
|
||||
if ( keystrokesp != 0 && myGetTransaction(spenttxid,spenttx,hashBlock) != 0 && spenttx.vout.size() >= 2 )
|
||||
{
|
||||
uint256 g,b; CPubKey p; std::vector<uint8_t> k;
|
||||
if ( rogue_keystrokesopretdecode(g,b,p,k,spenttx.vout[spenttx.vout.size()-1].scriptPubKey) == 'K' )
|
||||
{
|
||||
keystrokes = (char *)realloc(keystrokes,numkeys + (int32_t)k.size());
|
||||
for (i=0; i<k.size(); i++)
|
||||
keystrokes[numkeys+i] = (char)k[i];
|
||||
numkeys += (int32_t)k.size();
|
||||
(*keystrokesp) = keystrokes;
|
||||
//fprintf(stderr,"updated keystrokes.%p[%d]\n",keystrokes,numkeys);
|
||||
}
|
||||
}
|
||||
//fprintf(stderr,"n.%d txid.%s\n",n,txid.GetHex().c_str());
|
||||
if ( ++n >= ROGUE_MAXITERATIONS )
|
||||
{
|
||||
fprintf(stderr,"rogue_findbaton n.%d, seems something is wrong\n",n);
|
||||
return(-5);
|
||||
}
|
||||
}
|
||||
//fprintf(stderr,"set baton %s\n",txid.GetHex().c_str());
|
||||
batontxid = txid;
|
||||
batonvout = 0; // not vini
|
||||
// how to detect timeout, bailedout, highlander
|
||||
hashBlock = zeroid;
|
||||
if ( myGetTransaction(batontxid,batontx,hashBlock) != 0 && batontx.vout.size() > 0 )
|
||||
{
|
||||
if ( hashBlock == zeroid )
|
||||
batonht = komodo_nextheight();
|
||||
else if ( (pindex= komodo_blockindex(hashBlock)) == 0 )
|
||||
return(-4);
|
||||
else batonht = pindex->GetHeight();
|
||||
batonvalue = batontx.vout[0].nValue;
|
||||
//printf("batonht.%d keystrokes[%d]\n",batonht,numkeys);
|
||||
return(0);
|
||||
} else fprintf(stderr,"couldnt find baton\n");
|
||||
} else fprintf(stderr,"error with playerdata\n");
|
||||
} else fprintf(stderr,"findbaton opret error\n");
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
int32_t rogue_playersalive(int32_t &openslots,int32_t &numplayers,uint256 gametxid,int32_t maxplayers,int32_t gameht,CTransaction gametx)
|
||||
{
|
||||
int32_t i,n,vout,spentvini,registration_open = 0,alive = 0; CTransaction tx; uint256 txid,spenttxid,hashBlock; CBlockIndex *pindex; uint64_t txfee = 10000;
|
||||
numplayers = openslots = 0;
|
||||
if ( komodo_nextheight() <= gameht+ROGUE_MAXKEYSTROKESGAP )
|
||||
registration_open = 1;
|
||||
for (i=0; i<maxplayers; i++)
|
||||
{
|
||||
//fprintf(stderr,"players alive %d of %d\n",i,maxplayers);
|
||||
if ( CCgettxout(gametxid,1+i,1,0) < 0 )
|
||||
{
|
||||
numplayers++;
|
||||
//fprintf(stderr,"players alive %d spent baton\n",i);
|
||||
if ( CCgettxout(gametxid,1+maxplayers+i,1,0) == txfee )
|
||||
{
|
||||
txid = gametxid;
|
||||
vout = 1+i;
|
||||
//fprintf(stderr,"rogue_playersalive scan forward active.%s spenttxid.%s\n",gametxid.GetHex().c_str(),txid.GetHex().c_str());
|
||||
n = 0;
|
||||
while ( CCgettxout(txid,vout,1,0) < 0 )
|
||||
{
|
||||
spenttxid = zeroid;
|
||||
spentvini = -1;
|
||||
if ( (spentvini= myIsutxo_spent(spenttxid,txid,vout)) >= 0 )
|
||||
txid = spenttxid;
|
||||
else if ( myIsutxo_spentinmempool(spenttxid,spentvini,txid,vout) == 0 || spenttxid == zeroid )
|
||||
{
|
||||
fprintf(stderr,"mempool tracking error %s/v0\n",txid.ToString().c_str());
|
||||
break;
|
||||
}
|
||||
txid = spenttxid;
|
||||
vout = 0;
|
||||
//fprintf(stderr,"n.%d next txid.%s/v%d\n",n,txid.GetHex().c_str(),spentvini);
|
||||
if ( spentvini != 0 )
|
||||
break;
|
||||
if ( n++ > ROGUE_MAXITERATIONS )
|
||||
break;
|
||||
}
|
||||
if ( txid != zeroid )
|
||||
{
|
||||
if ( myGetTransaction(txid,tx,hashBlock) != 0 )
|
||||
{
|
||||
if ( (pindex= komodo_blockindex(hashBlock)) != 0 )
|
||||
{
|
||||
if ( pindex->GetHeight() <= gameht+ROGUE_MAXKEYSTROKESGAP )
|
||||
alive++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( registration_open != 0 )
|
||||
openslots++;
|
||||
}
|
||||
//fprintf(stderr,"numalive.%d openslots.%d\n",alive,openslots);
|
||||
return(alive);
|
||||
}
|
||||
|
||||
uint64_t rogue_gamefields(UniValue &obj,int64_t maxplayers,int64_t buyin,uint256 gametxid,char *myrogueaddr)
|
||||
{
|
||||
CBlockIndex *pindex; int32_t ht,openslots,delay,numplayers; uint256 hashBlock; uint64_t seed=0; char cmd[512]; CTransaction tx;
|
||||
if ( myGetTransaction(gametxid,tx,hashBlock) != 0 && (pindex= komodo_blockindex(hashBlock)) != 0 )
|
||||
{
|
||||
ht = pindex->GetHeight();
|
||||
delay = ROGUE_REGISTRATION * (maxplayers > 1);
|
||||
obj.push_back(Pair("height",ht));
|
||||
obj.push_back(Pair("start",ht+delay));
|
||||
if ( komodo_nextheight() > ht+delay )
|
||||
{
|
||||
if ( (pindex= komodo_chainactive(ht+delay)) != 0 )
|
||||
{
|
||||
hashBlock = pindex->GetBlockHash();
|
||||
obj.push_back(Pair("starthash",hashBlock.ToString()));
|
||||
memcpy(&seed,&hashBlock,sizeof(seed));
|
||||
seed &= (1LL << 62) - 1;
|
||||
obj.push_back(Pair("seed",(int64_t)seed));
|
||||
if ( rogue_iamregistered(maxplayers,gametxid,tx,myrogueaddr) > 0 )
|
||||
sprintf(cmd,"cc/rogue/rogue %llu %s",(long long)seed,gametxid.ToString().c_str());
|
||||
else sprintf(cmd,"./komodo-cli -ac_name=%s cclib register %d \"[%%22%s%%22]\"",ASSETCHAINS_SYMBOL,EVAL_ROGUE,gametxid.ToString().c_str());
|
||||
obj.push_back(Pair("run",cmd));
|
||||
}
|
||||
}
|
||||
obj.push_back(Pair("alive",rogue_playersalive(openslots,numplayers,gametxid,maxplayers,ht,tx)));
|
||||
obj.push_back(Pair("openslots",openslots));
|
||||
obj.push_back(Pair("numplayers",numplayers));
|
||||
}
|
||||
obj.push_back(Pair("maxplayers",maxplayers));
|
||||
obj.push_back(Pair("buyin",ValueFromAmount(buyin)));
|
||||
return(seed);
|
||||
}
|
||||
|
||||
void rogue_gameplayerinfo(struct CCcontract_info *cp,UniValue &obj,uint256 gametxid,CTransaction gametx,int32_t vout,int32_t maxplayers,char *myrogueaddr)
|
||||
{
|
||||
// identify if bailout or quit or timed out
|
||||
@@ -594,7 +708,7 @@ void rogue_gameplayerinfo(struct CCcontract_info *cp,UniValue &obj,uint256 gamet
|
||||
obj.push_back(Pair("slot",(int64_t)vout-1));
|
||||
if ( (retval= rogue_findbaton(cp,playertxid,0,numkeys,regslot,playerdata,batontxid,batonvout,batonvalue,batonht,gametxid,gametx,maxplayers,destaddr,numplayers,symbol,pname)) == 0 )
|
||||
{
|
||||
if ( CCgettxout(gametxid,maxplayers+vout,1) == 10000 )
|
||||
if ( CCgettxout(gametxid,maxplayers+vout,1,0) == 10000 )
|
||||
{
|
||||
if ( myGetTransaction(batontxid,batontx,hashBlock) != 0 && batontx.vout.size() > 1 )
|
||||
{
|
||||
@@ -611,7 +725,7 @@ void rogue_gameplayerinfo(struct CCcontract_info *cp,UniValue &obj,uint256 gamet
|
||||
obj.push_back(Pair("batonvalue",ValueFromAmount(batonvalue)));
|
||||
obj.push_back(Pair("batonht",(int64_t)batonht));
|
||||
if ( playerdata.size() > 0 )
|
||||
obj.push_back(Pair("player",rogue_playerobj(playerdata,playertxid,tokenid,symbol,pname)));
|
||||
obj.push_back(Pair("player",rogue_playerobj(playerdata,playertxid,tokenid,symbol,pname,gametxid)));
|
||||
} else fprintf(stderr,"findbaton err.%d\n",retval);
|
||||
}
|
||||
|
||||
@@ -624,7 +738,7 @@ int64_t rogue_registrationbaton(CMutableTransaction &mtx,uint256 gametxid,CTrans
|
||||
for (j=0; j<maxplayers; j++)
|
||||
{
|
||||
vout = ((r + j) % maxplayers) + 1;
|
||||
if ( CCgettxout(gametxid,vout,1) == ROGUE_REGISTRATIONSIZE )
|
||||
if ( CCgettxout(gametxid,vout,1,0) == ROGUE_REGISTRATIONSIZE )
|
||||
{
|
||||
mtx.vin.push_back(CTxIn(gametxid,vout,CScript()));
|
||||
return(ROGUE_REGISTRATIONSIZE);
|
||||
@@ -700,7 +814,7 @@ UniValue rogue_playerinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *param
|
||||
playertxid = juint256(jitem(params,0));
|
||||
if ( rogue_playerdata(cp,origplayergame,tokenid,pk,playerdata,symbol,pname,playertxid) < 0 )
|
||||
return(cclib_error(result,"invalid playerdata"));
|
||||
result.push_back(Pair("player",rogue_playerobj(playerdata,playertxid,tokenid,symbol,pname)));
|
||||
result.push_back(Pair("player",rogue_playerobj(playerdata,playertxid,tokenid,symbol,pname,origplayergame)));
|
||||
} else return(cclib_error(result,"no playertxid"));
|
||||
return(result);
|
||||
} else return(cclib_error(result,"couldnt reparse params"));
|
||||
@@ -764,20 +878,23 @@ UniValue rogue_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
CCaddr1of2set(cp,roguepk,roguepk,cp->CCpriv,destaddr);
|
||||
mtx.vout.push_back(MakeTokensCC1vout(cp->evalcode, 1, burnpk));
|
||||
|
||||
std::vector<uint8_t> vopretExtra; uint8_t e, funcid; uint256 tid; std::vector<CPubKey> voutPubkeys, voutPubkeysEmpty; int32_t didtx = 0;
|
||||
uint8_t e, funcid; uint256 tid; std::vector<CPubKey> voutPubkeys, voutPubkeysEmpty; int32_t didtx = 0;
|
||||
CScript opretRegister = rogue_registeropret(gametxid, playertxid);
|
||||
if ( playertxid != zeroid )
|
||||
{
|
||||
voutPubkeysEmpty.push_back(burnpk);
|
||||
if ( myGetTransaction(playertxid,playertx,hashBlock) != 0 )
|
||||
{
|
||||
if ( (funcid= DecodeTokenOpRet(playertx.vout.back().scriptPubKey, e, tid, voutPubkeys, vopretExtra)) != 0)
|
||||
std::vector<std::pair<uint8_t, vscript_t>> oprets;
|
||||
if ( (funcid= DecodeTokenOpRet(playertx.vout.back().scriptPubKey, e, tid, voutPubkeys, oprets)) != 0)
|
||||
{ // if token in the opret
|
||||
didtx = 1;
|
||||
if ( funcid == 'c' )
|
||||
tid = tokenid == zeroid ? playertxid : tokenid;
|
||||
vscript_t vopretRegister;
|
||||
GetOpReturnData(opretRegister, vopretRegister);
|
||||
rawtx = FinalizeCCTx(0, cp, mtx, mypk, txfee,
|
||||
EncodeTokenOpRet(tid, voutPubkeysEmpty /*=never spent*/, opretRegister));
|
||||
EncodeTokenOpRet(tid, voutPubkeysEmpty /*=never spent*/, std::make_pair(OPRETID_ROGUEGAMEDATA, vopretRegister)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -835,19 +952,20 @@ UniValue rogue_keystrokes(uint64_t txfee,struct CCcontract_info *cp,cJSON *param
|
||||
|
||||
char *rogue_extractgame(int32_t makefiles,char *str,int32_t *numkeysp,std::vector<uint8_t> &newdata,uint64_t &seed,uint256 &playertxid,struct CCcontract_info *cp,uint256 gametxid,char *rogueaddr)
|
||||
{
|
||||
CPubKey roguepk; int32_t i,num,maxplayers,gameheight,batonht,batonvout,numplayers,regslot,numkeys,err; std::string symbol,pname; CTransaction gametx; int64_t buyin,batonvalue; char fname[64],*keystrokes = 0; std::vector<uint8_t> playerdata; uint256 batontxid; FILE *fp; uint8_t newplayer[10000]; struct rogue_player P,endP;
|
||||
CPubKey roguepk; int32_t i,num,retval,maxplayers,gameheight,batonht,batonvout,numplayers,regslot,numkeys,err; std::string symbol,pname; CTransaction gametx; int64_t buyin,batonvalue; char fname[64],*keystrokes = 0; std::vector<uint8_t> playerdata; uint256 batontxid; FILE *fp; uint8_t newplayer[10000]; struct rogue_player P,endP;
|
||||
roguepk = GetUnspendable(cp,0);
|
||||
*numkeysp = 0;
|
||||
seed = 0;
|
||||
num = numkeys = 0;
|
||||
playertxid = zeroid;
|
||||
str[0] = 0;
|
||||
if ( (err= rogue_isvalidgame(cp,gameheight,gametx,buyin,maxplayers,gametxid,0)) == 0 )
|
||||
{
|
||||
if ( rogue_findbaton(cp,playertxid,&keystrokes,numkeys,regslot,playerdata,batontxid,batonvout,batonvalue,batonht,gametxid,gametx,maxplayers,rogueaddr,numplayers,symbol,pname) == 0 )
|
||||
if ( (retval= rogue_findbaton(cp,playertxid,&keystrokes,numkeys,regslot,playerdata,batontxid,batonvout,batonvalue,batonht,gametxid,gametx,maxplayers,rogueaddr,numplayers,symbol,pname)) == 0 )
|
||||
{
|
||||
UniValue obj;
|
||||
seed = rogue_gamefields(obj,maxplayers,buyin,gametxid,rogueaddr);
|
||||
//fprintf(stderr,"(%s) found baton %s numkeys.%d seed.%llu playerdata.%d playertxid.%s\n",pname.size()!=0?pname.c_str():Rogue_pname.c_str(),batontxid.ToString().c_str(),numkeys,(long long)seed,(int32_t)playerdata.size(),playertxid.GetHex().c_str());
|
||||
//fprintf(stderr,"(%s) found baton %s numkeys.%d seed.%llu playerdata.%d playertxid.%s\n",pname.size()!=0?pname.c_str():Rogue_pname.c_str(),batontxid.ToString().c_str(),numkeys,(long long)seed,(int32_t)playerdata.size(),playertxid.GetHex().c_str());
|
||||
memset(&P,0,sizeof(P));
|
||||
if ( playerdata.size() > 0 )
|
||||
{
|
||||
@@ -873,6 +991,7 @@ char *rogue_extractgame(int32_t makefiles,char *str,int32_t *numkeysp,std::vecto
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
//fprintf(stderr,"call replay2\n");
|
||||
num = rogue_replay2(newplayer,seed,keystrokes,numkeys,playerdata.size()==0?0:&P,0);
|
||||
newdata.resize(num);
|
||||
for (i=0; i<num; i++)
|
||||
@@ -880,22 +999,26 @@ char *rogue_extractgame(int32_t makefiles,char *str,int32_t *numkeysp,std::vecto
|
||||
newdata[i] = newplayer[i];
|
||||
((uint8_t *)&endP)[i] = newplayer[i];
|
||||
}
|
||||
//fprintf(stderr,"back replay2 gold.%d\n",endP.gold);
|
||||
if ( endP.gold <= 0 || endP.hitpoints <= 0 || (endP.strength&0xffff) <= 0 || endP.level <= 0 || endP.experience <= 0 || endP.dungeonlevel <= 0 )
|
||||
{
|
||||
//fprintf(stderr,"zero value character was killed -> no playerdata\n");
|
||||
sprintf(str,"zero value character was killed -> no playerdata\n");
|
||||
newdata.resize(0);
|
||||
//P.gold = (P.gold * 8) / 10;
|
||||
*numkeysp = numkeys;
|
||||
return(keystrokes);
|
||||
/* P.gold = (P.gold * 8) / 10;
|
||||
if ( keystrokes != 0 )
|
||||
{
|
||||
free(keystrokes);
|
||||
keystrokes = 0;
|
||||
*numkeysp = 0;
|
||||
}
|
||||
return(keystrokes);
|
||||
}*/
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(str,"extracted $$$gold.%d hp.%d strength.%d/%d level.%d exp.%d dl.%d\n",endP.gold,endP.hitpoints,endP.strength&0xffff,endP.strength>>16,endP.level,endP.experience,endP.dungeonlevel);
|
||||
fprintf(stderr,"%s\n",str);
|
||||
sprintf(str,"$$$gold.%d hp.%d strength.%d/%d level.%d exp.%d dl.%d",endP.gold,endP.hitpoints,endP.strength&0xffff,endP.strength>>16,endP.level,endP.experience,endP.dungeonlevel);
|
||||
//fprintf(stderr,"%s\n",str);
|
||||
*numkeysp = numkeys;
|
||||
return(keystrokes);
|
||||
}
|
||||
@@ -903,7 +1026,7 @@ char *rogue_extractgame(int32_t makefiles,char *str,int32_t *numkeysp,std::vecto
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"extractgame: couldnt find baton keystrokes.%p\n",keystrokes);
|
||||
fprintf(stderr,"extractgame: couldnt find baton keystrokes.%p retval.%d\n",keystrokes,retval);
|
||||
if ( keystrokes != 0 )
|
||||
free(keystrokes), keystrokes = 0;
|
||||
}
|
||||
@@ -914,11 +1037,12 @@ char *rogue_extractgame(int32_t makefiles,char *str,int32_t *numkeysp,std::vecto
|
||||
|
||||
UniValue rogue_extract(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ); CPubKey pk,roguepk; int32_t i,n,numkeys,flag = 0; uint64_t seed; char str[512],rogueaddr[64],*pubstr,*keystrokes = 0; std::vector<uint8_t> newdata; uint256 gametxid,playertxid; FILE *fp; uint8_t pub33[33];
|
||||
UniValue result(UniValue::VOBJ); CPubKey pk,roguepk; int32_t i,n,numkeys,flag = 0; uint64_t seed; char str[512],rogueaddr[64],*pubstr,*hexstr,*keystrokes = 0; std::vector<uint8_t> newdata; uint256 gametxid,playertxid; FILE *fp; uint8_t pub33[33];
|
||||
pk = pubkey2pk(Mypubkey());
|
||||
roguepk = GetUnspendable(cp,0);
|
||||
result.push_back(Pair("name","rogue"));
|
||||
result.push_back(Pair("method","extract"));
|
||||
rogueaddr[0] = 0;
|
||||
if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 )
|
||||
{
|
||||
if ( n > 0 )
|
||||
@@ -927,23 +1051,35 @@ UniValue rogue_extract(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
result.push_back(Pair("gametxid",gametxid.GetHex()));
|
||||
if ( n == 2 )
|
||||
{
|
||||
if ( (pubstr= jstr(jitem(params,1),0)) != 0 && strlen(pubstr) == 66 )
|
||||
if ( (pubstr= jstr(jitem(params,1),0)) != 0 )
|
||||
{
|
||||
decode_hex(pub33,33,pubstr);
|
||||
pk = buf2pk(pub33);
|
||||
if (strlen(pubstr) == 66 )
|
||||
{
|
||||
decode_hex(pub33,33,pubstr);
|
||||
pk = buf2pk(pub33);
|
||||
}
|
||||
else if ( strlen(pubstr) < 36 )
|
||||
strcpy(rogueaddr,pubstr);
|
||||
}
|
||||
//fprintf(stderr,"gametxid.%s %s\n",gametxid.GetHex().c_str(),pubstr);
|
||||
}
|
||||
GetCCaddress1of2(cp,rogueaddr,roguepk,pk);
|
||||
if ( rogueaddr[0] == 0 )
|
||||
GetCCaddress1of2(cp,rogueaddr,roguepk,pk);
|
||||
result.push_back(Pair("rogueaddr",rogueaddr));
|
||||
str[0] = 0;
|
||||
if ( (keystrokes= rogue_extractgame(1,str,&numkeys,newdata,seed,playertxid,cp,gametxid,rogueaddr)) != 0 )
|
||||
{
|
||||
result.push_back(Pair("status","success"));
|
||||
flag = 1;
|
||||
hexstr = (char *)malloc(numkeys*2 + 1);
|
||||
for (i=0; i<numkeys; i++)
|
||||
sprintf(&hexstr[i<<1],"%02x",keystrokes[i]);
|
||||
hexstr[i<<1] = 0;
|
||||
result.push_back(Pair("keystrokes",hexstr));
|
||||
free(hexstr);
|
||||
result.push_back(Pair("numkeys",(int64_t)numkeys));
|
||||
result.push_back(Pair("playertxid",playertxid.GetHex()));
|
||||
result.push_back(Pair("extracted",str));
|
||||
result.push_back(Pair("numkeys",(int64_t)numkeys));
|
||||
result.push_back(Pair("seed",(int64_t)seed));
|
||||
sprintf(str,"cc/rogue/rogue %llu",(long long)seed);
|
||||
result.push_back(Pair("replay",str));
|
||||
@@ -956,36 +1092,59 @@ UniValue rogue_extract(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
return(result);
|
||||
}
|
||||
|
||||
int32_t rogue_playerdata_validate(uint256 &playertxid,struct CCcontract_info *cp,std::vector<uint8_t> playerdata,uint256 gametxid,CPubKey pk)
|
||||
int32_t rogue_playerdata_validate(int64_t *cashoutp,uint256 &playertxid,struct CCcontract_info *cp,std::vector<uint8_t> playerdata,uint256 gametxid,CPubKey pk)
|
||||
{
|
||||
static uint32_t good,bad; static uint256 prevgame;
|
||||
char str[512],*keystrokes,rogueaddr[64],str2[67]; int32_t i,numkeys; std::vector<uint8_t> newdata; uint64_t seed; CPubKey roguepk; struct rogue_player P;
|
||||
if ( gametxid == prevgame )
|
||||
return(0);
|
||||
prevgame = gametxid;
|
||||
char str[512],*keystrokes,rogueaddr[64],str2[67],fname[64]; int32_t i,dungeonlevel,numkeys; std::vector<uint8_t> newdata; uint64_t seed,mult = 10; CPubKey roguepk; struct rogue_player P;
|
||||
*cashoutp = 0;
|
||||
roguepk = GetUnspendable(cp,0);
|
||||
GetCCaddress1of2(cp,rogueaddr,roguepk,pk);
|
||||
//fprintf(stderr,"call extractgame\n");
|
||||
if ( (keystrokes= rogue_extractgame(0,str,&numkeys,newdata,seed,playertxid,cp,gametxid,rogueaddr)) != 0 )
|
||||
{
|
||||
//fprintf(stderr,"numkeys.%d rogue_extractgame %s\n",numkeys,gametxid.GetHex().c_str());
|
||||
free(keystrokes);
|
||||
//fprintf(stderr,"extracted.(%s)\n",str);
|
||||
sprintf(fname,"rogue.%llu.pack",(long long)seed);
|
||||
remove(fname);
|
||||
|
||||
for (i=0; i<newdata.size(); i++)
|
||||
((uint8_t *)&P)[i] = newdata[i];
|
||||
if ( P.amulet != 0 )
|
||||
mult *= 5;
|
||||
dungeonlevel = P.dungeonlevel;
|
||||
if ( P.amulet != 0 && dungeonlevel < 26 )
|
||||
dungeonlevel = 26;
|
||||
*cashoutp = (uint64_t)P.gold * P.gold * mult * dungeonlevel;
|
||||
if ( newdata == playerdata )
|
||||
{
|
||||
good++;
|
||||
fprintf(stderr,"%s good.%d bad.%d\n",gametxid.GetHex().c_str(),good,bad);
|
||||
if ( gametxid != prevgame )
|
||||
{
|
||||
prevgame = gametxid;
|
||||
good++;
|
||||
fprintf(stderr,"%s good.%d bad.%d\n",gametxid.GetHex().c_str(),good,bad);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
newdata[10] = newdata[11] = playerdata[10] = playerdata[11] = 0;
|
||||
if ( newdata == playerdata )
|
||||
{
|
||||
good++;
|
||||
fprintf(stderr,"%s matched after clearing maxstrength good.%d bad.%d\n",gametxid.GetHex().c_str(),good,bad);
|
||||
if ( gametxid != prevgame )
|
||||
{
|
||||
prevgame = gametxid;
|
||||
good++;
|
||||
fprintf(stderr,"%s matched after clearing maxstrength good.%d bad.%d\n",gametxid.GetHex().c_str(),good,bad);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
newdata[0] = newdata[1] = playerdata[0] = playerdata[1] = 0; // vout.2 check will validate gold
|
||||
if ( newdata == playerdata )
|
||||
{
|
||||
if ( gametxid != prevgame )
|
||||
{
|
||||
prevgame = gametxid;
|
||||
good++;
|
||||
fprintf(stderr,"%s matched after clearing lower 16bits of gold good.%d bad.%d\n",gametxid.GetHex().c_str(),good,bad);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
for (i=0; i<playerdata.size(); i++)
|
||||
((uint8_t *)&P)[i] = playerdata[i];
|
||||
if ( P.gold <= 0 || P.hitpoints <= 0 || (P.strength&0xffff) <= 0 || P.level <= 0 || P.experience <= 0 || P.dungeonlevel <= 0 )
|
||||
{
|
||||
//P.gold = (P.gold * 8) / 10;
|
||||
@@ -993,16 +1152,29 @@ int32_t rogue_playerdata_validate(uint256 &playertxid,struct CCcontract_info *cp
|
||||
// playerdata[i] = ((uint8_t *)&P)[i];
|
||||
if ( newdata.size() == 0 )
|
||||
{
|
||||
good++;
|
||||
if ( gametxid != prevgame )
|
||||
{
|
||||
prevgame = gametxid;
|
||||
good++;
|
||||
fprintf(stderr,"zero value character was killed -> no playerdata, good.%d bad.%d\n",good,bad);
|
||||
}
|
||||
*cashoutp = 0;
|
||||
return(0);
|
||||
}
|
||||
fprintf(stderr,"zero value character was killed -> no playerdata, good.%d bad.%d\n",good,bad);
|
||||
}
|
||||
bad++;
|
||||
fprintf(stderr,"%s playerdata: gold.%d hp.%d strength.%d/%d level.%d exp.%d dl.%d\n",gametxid.GetHex().c_str(),P.gold,P.hitpoints,P.strength&0xffff,P.strength>>16,P.level,P.experience,P.dungeonlevel);
|
||||
fprintf(stderr,"newdata[%d] != playerdata[%d], numkeys.%d %s pub.%s playertxid.%s good.%d bad.%d\n",(int32_t)newdata.size(),(int32_t)playerdata.size(),numkeys,rogueaddr,pubkey33_str(str2,(uint8_t *)&pk),playertxid.GetHex().c_str(),good,bad);
|
||||
if ( gametxid != prevgame )
|
||||
{
|
||||
prevgame = gametxid;
|
||||
bad++;
|
||||
disp_playerdata(newdata);
|
||||
disp_playerdata(playerdata);
|
||||
fprintf(stderr,"%s playerdata: gold.%d hp.%d strength.%d/%d level.%d exp.%d dl.%d\n",gametxid.GetHex().c_str(),P.gold,P.hitpoints,P.strength&0xffff,P.strength>>16,P.level,P.experience,P.dungeonlevel);
|
||||
fprintf(stderr,"newdata[%d] != playerdata[%d], numkeys.%d %s pub.%s playertxid.%s good.%d bad.%d\n",(int32_t)newdata.size(),(int32_t)playerdata.size(),numkeys,rogueaddr,pubkey33_str(str2,(uint8_t *)&pk),playertxid.GetHex().c_str(),good,bad);
|
||||
}
|
||||
}
|
||||
//fprintf(stderr,"no keys rogue_extractgame %s\n",gametxid.GetHex().c_str());
|
||||
sprintf(fname,"rogue.%llu.pack",(long long)seed);
|
||||
remove(fname);
|
||||
//fprintf(stderr,"no keys rogue_extractgame %s\n",gametxid.GetHex().c_str());
|
||||
return(-1);
|
||||
}
|
||||
|
||||
@@ -1020,7 +1192,7 @@ UniValue rogue_finishgame(uint64_t txfee,struct CCcontract_info *cp,cJSON *param
|
||||
// vout0 -> 1% ingame gold
|
||||
// get any playerdata, get all keystrokes, replay game and compare final state
|
||||
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
|
||||
UniValue result(UniValue::VOBJ); std::string rawtx,symbol,pname; CTransaction gametx; uint64_t seed,mult; int64_t buyin,batonvalue,inputsum,cashout,CCchange=0; int32_t i,err,gameheight,tmp,numplayers,regslot,n,num,dungeonlevel,numkeys,maxplayers,batonht,batonvout; char myrogueaddr[64],*keystrokes = 0; std::vector<uint8_t> playerdata,newdata,nodata; uint256 batontxid,playertxid,gametxid; CPubKey mypk,roguepk; uint8_t player[10000],mypriv[32],funcid;
|
||||
UniValue result(UniValue::VOBJ); std::string rawtx,symbol,pname; CTransaction gametx; uint64_t seed,mult; int64_t buyin,batonvalue,inputsum,cashout=0,CCchange=0; int32_t i,err,gameheight,tmp,numplayers,regslot,n,num,dungeonlevel,numkeys,maxplayers,batonht,batonvout; char myrogueaddr[64],*keystrokes = 0; std::vector<uint8_t> playerdata,newdata,nodata; uint256 batontxid,playertxid,gametxid; CPubKey mypk,roguepk; uint8_t player[10000],mypriv[32],funcid;
|
||||
struct CCcontract_info *cpTokens, tokensC;
|
||||
|
||||
if ( txfee == 0 )
|
||||
@@ -1086,33 +1258,38 @@ UniValue rogue_finishgame(uint64_t txfee,struct CCcontract_info *cp,cJSON *param
|
||||
}
|
||||
else
|
||||
{
|
||||
//if ( maxplayers == 1 )
|
||||
// mult /= 2;
|
||||
cpTokens = CCinit(&tokensC, EVAL_TOKENS);
|
||||
mtx.vout.push_back(MakeCC1vout(EVAL_TOKENS, txfee, GetUnspendable(cpTokens,NULL))); // marker to token cc addr, burnable and validated
|
||||
mtx.vout.push_back(MakeTokensCC1vout(cp->evalcode,1,mypk));
|
||||
if ( P.amulet != 0 )
|
||||
mult *= 5;
|
||||
dungeonlevel = P.dungeonlevel;
|
||||
if ( P.amulet != 0 && dungeonlevel < 21 )
|
||||
dungeonlevel = 21;
|
||||
if ( P.amulet != 0 && dungeonlevel < 26 )
|
||||
dungeonlevel = 26;
|
||||
cashout = (uint64_t)P.gold * P.gold * mult * dungeonlevel;
|
||||
fprintf(stderr,"\nextracted $$$gold.%d -> %.8f ROGUE hp.%d strength.%d/%d level.%d exp.%d dl.%d n.%d amulet.%d\n",P.gold,(double)cashout/COIN,P.hitpoints,P.strength&0xffff,P.strength>>16,P.level,P.experience,P.dungeonlevel,n,P.amulet);
|
||||
if ( funcid == 'H' && maxplayers > 1 )
|
||||
{
|
||||
if ( (numplayers != maxplayers || (numplayers - rogue_playersalive(tmp,gametxid,maxplayers)) > 1) && P.amulet == 0 )
|
||||
return(cclib_error(result,"highlander must be a winner or last one standing"));
|
||||
if ( P.amulet == 0 )
|
||||
{
|
||||
if ( numplayers != maxplayers )
|
||||
return(cclib_error(result,"numplayers != maxplayers"));
|
||||
else if ( rogue_playersalive(tmp,tmp,gametxid,maxplayers,gameheight,gametx) > 1 )
|
||||
return(cclib_error(result,"highlander must be a winner or last one standing"));
|
||||
}
|
||||
cashout += numplayers * buyin;
|
||||
}
|
||||
if ( cashout >= txfee )
|
||||
if ( cashout > 0 )
|
||||
{
|
||||
if ( (inputsum= AddCClibInputs(cp,mtx,roguepk,cashout,16,cp->unspendableCCaddr)) > (uint64_t)P.gold*mult )
|
||||
if ( (inputsum= AddCClibInputs(cp,mtx,roguepk,cashout,60,cp->unspendableCCaddr)) > cashout )
|
||||
CCchange = (inputsum - cashout);
|
||||
mtx.vout.push_back(CTxOut(cashout,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
|
||||
else fprintf(stderr,"couldnt find enough utxos\n");
|
||||
}
|
||||
mtx.vout.push_back(CTxOut(cashout,CScript() << ParseHex(HexStr(mypk)) << OP_CHECKSIG));
|
||||
}
|
||||
}
|
||||
mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange + (batonvalue-3*txfee),roguepk));
|
||||
if ( CCchange + (batonvalue-3*txfee) >= txfee )
|
||||
mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange + (batonvalue-3*txfee),roguepk));
|
||||
Myprivkey(mypriv);
|
||||
CCaddr1of2set(cp,roguepk,mypk,mypriv,myrogueaddr);
|
||||
CScript opret;
|
||||
@@ -1154,7 +1331,7 @@ UniValue rogue_highlander(uint64_t txfee,struct CCcontract_info *cp,cJSON *param
|
||||
|
||||
UniValue rogue_gameinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ),a(UniValue::VARR); int32_t i,n,gameheight,maxplayers,numvouts; uint256 txid; CTransaction tx; int64_t buyin; uint64_t seed; bits256 t; char myrogueaddr[64]; CPubKey mypk,roguepk;
|
||||
UniValue result(UniValue::VOBJ),a(UniValue::VARR); int32_t i,n,gameheight,maxplayers,numvouts; uint256 txid; CTransaction tx; int64_t buyin; uint64_t seed; bits256 t; char myrogueaddr[64],str[64]; CPubKey mypk,roguepk;
|
||||
result.push_back(Pair("name","rogue"));
|
||||
result.push_back(Pair("method","gameinfo"));
|
||||
if ( params != 0 && (n= cJSON_GetArraySize(params)) > 0 )
|
||||
@@ -1175,12 +1352,17 @@ UniValue rogue_gameinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
result.push_back(Pair("seed",(int64_t)seed));
|
||||
for (i=0; i<maxplayers; i++)
|
||||
{
|
||||
if ( CCgettxout(txid,i+1,1) < 0 )
|
||||
if ( CCgettxout(txid,i+1,1,0) < 0 )
|
||||
{
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
rogue_gameplayerinfo(cp,obj,txid,tx,i+1,maxplayers,myrogueaddr);
|
||||
a.push_back(obj);
|
||||
}
|
||||
else if ( 0 )
|
||||
{
|
||||
sprintf(str,"vout %d+1 is unspent",i);
|
||||
result.push_back(Pair("unspent",str));
|
||||
}
|
||||
}
|
||||
result.push_back(Pair("players",a));
|
||||
} else return(cclib_error(result,"couldnt find valid game"));
|
||||
@@ -1191,7 +1373,7 @@ UniValue rogue_gameinfo(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
|
||||
UniValue rogue_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
{
|
||||
UniValue result(UniValue::VOBJ),a(UniValue::VARR); int64_t buyin; uint256 txid,hashBlock; CTransaction tx; int32_t maxplayers,numplayers,gameheight,nextheight,vout,numvouts; CPubKey roguepk; char coinaddr[64];
|
||||
UniValue result(UniValue::VOBJ),a(UniValue::VARR); int64_t buyin; uint256 txid,hashBlock; CTransaction tx; int32_t openslots,maxplayers,numplayers,gameheight,nextheight,vout,numvouts; CPubKey roguepk; char coinaddr[64];
|
||||
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
|
||||
roguepk = GetUnspendable(cp,0);
|
||||
GetCCaddress(cp,coinaddr,roguepk);
|
||||
@@ -1206,8 +1388,8 @@ UniValue rogue_pending(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
continue;
|
||||
if ( rogue_isvalidgame(cp,gameheight,tx,buyin,maxplayers,txid,1) == 0 && nextheight <= gameheight+ROGUE_MAXKEYSTROKESGAP )
|
||||
{
|
||||
rogue_playersalive(numplayers,txid,maxplayers);
|
||||
if ( numplayers < maxplayers )
|
||||
rogue_playersalive(openslots,numplayers,txid,maxplayers,gameheight,tx);
|
||||
if ( openslots > 0 )
|
||||
a.push_back(txid.GetHex());
|
||||
}
|
||||
}
|
||||
@@ -1270,7 +1452,7 @@ UniValue rogue_games(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
{
|
||||
if ( rogue_isvalidgame(cp,gameheight,gametx,buyin,maxplayers,gametxid,0) == 0 )
|
||||
{
|
||||
if ( CCgettxout(txid,vout,1) < 0 )
|
||||
if ( CCgettxout(txid,vout,1,0) < 0 )
|
||||
b.push_back(gametxid.GetHex());
|
||||
else a.push_back(gametxid.GetHex());
|
||||
}
|
||||
@@ -1308,11 +1490,19 @@ UniValue rogue_setname(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
|
||||
|
||||
bool rogue_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx)
|
||||
{
|
||||
CScript scriptPubKey; std::vector<uint8_t> vopret; uint8_t *script,e,f,funcid; int32_t i,maxplayers,decoded=0,regslot,ind,err,dispflag,gameheight,score,numvouts; CTransaction vintx,gametx; CPubKey pk; uint256 hashBlock,gametxid,tokenid,batontxid,playertxid,ptxid; int64_t buyin; std::vector<uint8_t> playerdata,keystrokes; std::string symbol,pname;
|
||||
if ( strcmp(ASSETCHAINS_SYMBOL,"ROGUE") == 0 && height < 21274 )
|
||||
return(true);
|
||||
CScript scriptPubKey; std::vector<uint8_t> vopret; uint8_t *script,e,f,funcid,tokentx=0; int32_t i,maxplayers,enabled = 0,decoded=0,regslot,ind,err,dispflag,gameheight,score,numvouts; CTransaction vintx,gametx; CPubKey pk; uint256 hashBlock,gametxid,txid,tokenid,batontxid,playertxid,ptxid; int64_t buyin,cashout; std::vector<uint8_t> playerdata,keystrokes; std::string symbol,pname;
|
||||
if ( strcmp(ASSETCHAINS_SYMBOL,"ROGUE") == 0 )
|
||||
{
|
||||
if (height < 21274 )
|
||||
return(true);
|
||||
else if ( height > 50000 )
|
||||
enabled = 1;
|
||||
} else enabled = 1;
|
||||
if ( (numvouts= tx.vout.size()) > 1 )
|
||||
{
|
||||
txid = tx.GetHash();
|
||||
if ( txid == Parseuint256("1ae04dc0c5f2fca2053819a3a1b2efe5d355c34f58d6f16d59e5e2573e7baf7f") ) // osx rogue chain ht.50902
|
||||
enabled = 0;
|
||||
scriptPubKey = tx.vout[numvouts-1].scriptPubKey;
|
||||
GetOpReturnData(scriptPubKey,vopret);
|
||||
if ( vopret.size() > 2 )
|
||||
@@ -1321,6 +1511,7 @@ bool rogue_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const C
|
||||
funcid = script[1];
|
||||
if ( (e= script[0]) == EVAL_TOKENS )
|
||||
{
|
||||
tokentx = funcid;
|
||||
if ( (funcid= rogue_highlanderopretdecode(gametxid,tokenid,regslot,pk,playerdata,symbol,pname,scriptPubKey)) == 0 )
|
||||
{
|
||||
if ( (funcid= rogue_registeropretdecode(gametxid,tokenid,playertxid,scriptPubKey)) == 0 )
|
||||
@@ -1351,9 +1542,7 @@ bool rogue_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const C
|
||||
case 'R':
|
||||
if ( (funcid= rogue_registeropretdecode(gametxid,tokenid,playertxid,scriptPubKey)) != 'R' )
|
||||
{
|
||||
//fprintf(stderr,"height.%d couldnt decode register opret\n",height);
|
||||
//if ( height > 20000 )
|
||||
return eval->Invalid("couldnt decode register opret");
|
||||
return eval->Invalid("couldnt decode register opret");
|
||||
}
|
||||
// baton is created
|
||||
// validation is done below
|
||||
@@ -1361,22 +1550,13 @@ bool rogue_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const C
|
||||
case 'K':
|
||||
if ( (funcid= rogue_keystrokesopretdecode(gametxid,batontxid,pk,keystrokes,scriptPubKey)) != 'K' )
|
||||
{
|
||||
//fprintf(stderr,"height.%d couldnt decode keystrokes opret\n",height);
|
||||
//if ( height > 20000 )
|
||||
return eval->Invalid("couldnt decode keystrokes opret");
|
||||
return eval->Invalid("couldnt decode keystrokes opret");
|
||||
}
|
||||
// spending the baton proves it is the user if the pk is the signer
|
||||
return(true);
|
||||
break;
|
||||
case 'H': case 'Q':
|
||||
if ( (f= rogue_highlanderopretdecode(gametxid,tokenid,regslot,pk,playerdata,symbol,pname,scriptPubKey)) != funcid )
|
||||
{
|
||||
//fprintf(stderr,"height.%d couldnt decode H/Q opret\n",height);
|
||||
//if ( height > 20000 )
|
||||
return eval->Invalid("couldnt decode H/Q opret");
|
||||
}
|
||||
// spending the baton proves it is the user if the pk is the signer
|
||||
// rest of validation is done below
|
||||
// done in the next switch statement as there are some H/Q tx with playerdata which would skip this section
|
||||
break;
|
||||
default:
|
||||
return eval->Invalid("illegal rogue non-decoded funcid");
|
||||
@@ -1390,13 +1570,40 @@ bool rogue_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const C
|
||||
return(true);
|
||||
case 'H': // win
|
||||
case 'Q': // bailout
|
||||
// verify pk belongs to this tx
|
||||
if ( playerdata.size() > 0 )
|
||||
if ( (f= rogue_highlanderopretdecode(gametxid,tokenid,regslot,pk,playerdata,symbol,pname,scriptPubKey)) != funcid )
|
||||
{
|
||||
if ( rogue_playerdata_validate(ptxid,cp,playerdata,gametxid,pk) < 0 )
|
||||
//fprintf(stderr,"height.%d couldnt decode H/Q opret\n",height);
|
||||
//if ( height > 20000 )
|
||||
return eval->Invalid("couldnt decode H/Q opret");
|
||||
}
|
||||
// verify pk belongs to this tx
|
||||
if ( tokentx == 'c' )
|
||||
{
|
||||
if ( playerdata.size() > 0 )
|
||||
{
|
||||
//fprintf(stderr,"ht.%d gametxid.%s player.%s invalid playerdata[%d]\n",height,gametxid.GetHex().c_str(),ptxid.GetHex().c_str(),(int32_t)playerdata.size());
|
||||
} //else fprintf(stderr,"ht.%d playertxid.%s validated\n",height,ptxid.GetHex().c_str());
|
||||
static char laststr[512]; char cashstr[512];
|
||||
if ( rogue_playerdata_validate(&cashout,ptxid,cp,playerdata,gametxid,pk) < 0 )
|
||||
{
|
||||
sprintf(cashstr,"tokentx.(%c) decoded.%d ht.%d gametxid.%s player.%s invalid playerdata[%d]\n",tokentx,decoded,height,gametxid.GetHex().c_str(),ptxid.GetHex().c_str(),(int32_t)playerdata.size());
|
||||
if ( strcmp(laststr,cashstr) != 0 )
|
||||
{
|
||||
strcpy(laststr,cashstr);
|
||||
fprintf(stderr,"%s\n",cashstr);
|
||||
}
|
||||
if ( enabled != 0 )
|
||||
return eval->Invalid("mismatched playerdata");
|
||||
}
|
||||
if ( funcid == 'H' )
|
||||
cashout *= 2;
|
||||
sprintf(cashstr,"tokentx.(%c) decoded.%d ht.%d txid.%s %.8f vs vout2 %.8f",tokentx,decoded,height,txid.GetHex().c_str(),(double)cashout/COIN,(double)tx.vout[2].nValue/COIN);
|
||||
if ( strcmp(laststr,cashstr) != 0 )
|
||||
{
|
||||
strcpy(laststr,cashstr);
|
||||
fprintf(stderr,"%s\n",cashstr);
|
||||
}
|
||||
} else cashout = 10000;
|
||||
if ( enabled != 0 && tx.vout[2].nValue > cashout )
|
||||
return eval->Invalid("mismatched cashout amount");
|
||||
}
|
||||
if ( funcid == 'Q' )
|
||||
{
|
||||
|
||||
@@ -2859,7 +2859,7 @@ UniValue sudoku_solution(uint64_t txfee,struct CCcontract_info *cp,cJSON *params
|
||||
decode_hex((uint8_t *)&txid,32,txidstr);
|
||||
txid = revuint256(txid);
|
||||
result.push_back(Pair("txid",txid.GetHex()));
|
||||
if ( CCgettxout(txid,0,1) < 0 )
|
||||
if ( CCgettxout(txid,0,1,0) < 0 )
|
||||
result.push_back(Pair("error","already solved"));
|
||||
else if ( GetTransaction(txid,tx,hashBlock,false) != 0 && (numvouts= tx.vout.size()) > 1 )
|
||||
{
|
||||
|
||||
2411
src/cc/tetris.cpp
Normal file
2411
src/cc/tetris.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -289,15 +289,22 @@ void *chainparams_commandline(void *ptr)
|
||||
mainParams.pchMessageStart[2] = (ASSETCHAINS_MAGIC >> 16) & 0xff;
|
||||
mainParams.pchMessageStart[3] = (ASSETCHAINS_MAGIC >> 24) & 0xff;
|
||||
fprintf(stderr,">>>>>>>>>> %s: p2p.%u rpc.%u magic.%08x %u %u coins\n",ASSETCHAINS_SYMBOL,ASSETCHAINS_P2PPORT,ASSETCHAINS_RPCPORT,ASSETCHAINS_MAGIC,ASSETCHAINS_MAGIC,(uint32_t)ASSETCHAINS_SUPPLY);
|
||||
|
||||
if (ASSETCHAINS_ALGO != ASSETCHAINS_EQUIHASH)
|
||||
if (ASSETCHAINS_ALGO == ASSETCHAINS_VERUSHASH)
|
||||
{
|
||||
// this is only good for 60 second blocks with an averaging window of 45. for other parameters, use:
|
||||
// nLwmaAjustedWeight = (N+1)/2 * (0.9989^(500/nPowAveragingWindow)) * nPowTargetSpacing
|
||||
// nLwmaAjustedWeight = (N+1)/2 * (0.9989^(500/nPowAveragingWindow)) * nPowTargetSpacing
|
||||
mainParams.consensus.nLwmaAjustedWeight = 1350;
|
||||
mainParams.consensus.nPowAveragingWindow = 45;
|
||||
mainParams.consensus.powAlternate = uint256S("00000f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f");
|
||||
}
|
||||
else if (ASSETCHAINS_ALGO == ASSETCHAINS_VERUSHASHV1_1)
|
||||
{
|
||||
// this is only good for 60 second blocks with an averaging window of 45. for other parameters, use:
|
||||
// nLwmaAjustedWeight = (N+1)/2 * (0.9989^(500/nPowAveragingWindow)) * nPowTargetSpacing
|
||||
mainParams.consensus.nLwmaAjustedWeight = 1350;
|
||||
mainParams.consensus.nPowAveragingWindow = 45;
|
||||
mainParams.consensus.powAlternate = uint256S("0000000f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f");
|
||||
}
|
||||
|
||||
if (ASSETCHAINS_LWMAPOS != 0)
|
||||
{
|
||||
@@ -668,7 +675,7 @@ public:
|
||||
BOOST_STATIC_ASSERT(equihash_parameters_acceptable(N, K));
|
||||
nEquihashN = N;
|
||||
nEquihashK = K;
|
||||
|
||||
|
||||
genesis = CreateGenesisBlock(
|
||||
1296688602,
|
||||
uint256S("0x0000000000000000000000000000000000000000000000000000000000000009"),
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "clientversion.h"
|
||||
|
||||
#include "tinyformat.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
@@ -34,7 +35,7 @@
|
||||
* for both bitcoind and bitcoin-core, to make it harder for attackers to
|
||||
* target servers or GUI users specifically.
|
||||
*/
|
||||
const std::string CLIENT_NAME("MagicBean");
|
||||
const std::string CLIENT_NAME = GetArg("-ac_clientname", "MagicBean");
|
||||
|
||||
/**
|
||||
* Client version number
|
||||
|
||||
@@ -446,7 +446,7 @@ class CCoinsViewCache;
|
||||
/**
|
||||
* A reference to a mutable cache entry. Encapsulating it allows us to run
|
||||
* cleanup code after the modification is finished, and keeping track of
|
||||
* concurrent modifications.
|
||||
* concurrent modifications.
|
||||
*/
|
||||
class CCoinsModifier
|
||||
{
|
||||
@@ -503,7 +503,7 @@ protected:
|
||||
|
||||
/**
|
||||
* Make mutable so that we can "fill the cache" even from Get-methods
|
||||
* declared as "const".
|
||||
* declared as "const".
|
||||
*/
|
||||
mutable uint256 hashBlock;
|
||||
mutable CCoinsMap cacheCoins;
|
||||
|
||||
@@ -66,7 +66,7 @@ uint256 CalculateProofRoot(const char* symbol, uint32_t targetCCid, int kmdHeigh
|
||||
|
||||
int seenOwnNotarisations = 0;
|
||||
|
||||
bool txscl = IsTXSCL(symbol);
|
||||
int authority = GetSymbolAuthority(symbol);
|
||||
|
||||
for (int i=0; i<NOTARISATION_SCAN_LIMIT_BLOCKS; i++) {
|
||||
if (i > kmdHeight) break;
|
||||
@@ -90,13 +90,20 @@ uint256 CalculateProofRoot(const char* symbol, uint32_t targetCCid, int kmdHeigh
|
||||
|
||||
if (seenOwnNotarisations == 1) {
|
||||
BOOST_FOREACH(Notarisation& nota, notarisations) {
|
||||
if (IsTXSCL(nota.second.symbol) == txscl)
|
||||
if (nota.second.ccId == targetCCid)
|
||||
moms.push_back(nota.second.MoM);
|
||||
if (GetSymbolAuthority(nota.second.symbol) == authority)
|
||||
if (nota.second.ccId == targetCCid) {
|
||||
moms.push_back(nota.second.MoM);
|
||||
//fprintf(stderr, "added mom: %s\n",nota.second.MoM.GetHex().data());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Not enough own notarisations found to return determinate MoMoM
|
||||
destNotarisationTxid = uint256();
|
||||
moms.clear();
|
||||
return uint256();
|
||||
|
||||
end:
|
||||
return GetMerkleRoot(moms);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,18 @@
|
||||
|
||||
#include "cc/eval.h"
|
||||
|
||||
const int CROSSCHAIN_KOMODO = 1;
|
||||
const int CROSSCHAIN_TXSCL = 2;
|
||||
const int CROSSCHAIN_STAKED = 3;
|
||||
|
||||
typedef struct CrosschainAuthority {
|
||||
uint8_t notaries[64][33];
|
||||
int8_t size;
|
||||
int8_t requiredSigs;
|
||||
} CrosschainAuthority;
|
||||
|
||||
int GetSymbolAuthority(const char* symbol);
|
||||
bool CheckTxAuthority(const CTransaction &tx, CrosschainAuthority auth);
|
||||
|
||||
/* On assetchain */
|
||||
TxProof GetAssetchainProof(uint256 hash,CTransaction burnTx);
|
||||
|
||||
70
src/crosschain_authority.cpp
Normal file
70
src/crosschain_authority.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
#include "cc/eval.h"
|
||||
#include "crosschain.h"
|
||||
#include "notarisationdb.h"
|
||||
#include "notaries_staked.h"
|
||||
|
||||
int GetSymbolAuthority(const char* symbol)
|
||||
{
|
||||
if (strncmp(symbol, "TXSCL", 5) == 0)
|
||||
return CROSSCHAIN_TXSCL;
|
||||
if (is_STAKED(symbol) != 0) {
|
||||
//printf("RETURNED CROSSCHAIN STAKED AS TRUE\n");
|
||||
return CROSSCHAIN_STAKED;
|
||||
}
|
||||
//printf("RETURNED CROSSCHAIN KOMODO AS TRUE\n");
|
||||
return CROSSCHAIN_KOMODO;
|
||||
}
|
||||
|
||||
|
||||
bool CheckTxAuthority(const CTransaction &tx, CrosschainAuthority auth)
|
||||
{
|
||||
EvalRef eval;
|
||||
|
||||
if (tx.vin.size() < auth.requiredSigs) return false;
|
||||
|
||||
uint8_t seen[64] = {0};
|
||||
|
||||
BOOST_FOREACH(const CTxIn &txIn, tx.vin)
|
||||
{
|
||||
// Get notary pubkey
|
||||
CTransaction tx;
|
||||
uint256 hashBlock;
|
||||
if (!eval->GetTxUnconfirmed(txIn.prevout.hash, tx, hashBlock)) return false;
|
||||
if (tx.vout.size() < txIn.prevout.n) return false;
|
||||
CScript spk = tx.vout[txIn.prevout.n].scriptPubKey;
|
||||
if (spk.size() != 35) return false;
|
||||
const unsigned char *pk = &spk[0];
|
||||
if (pk++[0] != 33) return false;
|
||||
if (pk[33] != OP_CHECKSIG) return false;
|
||||
|
||||
// Check it's a notary
|
||||
for (int i=0; i<auth.size; i++) {
|
||||
if (!seen[i]) {
|
||||
if (memcmp(pk, auth.notaries[i], 33) == 0) {
|
||||
seen[i] = 1;
|
||||
goto found;
|
||||
} else {
|
||||
//printf("notary.%i is not valid!\n",i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
found:;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
const CrosschainAuthority auth_STAKED = [&](){
|
||||
CrosschainAuthority auth;
|
||||
auth.requiredSigs = (num_notaries_STAKED / 5);
|
||||
auth.size = num_notaries_STAKED;
|
||||
for (int n=0; n<auth.size; n++)
|
||||
for (size_t i=0; i<33; i++)
|
||||
sscanf(notaries_STAKED[n][1]+(i*2), "%2hhx", auth.notaries[n]+i);
|
||||
return auth;
|
||||
}();
|
||||
*/
|
||||
3
src/fiat/ilien
Executable file
3
src/fiat/ilien
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
./komodo-cli -ac_name=ILN $1 $2 $3 $4 $5 $6
|
||||
|
||||
2
src/fiat/iln
Executable file
2
src/fiat/iln
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
./komodo-cli -ac_name=ILN $1 $2 $3 $4 $5 $6
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user