diff --git a/src/app/fddev/configure/dump_genesis_features.py b/src/app/fddev/configure/dump_genesis_features.py new file mode 100644 index 0000000000..671221feda --- /dev/null +++ b/src/app/fddev/configure/dump_genesis_features.py @@ -0,0 +1,187 @@ +import base58 +import sys + +features = """16FMCmgLzCNNz6eTwGanbyN2ZxvTBSLuQ6DZhgeMshg +SAdVFw3RZvzbo6DvySbSdBnHN4gkzSTH9dSxesyKKPj +SVn36yVApPLYsa8koK3qUcy14zXDnqkNYWyUh1f4oK1 +St8k9dVXP97xT6faW24YmRSYConLbhsMJA4TJTBLmMT +Vo5siZ442SaZBKPXNocthiXysNviW4UYPwRFggmbgAp +capRxUrBjNkkCpjrJxPGfPaWijB7q3JoDfsWXAnt46r +dupPajaLy2SSn8ko42aZz4mHANDNrLe8Nw8VQgFecLa +eca6zf6JJRjQsYYPkBHF3N32MTzur4n2WL4QiiacPCL +meRgp4ArRPhD3KtCY9c5yAf2med7mBLsjKTPeVUHqBL +nWBqjr3gpETbiaVj3CBJ3HFC5TMdnJDGt21hnvSTvVZ +noRuG2kzACwgaY7TVmLRnUNPLKNVQE1fb7X55YWBehp +prpFrMtgNmzaNzkPJg9o753fVvbHKqNrNTm76foJ2wm +qywiJyZmqTKspFg2LeuUHqcA5nNvBgobqb9UprywS9N +sTKz343FM8mqtyGvYWvbLpTThw3ixRM4Xk8QvZ985mw +zk1snxsc6Fh3wsGNbbHAJNHiJoYgF29mMnTSusGx5EJ +zkNLP7EQALfC1TYeB3biDU7akDckj8iPkvh9y2Mt2K3 +21AWDosvp3pBamFW91KB35pNoaoZVTM7ess8nr2nt53B +25vqsfjk7Nv1prsQJmA4Xu1bN61s8LXCBGUPp8Rfy1UF +265hPS8k8xJ37ot82KEgjRunsUp5w4n4Q4VwwiN9i9ps +28s7i3htzhahXQKqmS2ExzbEoUypg9krwvtK2M9UWXh9 +2HmTkCj9tXuPE4ueHzdD7jPeMf9JGCoZh5AsyoATiWEe +2KKG3C6RBnxQo9jVVrbzsoSh41TDXLK7gBc9gduyxSzW +2R72wpcQ7qV7aTJWUumdn8u5wmmTyXbK7qzEy7YSAgyY +2h63t332mGCCsWK2nqqqHhN4U9ayyqhLVFvczznHDoTZ +2jXx2yDmGysmBKfKYNgLj2DQyAQv6mMk2BPh4eSbyB4H +2oXpeh141pPZCTCFHBsvCwG2BtaHZZAtrVhwaxSy6brS +2ry7ygxiYURULZCrypHhveanvP5tzZ4toRwVp89oCNSj +36PRUK2Dz6HWYdG9SpjeAsF5F3KxnFCakA2BZMbtMhSb +3BX6SBeEBibHaVQXywdkcgyUk6evfYZkHdztXiDtEpFS +3E3jV7v9VcdJL8iYZUMax9DiDno8j7EWUVbhm9RtShj2 +3KZZ6Ks1885aGBQ45fwRcPXVBCtzUvxhUTkwKMR41Tca +3NKRSwpySNwD3TvP5pHnRmkAQRsdkXWRr1WaQh8p4PWX +3XgNukcZWf9o3HdA3fpJbm94XFc4qpvTXc8h1wxYwiPi +3aJdcZqxoLpSBxgeYGjPwaYS1zzcByxUDqJkbzWAH1Zb +3ccR6QpxGYsAbWyfevEtBNGfWV4xBffxRj2tD6A9i39F +3gtZPqvPpsbXZVCx6hceMfWxtsmrjMzmg8C7PLKSxS2d +3u3Er5Vc2jVcwz4xr2GJeSAXT3fAj6ADHZ4BJMZiScFd +3uFHb9oKdGfgZGJK9EHaAXN4USvnQtAFC13Fh5gGFS5B +3uRVPBpyEJRo1emLCrq38eLRFGcu6uKSpUXqGvU8T7SZ +41tVp5qR1XwWRt5WifvtSQyuxtqQWJgEK8w91AtBqSwP +437r62HoAdUb63amq3D7ENnBLDhHT2xY8eFkLJYVKK4x +4ApgRX3ud6p7LNMJmsuaAcZY5HWctGPr5obAsjB3A54d +4Di3y24QFLt5QEUPZtbnjyfQKfm6ZMTfa6Dw1psfoMKU +4EJQtF2pkRyawwcTVfQutzq4Sa5hRhibF6QAK1QXhtEX +4RWNif6C2WCNiKVW7otP4G7dkmkHGyKQWRpuZ1pxKU5m +4UDcAfQ6EcA6bdcadkeHpkarkhZGJ7Bpq7wTAiRMjkoi +4d5AKtxoh93Dwm1vHXUU3iRATuMndx1c431KgT2td52r +4kpdyrcj5jS47CZb2oJGfVxjYbsMm2Kx97gFyZrxxwXz +4yuaYAj2jGMGTh1sSmi4G2eFscsDq8qjugJXZoBN6YEa +54KAoNiUERNoWWUhTWWwXgym94gzoXFVnHyQwPA18V9A +5GpmAKxaGsWWbPp4bNXFLJxZVvG92ctxf7jQnzTQjF3n +5Pecy6ie6XGm22pc9d4P9W5c31BugcFBuy6hsP2zkETv +5TuppMutoyzhUSfuYdhgzD47F92GL1g89KpCZQKqedxP +5ZCcFAzJ1zsFKe1KSZa9K92jhx7gkcKj97ci2DBo1vwj +5ekBxc8itEnPv4NzGJtr8BVVQLNMQuLMNQQj7pHoLNZ9 +5wAGiy15X1Jb2hkHnPDCM8oB9V42VNA9ftNVFK84dEgv +5x3825XS7M2A3Ekbn5VGGkvFoAg5qrRWkTrY4bARP1GL +6RvdSWHh8oh72Dp7wMTS2DBkf3fRPtChfNrAo3cZZoXJ +6YsBCejwK96GZCkJ6mkZ4b68oP63z2PLoQmWjC7ggTqZ +6iyggb5MTcsvdcugX7bEKbHV8c6jdLbpHwkncrgLMhfo +6ppMXNYLhVd7GcsZ5uV11wQEW7spppiMVfqQv5SXhDpX +6tRxEYKuy2L5nnv5bgn7iT28MxUbYxp5h7F3Ncf1exrT +6uaHcKPGUy4J7emLBgUTeufhJdiwhngW6a1R9B7c2ob9 +74CoWuBmt3rUVUrCb2JiSTvh6nXyBWUsK4SaMj3CtE3T +75m6ysz33AfLA5DDEzWM1obBrnPQRSsdVQ2nRmc8Vuu1 +79HWsX9rpnnJBPcdNURVqygpMAfxdrAirzAGAVmf92im +7GUcYgq4tVtaqNCKT3dho9r4665Qp5TxCZ27Qgjx3829 +7Vced912WrRnfjaiKRiNBcbuFw7RrnLv3E3z95Y4GTNc +7WeS1vfPRgeeoXArLh7879YcB9mgE9ktjPDtajXeWfXn +7XRJcS5Ud5vxGB54JbK9N2vBZVwnwdBNeJW1ibRgD9gx +7axKe5BTYBDD87ftzWbk5DfzWMGyRvqmWTduuo22Yaqy +7g9EUwj4j7CS21Yx1wvgWLjSZeh5aPq8x9kpoPwXM8n8 +7rcw5UtqgDTBBv2EcynNfYckgdAaH1MAsCjKgXMkN7Ri +7txXZZD6Um59YoLMF7XUNimbMjsqsWhc7g2EniiTrmp1 +812kqX67odAp5NFwM8D2N24cku7WTm9CHUTFUXaDkWPn +8199Q2gMD2kwgfopK5qqVWuDbegLgpuFUFHCcUJQDN8b +86HpNqzutEZwLcPxS6EHDcMNYWk6ikhteg9un7Y2PBKE +8C8MCtsab5SsfammbzvYz65HHauuUYdbY2DZ4sznH6h5 +8FdwgyHFEjhAdjWfV2vfqk7wA1g9X3fQpKH7SBpEv3kC +8We4E7DPwF2WfAN8tRTtWQNhi98B99Qpuj7JoZ3Aikgg +8Zs9W7D9MpSEtUWSQdGniZk2cNmV22y6FLJwCx53asme +8aXvSuopd1PUj7UhehfXJRg6619RHp8ZvwTyyJHdUYsj +8kEuAshXLsgkUEdcFVLqrjCGGHVWFW99ZZpxvAzzMtBp +8oBxsYqnCvUTGzgEpxPcnVf7MLbWWPYddE33PftFeBBd +8pgXCMNXC8qyEFypuwpXyRxLXZdpM4Qo72gJ6k87A6wL +8sKQrMQoUHtQSUP83SPG4ta2JDjSAiWs7t5aJ9uEd6To +98std1NSHqXi9WYvFShfVepRdCoq1qvsp8fsR2XZtG8g +9LZdXeKGeBV6hRLdxS1rHbHoEUsKqesCC2ZAPTPKJAbK +9gxu85LYRAcZL38We8MYJ4A9AwgBBPtVBAqebMcT1241 +9k5ijzTbYPtjzu8wj2ErH9v45xecHzQ1x4PMYMMxFgdM +9kdtFSrXHQg3hKkbXkQ6trJ3Ja1xpJ22CTFSNAciEwmL +9onWzzvCzNC2jfhxxeqRgs5q7nFAAKpCUvkj6T6GJK9i +A16q37opZdQMCbe5qJ6xpBB9usykfv8jZaMkxvZQi4GJ +A8xyMHZovGXFkorFqEmVH2PKGLiBip5JD7jt4zsUWo4H +ALBk3EWdeAg2WAGf6GPDUf1nynyNqCdEVmgouG7rpuCj +AVZS3ZsN4gi6Rkx2QUibYuSJG3S6QHib7xCYhG6vGJxU +B9cdB55u4jQsDNsdTK525yE9dmSc5Ga7YBaBrDFvEhM9 +BKCPBQQBZqggVnFso5nQ8rQ4RwwogYwjuUt9biBjxwNF +BL99GYhdjjcv6ys22C9wPgn2aTVERDbPHHo4NbS3hgp7 +BTWmtJC8U5ZLMbBUUA1k6As62sYjPEjAiNAT55xYGdJU +BUS12ciZ5gCoFafUHWW8qaFMMtwFQGVxjsDheWLdqBE2 +BcWknVcgvonN8sL4HE4XFuEVgfcee5MwxWPAgP6ZV89X +BiCU7M5w8ZCMykVSyhZ7Q3m2SWoR2qrEQ86ERcDX77ME +Bj2jmUsM2iRhfdLLDSTkhM5UQRQvQHm57HSmPibPtEyu +BkFDxiJQWZXGTZaJQxH7wVEHkAmwCgSEVkrvswFfRJPD +BrTR9hzw4WBGFP65AJMbpAo64DcA3U6jdPSga9fMV5cS +BsKLKAn1WM4HVhPRDsjosmqSg2J8Tq5xP2s2daDS6Ni4 +BzBBveUDymEYoYzcMWNQCx3cd4jQs7puaVFHLtsbB6fm +C5fh68nJ7uyKAuYZg2x9sEQ5YrVf3dkW6oojNBSc3Jvo +CBkDroRDqm8HwHe6ak9cguPjUomrASEkfmxEaZ5CNNxz +CCu4boMmfLuqcmfTLPHQiUo22ZdUsXjgzPAURYaWt1Bw +CE2et8pqgyQMP2mQRg3CgvX8nJBKUArMu3wfiQiQKY1y +CFK1hRCNy8JJuAAY8Pb2GjLFNdCThS2qwZNe3izzBMgn +CGB2jM8pwZkeeiXQ66kBMyBR6Np61mggL7XUsmLjVcrw +Cdkc8PPTeTNUPoZEfCY5AyetUrEdkZtNPMgz58nqyaHD +CpkdQmspsaZZ8FVAouQTtTWZkc8eeQ7V3uj7dWz543rZ +CveezY6FDLVBToHDcvJRmtMouqzsmj4UXYh5ths5G5Uv +D2aip4BBr8NPWtU9vLrwrBvbuaQ8w1zV38zFLxx4pfBV +D31EFnLgdiysi84Woo3of4JMu7VmasUS3Z7j9HYXCeLY +D4jsDcXaqdW8tDAWn8H4R25Cdns2YwLneujSL1zvjW6R +DT4n6ABDqs6w4bnfwrXT9rsprcPf6cdDga1egctaPkLC +DTVTkmw3JSofd8CJVJte8PXEbxNQ2yZijvVr3pe2APPj +DdLwVYuvDz26JohmgSbA7mjpJFgX5zP2dkp8qsF2C33V +DhsYfRjxfnh2g7HKJYSzT79r74Afa1wbHkAgHndrA1oy +DpJREPyuMZ5nDfU6H3WTqSqUFSXAfw8u7xqmWtEwJDcP +Ds87KVeqhbv7Jw8W6avsS1mqz3Mw5J3pRTpPoDQ2QdiJ +DwScAzPUjuv65TMbDnFY7AgwmotzWy3xpEJMXM3hZFaB +E3PHP7w8kB7np3CTQ1qQ2tW3KCtjRSXBQgW9vM2mWv2Y +E5JiFDQCwyC6QfT9REFyMpfK2mHcmv1GUDySU1Ue7TYv +E8MkiWZNNPGU6n55jkGzyj8ghUmjCHRmDFdYYFYHxWhQ +EBeznQDjcPG8491sFsKZYBi5S5jTVXMpAKNDJMQPS2kq +EBq48m8irRKuE7ZnMTLvLg2UuGSqhe8s8oMqnmja1fJw +EJJewYSddEEtSZHiqugnvhQHiWyZKjkFDQASd7oKSagn +EMX9Q7TVFAmQ9V1CggAkhMzhXSg8ECp7fHrWQX2G1chf +EVW9B5xD9FFK7vw1SBARwMA4s5eRo5eKJdKpsBikzKBz +EWme9uFqfy1ikK1jhJs8fM5hxWnK336QJpbscNtizkTU +EYVpEP7uzH1CoXzbD6PubGhYmnxRXPeq3PPsm1ba3gpo +EaQpmC6GtRssaZ3PCUM5YksGqUdMLeZ46BQXYtHYakDS +EenyoWx9UMXYKpR8mW5Jmfmy2fRjzUtM7NduYMY8bx33 +EfhYd3SafzGT472tYQDUc4dPd2xdEfKs5fwkowUgVt4W +FKAcEvNgSY79RpqsPNUV5gDyumopH4cEHqUxyfm8b8Ap +FKu1qYwLQSiehz644H6Si65U5ZQ2cp9GxsyFUfYcuADv +FL9RsQA6TVUoh5xJQ9d936RHSebA1NLQqe3Zv9sXZRpr +FQnc7U4koHqWgRvFaBJjZnV8VPg6L6wWK33yJeDp4yvV +FToKNBYyiF4ky9s8WsmLBXHCht17Ek7RXaLZGHzzQhJ1 +FaTa17gVKoqbh38HcfiQonPsAaQViyDCCSg71AubYZw8 +FaTa4SpiaSNH44PGC4z8bnGVTkSRYaWvrBs3KTu8XQQq +Fab5oP3DmsLYCiQZXdjyqT3ukFFPrsmqhXU4WU1AWVVF +Ff8b1fBeB86q8cjq47ZhsQLgv5EkHu3G1C99zjUfAzrq +Ffswd3egL3tccB6Rv3XY6oqfdzn913vUcjCSnpvCKpfx +Ftok2jhqAqxUWEiCVRrfRs9DPppWP8cgTB7NQNKL88mS +Ftok4njE8b7tDffYkC5bAbCaQv5sL6jispYrprzatUwN +G6ANXD6ptCSyNd9znZm7j4dEczAJCfx7Cy43oBx3rKHJ +G6vbf1UBok8MWb8m25ex86aoQHeKTzDKzuZADHkShqm6 +G74BkWBzmsByZ1kxHy44H3wjwp5hp7JbrGRuDpco22tY +GDH5TVdbTPUpRnXaRyQqiKUa7uZAbZ28Q2N9bhbKoMLm +GE7fRxmW46K6EmCD9AMZSbnaJ2e3LfqCZzdHi9hmYAgi +GQALDaC48fEhZGWRj9iL5Q889emJKcj3aCvHF7VCbbF4 +GTUMCZ8LTNxVfxdrw7ZsDFTxXb7TutYkzJnFwinpE6dg +GV49KKQdBNaiv2pgqhS2Dy3GWYJGXMTVYbYkdk91orRy +GaBtBJvmS4Arjj5W1NmFcyvPjsHN38UGYDq2MDwbs9Qu +Gea3ZkK2N4pHuVZVxWcnAtS6UEDdyumdYt4pFcKjA3ar +GmC19j9qLn2RFk5NduX6QXaDhVpGncVVBzyM8e9WMz2F +GmuBvtFb2aHfSfMXpuFeWZGHyDeCLPS79s48fmCWCfM5 +GvDsGDkH5gyzwpDhxNixx8vtx1kwYHH13RiNAPw27zXb +GwtDQBghCTBgmX2cpEGNPxTEBUTQRaDMGTr5qychdGMj +Gz1aLrbeQ4Q6PTSafCZcGWZXz91yVRi7ASFzFEr1U4sa +H3kBSaKdeiUsyHmeHqjJYNc27jesXZ6zWj3zWkowQbkV +HFpdDDNQjvcXnXKec697HDDsyk6tFoWS2o8fkxuhQZpL +HH3MUYReL2BvqqA3oEcAa7txju5GY6G4nxJ51zvsEjEZ +HTTgmruMYRZEntyL3EdCDdnS6e4D5wRq1FA7kQsb66qq +HTW2pSyErTj4BV6KBM9NZ9VBUJVxt7sacNWcf76wtzb3 +HooKD5NC9QNxk25QuzCssB8ecrEzGt6eXEPBUxWp1LaR +Hr1nUA9b7NJ6eChS26o7Vi8gYYDDwWD3YeBfzJkTbU86 +HxrEu1gXuH7iD3Puua1ohd5n4iUKJyFNtNxk9DVJkvgr +HyrbKftCdJ5CrUfEti6x26Cj7rZLNe32weugk7tLcWb8 +J2QdYx8crLbTVK8nur1jeLsmc3krDbfjoxoea2V1Uy5Q +J4HFT8usBxpcF63y46t1upYobJgChmKyZPm5uTBRg25Z +JAN1trEUEtZjgXYzNBYHU9DYd7GnThhXfFP7SzPXkPsG""".split() + +with open('genesis_features.bin', 'wb') as f: + for feature in features: + f.write(base58.b58decode(feature)) + diff --git a/src/app/fddev/configure/genesis.c b/src/app/fddev/configure/genesis.c index 621b958e5a..edbe94539c 100644 --- a/src/app/fddev/configure/genesis.c +++ b/src/app/fddev/configure/genesis.c @@ -17,6 +17,8 @@ #define NAME "genesis" +FD_IMPORT( feature_gate, "src/app/fddev/configure/genesis_features.bin", fd_pubkey_t, 5, "" ); + /* estimate_hashes_per_tick approximates the PoH hashrate of the current tile. Spins PoH hashing for estimate_dur_ns nanoseconds. Returns the hashes per tick achieved, where tick_mhz is the target tick rate @@ -45,6 +47,7 @@ estimate_hashes_per_tick( ulong tick_mhz, return (ulong)hashes_per_tick; } + /* Create a new genesis.bin file contents into the provided blob buffer and return the size of the buffer. Will abort on error if the provided buffer is not large enough. */ @@ -53,39 +56,34 @@ static ulong create_genesis( config_t * const config, uchar * blob, ulong blob_sz ) { + + fd_genesis_options_t options[1]; + /* Read in keys */ uchar const * identity_pubkey_ = fd_keyload_load( config->consensus.identity_path, 1 ); if( FD_UNLIKELY( !identity_pubkey_ ) ) FD_LOG_ERR(( "Failed to load identity key" )); - fd_pubkey_t identity_pubkey; memcpy( identity_pubkey.key, identity_pubkey_, 32 ); + memcpy( options->identity_pubkey.key, identity_pubkey_, 32 ); char file_path[ PATH_MAX ]; FD_TEST( fd_cstr_printf_check( file_path, PATH_MAX, NULL, "%s/faucet.json", config->scratch_directory ) ); uchar const * faucet_pubkey_ = fd_keyload_load( file_path, 1 ); if( FD_UNLIKELY( !faucet_pubkey_ ) ) FD_LOG_ERR(( "Failed to load faucet key" )); - fd_pubkey_t faucet_pubkey; memcpy( faucet_pubkey.key, faucet_pubkey_, 32 ); + memcpy( options->faucet_pubkey.key, faucet_pubkey_, 32 ); FD_TEST( fd_cstr_printf_check( file_path, PATH_MAX, NULL, "%s/stake-account.json", config->scratch_directory ) ); uchar const * stake_pubkey_ = fd_keyload_load( file_path, 1 ); if( FD_UNLIKELY( !stake_pubkey_ ) ) FD_LOG_ERR(( "Failed to load stake account key" )); - fd_pubkey_t stake_pubkey; memcpy( stake_pubkey.key, stake_pubkey_, 32 ); + memcpy( options->stake_pubkey.key, stake_pubkey_, 32 ); FD_TEST( fd_cstr_printf_check( file_path, PATH_MAX, NULL, "%s/vote-account.json", config->scratch_directory ) ); uchar const * vote_pubkey_ = fd_keyload_load( file_path, 1 ); if( FD_UNLIKELY( !vote_pubkey_ ) ) FD_LOG_ERR(( "Failed to load vote account key" )); - fd_pubkey_t vote_pubkey; memcpy( vote_pubkey.key, vote_pubkey_, 32 ); - - uchar pod_mem[ 8192 ]; - uchar * pod = fd_pod_join( fd_pod_new( pod_mem, sizeof(pod_mem) ) ); + memcpy( options->vote_pubkey.key, vote_pubkey_, 32 ); - fd_pod_insert_pubkey( pod, "identity.pubkey", &identity_pubkey ); - fd_pod_insert_pubkey( pod, "faucet.pubkey", &faucet_pubkey ); - fd_pod_insert_pubkey( pod, "stake.pubkey", &stake_pubkey ); - fd_pod_insert_pubkey( pod, "vote.pubkey", &vote_pubkey ); - fd_pod_insert_ulong( pod, "creation_time", (ulong)fd_log_wallclock() / (ulong)1e9 ); - - fd_pod_insert_ulong( pod, "faucet.balance", 500000000000000000UL ); + options->creation_time = (ulong)fd_log_wallclock() / (ulong)1e9; + options->faucet_balance = 500000000000000000UL; /* Set up PoH config */ @@ -102,24 +100,35 @@ create_genesis( config_t * const config, hashes_per_tick = FD_SYSVAR_CLOCK_DEFAULT_HASHES_PER_TICK; } - fd_pod_insert_ulong( pod, "hashes_per_tick", hashes_per_tick ); + options->hashes_per_tick = hashes_per_tick; } else if( 1UL==config->development.genesis.hashes_per_tick ) { - /* do not set hashes_per_tick field */ + /* set hashes_per_tick field to 0, which means sleep mode */ + options->hashes_per_tick = 0UL; } else { /* set hashes_per_tick to the specified value */ - fd_pod_insert_ulong( pod, "hashes_per_tick", config->development.genesis.hashes_per_tick ); + options->hashes_per_tick = config->development.genesis.hashes_per_tick; } - fd_pod_insert_ulong( pod, "ticks_per_slot", config->development.genesis.ticks_per_slot ); - fd_pod_insert_ulong( pod, "target_tick_µs", config->development.genesis.target_tick_duration_micros ); + options->ticks_per_slot = config->development.genesis.ticks_per_slot; + options->target_tick_duration_micros = config->development.genesis.target_tick_duration_micros; + + options->fund_initial_accounts = config->development.genesis.fund_initial_accounts; + options->fund_initial_amount_lamports = config->development.genesis.fund_initial_amount_lamports; + + /* Enable features gates */ + ulong feature_gate_cnt = feature_gate_sz/32UL; + FD_LOG_INFO(( "Enabling %lu feature gates", feature_gate_cnt )); + for( ulong i=0UL; idevelopment.genesis.fund_initial_accounts ); - fd_pod_insert_ulong( pod, "default_funded.balance", config->development.genesis.fund_initial_amount_lamports ); /* Serialize blob */ @@ -128,7 +137,7 @@ create_genesis( config_t * const config, fd_scratch_attach( scratch_smem, scratch_fmem, sizeof(scratch_smem), sizeof(scratch_fmem)/sizeof(ulong) ); - ulong blob_len = fd_genesis_create( blob, blob_sz, pod ); + ulong blob_len = fd_genesis_create( blob, blob_sz, options, feature_gate, feature_gate_sz/32UL ); if( FD_UNLIKELY( !blob_sz ) ) FD_LOG_ERR(( "Failed to create genesis blob" )); FD_LOG_DEBUG(( "Created genesis blob (sz=%lu)", blob_len )); diff --git a/src/app/fddev/configure/genesis_features.bin b/src/app/fddev/configure/genesis_features.bin new file mode 100644 index 0000000000..cae1a3061c Binary files /dev/null and b/src/app/fddev/configure/genesis_features.bin differ diff --git a/src/flamenco/genesis/fd_genesis_create.c b/src/flamenco/genesis/fd_genesis_create.c index a8c734394e..6150d66143 100644 --- a/src/flamenco/genesis/fd_genesis_create.c +++ b/src/flamenco/genesis/fd_genesis_create.c @@ -14,9 +14,11 @@ #include "../../util/tmpl/fd_sort.c" static ulong -genesis_create( void * buf, - ulong bufsz, - uchar const * pod ) { +genesis_create( void * buf, + ulong bufsz, + fd_genesis_options_t const * options, + fd_pubkey_t const * feature_gates, + ulong feature_gate_cnt ) { # define REQUIRE(c) \ do { \ @@ -26,32 +28,21 @@ genesis_create( void * buf, } \ } while(0); - fd_pubkey_t identity_pubkey; - REQUIRE( fd_pod_query_pubkey( pod, "identity.pubkey", &identity_pubkey ) ); - - fd_pubkey_t faucet_pubkey; - REQUIRE( fd_pod_query_pubkey( pod, "faucet.pubkey", &faucet_pubkey ) ); - - fd_pubkey_t stake_pubkey; - REQUIRE( fd_pod_query_pubkey( pod, "stake.pubkey", &stake_pubkey ) ); - - fd_pubkey_t vote_pubkey; - REQUIRE( fd_pod_query_pubkey( pod, "vote.pubkey", &vote_pubkey ) ); - fd_genesis_solana_t genesis[1]; fd_genesis_solana_new( genesis ); genesis->cluster_type = 3; /* development */ - genesis->creation_time = fd_pod_query_ulong( pod, "creation_time", 0UL ); - genesis->ticks_per_slot = fd_pod_query_ulong( pod, "ticks_per_slot", 0UL ); + genesis->creation_time = options->creation_time; + genesis->ticks_per_slot = options->ticks_per_slot; REQUIRE( genesis->ticks_per_slot ); - ulong hashes_per_tick = fd_pod_query_ulong( pod, "hashes_per_tick", 0UL ); - genesis->poh_config.has_hashes_per_tick = !!hashes_per_tick; - genesis->poh_config.hashes_per_tick = hashes_per_tick; + genesis->unused = 1024UL; /* match Anza genesis byte-for-byte */ - ulong target_tick_micros = fd_pod_query_ulong( pod, "target_tick_µs", 0UL ); + genesis->poh_config.has_hashes_per_tick = !!options->hashes_per_tick; + genesis->poh_config.hashes_per_tick = options->hashes_per_tick; + + ulong target_tick_micros = options->target_tick_duration_micros; REQUIRE( target_tick_micros ); genesis->poh_config.target_tick_duration = (fd_rust_duration_t) { .seconds = target_tick_micros / 1000000UL, @@ -61,11 +52,11 @@ genesis_create( void * buf, /* Create fee rate governor */ genesis->fee_rate_governor = (fd_fee_rate_governor_t) { - .target_lamports_per_signature = 10000UL, - .target_signatures_per_slot = 20000UL, - .min_lamports_per_signature = 0UL, - .max_lamports_per_signature = 0UL, - .burn_percent = 50, + .target_lamports_per_signature = 10000UL, + .target_signatures_per_slot = 20000UL, + .min_lamports_per_signature = 5000UL, + .max_lamports_per_signature = 100000UL, + .burn_percent = 50, }; /* Create rent configuration */ @@ -76,6 +67,17 @@ genesis_create( void * buf, .burn_percent = 50, }; + /* Create inflation configuration */ + + genesis->inflation = (fd_inflation_t) { + .initial = 0.08, + .terminal = 0.015, + .taper = 0.15, + .foundation = 0.05, + .foundation_term = 7.0, + .__unused = 0.0, + }; + /* Create epoch schedule */ /* TODO The epoch schedule should be configurable! */ @@ -90,11 +92,11 @@ genesis_create( void * buf, /* Create faucet account */ fd_pubkey_account_pair_t const faucet_account = { - .key = faucet_pubkey, + .key = options->faucet_pubkey, .account = { - .lamports = fd_pod_query_ulong( pod, "faucet.balance", 1000000000UL /* 1 SOL */ ), + .lamports = options->faucet_balance, .owner = fd_solana_system_program_id, - .rent_epoch = ULONG_MAX + .rent_epoch = 0UL } }; ulong const faucet_account_index = genesis->accounts_len++; @@ -102,11 +104,11 @@ genesis_create( void * buf, /* Create identity account (vote authority, withdraw authority) */ fd_pubkey_account_pair_t const identity_account = { - .key = identity_pubkey, + .key = options->identity_pubkey, .account = { .lamports = 500000000000UL /* 500 SOL */, .owner = fd_solana_system_program_id, - .rent_epoch = ULONG_MAX + .rent_epoch = 0UL } }; ulong const identity_account_index = genesis->accounts_len++; @@ -122,8 +124,8 @@ genesis_create( void * buf, fd_vote_state_versioned_new_disc( vsv, fd_vote_state_versioned_enum_current ); fd_vote_state_t * vs = &vsv->inner.current; - vs->node_pubkey = identity_pubkey; - vs->authorized_withdrawer = identity_pubkey; + vs->node_pubkey = options->identity_pubkey; + vs->authorized_withdrawer = options->identity_pubkey; vs->commission = 100; vs->authorized_voters.pool = fd_vote_authorized_voters_pool_alloc ( fd_scratch_virtual() ); vs->authorized_voters.treap = fd_vote_authorized_voters_treap_alloc( fd_scratch_virtual() ); @@ -132,8 +134,8 @@ genesis_create( void * buf, fd_vote_authorized_voters_pool_ele_acquire( vs->authorized_voters.pool ); *ele = (fd_vote_authorized_voter_t) { .epoch = 0UL, - .pubkey = identity_pubkey, - .prio = identity_pubkey.ul[0], /* treap prio */ + .pubkey = options->identity_pubkey, + .prio = options->identity_pubkey.ul[0], /* treap prio */ }; fd_vote_authorized_voters_treap_ele_insert( vs->authorized_voters.treap, ele, vs->authorized_voters.pool ); @@ -161,13 +163,13 @@ genesis_create( void * buf, stake->meta = (fd_stake_meta_t) { .rent_exempt_reserve = stake_state_min_bal, .authorized = { - .staker = identity_pubkey, - .withdrawer = identity_pubkey, + .staker = options->identity_pubkey, + .withdrawer = options->identity_pubkey, } }; stake->stake = (fd_stake_t) { .delegation = (fd_delegation_t) { - .voter_pubkey = vote_pubkey, + .voter_pubkey = options->vote_pubkey, .stake = fd_ulong_max( stake_state_min_bal, 500000000UL /* 0.5 SOL */ ), .activation_epoch = ULONG_MAX, /* bootstrap stake denoted with ULONG_MAX */ .deactivation_epoch = ULONG_MAX @@ -183,9 +185,10 @@ genesis_create( void * buf, /* Allocate the account table */ - ulong default_funded_idx = genesis->accounts_len; - ulong default_funded_cnt = fd_pod_query_ulong( pod, "default_funded.cnt", 0UL ); - genesis->accounts_len += default_funded_cnt; + ulong default_funded_cnt = options->fund_initial_accounts; + + ulong default_funded_idx = genesis->accounts_len; genesis->accounts_len += default_funded_cnt; + ulong feature_gate_idx = genesis->accounts_len; genesis->accounts_len += feature_gate_cnt; genesis->accounts = fd_scratch_alloc( alignof(fd_pubkey_account_pair_t), genesis->accounts_len * sizeof(fd_pubkey_account_pair_t) ); @@ -194,29 +197,29 @@ genesis_create( void * buf, genesis->accounts[ faucet_account_index ] = faucet_account; genesis->accounts[ identity_account_index ] = identity_account; genesis->accounts[ stake_account_index ] = (fd_pubkey_account_pair_t) { - .key = stake_pubkey, + .key = options->stake_pubkey, .account = (fd_solana_account_t) { .lamports = stake_state_min_bal, .data_len = FD_STAKE_STATE_V2_SZ, .data = stake_data, .owner = fd_solana_stake_program_id, - .rent_epoch = ULONG_MAX + .rent_epoch = 0UL } }; genesis->accounts[ vote_account_index ] = (fd_pubkey_account_pair_t) { - .key = vote_pubkey, + .key = options->vote_pubkey, .account = (fd_solana_account_t) { .lamports = vote_min_bal, .data_len = FD_VOTE_STATE_V3_SZ, .data = vote_state_data, .owner = fd_solana_vote_program_id, - .rent_epoch = ULONG_MAX + .rent_epoch = 0UL } }; /* Set up primordial accounts */ - ulong default_funded_balance = fd_pod_query_ulong( pod, "default_funded.balance", 0UL ); + ulong default_funded_balance = options->fund_initial_amount_lamports; for( ulong j=0UL; jaccounts[ default_funded_idx+j ]; @@ -229,9 +232,28 @@ genesis_create( void * buf, .lamports = default_funded_balance, .data_len = 0UL, .owner = fd_solana_system_program_id, - .rent_epoch = ULONG_MAX + .rent_epoch = 0UL + }; + } + +#define FEATURE_ENABLED_SZ 9UL + static const uchar feature_enabled_data[ FEATURE_ENABLED_SZ ] = { 1, 0, 0, 0, 0, 0, 0, 0, 0 }; + ulong default_feature_enabled_balance = fd_rent_exempt_minimum_balance2( &genesis->rent, FEATURE_ENABLED_SZ ); + + /* Set up feature gate accounts */ + for( ulong j=0UL; jaccounts[ feature_gate_idx+j ]; + + pair->key = feature_gates[ j ]; + pair->account = (fd_solana_account_t) { + .lamports = default_feature_enabled_balance, + .data_len = FEATURE_ENABLED_SZ, + .data = (uchar *)feature_enabled_data, + .owner = fd_solana_feature_program_id, + .rent_epoch = 0UL, }; } +#undef FEATURE_ENABLED_SZ /* Sort and check for duplicates */ @@ -262,11 +284,13 @@ genesis_create( void * buf, } ulong -fd_genesis_create( void * buf, - ulong bufsz, - uchar const * pod ) { +fd_genesis_create( void * buf, + ulong bufsz, + fd_genesis_options_t const * options, + fd_pubkey_t const * feature_gates, + ulong feature_gate_cnt ) { fd_scratch_push(); - ulong ret = genesis_create( buf, bufsz, pod ); + ulong ret = genesis_create( buf, bufsz, options, feature_gates, feature_gate_cnt ); fd_scratch_pop(); return ret; } diff --git a/src/flamenco/genesis/fd_genesis_create.h b/src/flamenco/genesis/fd_genesis_create.h index 29b293868a..4af6cafcb4 100644 --- a/src/flamenco/genesis/fd_genesis_create.h +++ b/src/flamenco/genesis/fd_genesis_create.h @@ -6,13 +6,38 @@ #include "../fd_flamenco_base.h" + +/* fd_genesis_options_t exists as a convenient way to specify options + for genesis creation. */ + +struct fd_genesis_options { + fd_pubkey_t identity_pubkey; + fd_pubkey_t faucet_pubkey; + fd_pubkey_t stake_pubkey; + fd_pubkey_t vote_pubkey; + + ulong creation_time; /* unix time, i.e. seconds since the unix epoch */ + ulong faucet_balance; /* in lamports */ + + ulong hashes_per_tick; /* 0 means unset */ + ulong ticks_per_slot; + ulong target_tick_duration_micros; + + ulong fund_initial_accounts; + ulong fund_initial_amount_lamports; +}; + +typedef struct fd_genesis_options fd_genesis_options_t; + FD_PROTOTYPES_BEGIN /* fd_genesis_create creates a 'genesis.bin' compatible genesis blob. (Bincode encoded fd_genesis_solana_t) [buf,bufsz) it the output - memory region into which the genesis blob will be written. pod - points to an fd_pod containing the genesis configuration parameters. - (Refer to fd_genesis.c code for the pod layout, there are no docs.) + memory region into which the genesis blob will be written. options + points to a struct containing the genesis configuration parameters. + Additionally, the feature gates corresponding to the pubkeys + feature_gates[ i ] for i in [0, feature_gate_cnt) will be active from + genesis. feature_gates==NULL is okay if feature_gate_cnt==0. Returns the number of bytes in the output memory region used on success. On failure, returns 0UL and logs reason for error. @@ -24,9 +49,11 @@ FD_PROTOTYPES_BEGIN It is intended for development only. */ ulong -fd_genesis_create( void * buf, - ulong bufsz, - uchar const * pod ); +fd_genesis_create( void * buf, + ulong bufsz, + fd_genesis_options_t const * options, + fd_pubkey_t const * feature_gates, + ulong feature_gate_cnt ); /* TODO Add method to estimate the scratch and genesis blob size given a pod */ diff --git a/src/flamenco/genesis/test_genesis_create.c b/src/flamenco/genesis/test_genesis_create.c index ced20524d1..f61ca74cbf 100644 --- a/src/flamenco/genesis/test_genesis_create.c +++ b/src/flamenco/genesis/test_genesis_create.c @@ -18,37 +18,21 @@ main( int argc, fd_scratch_attach( scratch_smem, scratch_fmem, sizeof(scratch_smem), sizeof(scratch_fmem)/sizeof(ulong) ); - static uchar pod_mem[ 8192 ]; - uchar * pod = fd_pod_join( fd_pod_new( pod_mem, sizeof(pod_mem) ) ); /* Minimal configuration */ - - FD_TEST( !fd_genesis_create( NULL, 0UL, pod ) ); - fd_pubkey_t identity_pubkey = { .ul = { 0, 0, 0, 1 } }; - fd_pod_insert_pubkey( pod, "identity.pubkey", &identity_pubkey ); - - FD_TEST( !fd_genesis_create( NULL, 0UL, pod ) ); - fd_pubkey_t faucet_pubkey = { .ul = { 0, 0, 0, 2 } }; - fd_pod_insert_pubkey( pod, "faucet.pubkey", &faucet_pubkey ); - - FD_TEST( !fd_genesis_create( NULL, 0UL, pod ) ); - fd_pubkey_t stake_pubkey = { .ul = { 0, 0, 0, 3 } }; - fd_pod_insert_pubkey( pod, "stake.pubkey", &stake_pubkey ); - - FD_TEST( !fd_genesis_create( NULL, 0UL, pod ) ); - fd_pubkey_t vote_pubkey = { .ul = { 0, 0, 0, 4 } }; - fd_pod_insert_pubkey( pod, "vote.pubkey", &vote_pubkey ); - - FD_TEST( !fd_genesis_create( NULL, 0UL, pod ) ); - fd_pod_insert_ulong( pod, "creation_time", 123UL ); - fd_pod_insert_ulong( pod, "ticks_per_slot", 64UL ); - - FD_TEST( !fd_genesis_create( NULL, 0UL, pod ) ); - fd_pod_insert_ulong( pod, "target_tick_µs", 6250UL ); + fd_genesis_options_t options[1] = {{ + .identity_pubkey = { .ul = { 0, 0, 0, 1 } }, + .faucet_pubkey = { .ul = { 0, 0, 0, 2 } }, + .stake_pubkey = { .ul = { 0, 0, 0, 3 } }, + .vote_pubkey = { .ul = { 0, 0, 0, 4 } }, + .creation_time = 123UL, + .ticks_per_slot = 64UL, + .target_tick_duration_micros = 6250UL + }}; /* Buffer too small */ - FD_TEST( !fd_genesis_create( NULL, 0UL, pod ) ); + FD_TEST( !fd_genesis_create( NULL, 0UL, options, NULL, 0UL ) ); /* No more warnings expected */ @@ -57,19 +41,17 @@ main( int argc, /* Serialize to buffer */ static uchar result_mem[ BUFSZ ]; - ulong result_sz = fd_genesis_create( result_mem, sizeof(result_mem), pod ); + ulong result_sz = fd_genesis_create( result_mem, sizeof(result_mem), options, NULL, 0UL ); FD_TEST( result_sz ); /* Now try adding a few accounts */ - fd_pod_insert_ulong( pod, "default_funded.cnt", 16UL ); - result_sz = fd_genesis_create( result_mem, sizeof(result_mem), pod ); + options->fund_initial_accounts = 16UL; + result_sz = fd_genesis_create( result_mem, sizeof(result_mem), options, NULL, 0UL ); FD_TEST( result_sz ); /* TODO load this into a Firedancer runtime and verify the resulting slot context */ - FD_TEST( fd_pod_delete( fd_pod_leave ( pod ) )==pod_mem ); - FD_LOG_NOTICE(( "pass" )); fd_scratch_detach( NULL );