Merge pull request #655 from vss96/Limit-Script-Size

This commit is contained in:
Dr. Maxim Orlovsky 2021-09-16 10:42:08 +02:00 committed by GitHub
commit b7f984972a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 6 deletions

View File

@ -58,6 +58,8 @@ pub const SCRIPT_ADDRESS_PREFIX_MAIN: u8 = 5; // 0x05
pub const PUBKEY_ADDRESS_PREFIX_TEST: u8 = 111; // 0x6f pub const PUBKEY_ADDRESS_PREFIX_TEST: u8 = 111; // 0x6f
/// Test (tesnet, signet, regtest) script address prefix. /// Test (tesnet, signet, regtest) script address prefix.
pub const SCRIPT_ADDRESS_PREFIX_TEST: u8 = 196; // 0xc4 pub const SCRIPT_ADDRESS_PREFIX_TEST: u8 = 196; // 0xc4
/// The maximum allowed script size.
pub const MAX_SCRIPT_ELEMENT_SIZE: usize = 520;
/// In Bitcoind this is insanely described as ~((u256)0 >> 32) /// In Bitcoind this is insanely described as ~((u256)0 >> 32)

View File

@ -44,7 +44,7 @@ use bech32;
use hashes::Hash; use hashes::Hash;
use hash_types::{PubkeyHash, WPubkeyHash, ScriptHash, WScriptHash}; use hash_types::{PubkeyHash, WPubkeyHash, ScriptHash, WScriptHash};
use blockdata::{script, opcodes}; use blockdata::{script, opcodes};
use blockdata::constants::{PUBKEY_ADDRESS_PREFIX_MAIN, SCRIPT_ADDRESS_PREFIX_MAIN, PUBKEY_ADDRESS_PREFIX_TEST, SCRIPT_ADDRESS_PREFIX_TEST}; use blockdata::constants::{PUBKEY_ADDRESS_PREFIX_MAIN, SCRIPT_ADDRESS_PREFIX_MAIN, PUBKEY_ADDRESS_PREFIX_TEST, SCRIPT_ADDRESS_PREFIX_TEST, MAX_SCRIPT_ELEMENT_SIZE};
use network::constants::Network; use network::constants::Network;
use util::base58; use util::base58;
use util::ecdsa; use util::ecdsa;
@ -71,6 +71,8 @@ pub enum Error {
InvalidSegwitV0ProgramLength(usize), InvalidSegwitV0ProgramLength(usize),
/// An uncompressed pubkey was used where it is not allowed. /// An uncompressed pubkey was used where it is not allowed.
UncompressedPubkey, UncompressedPubkey,
/// Address size more than 520 bytes is not allowed.
ExcessiveScriptSize
} }
impl fmt::Display for Error { impl fmt::Display for Error {
@ -91,6 +93,8 @@ impl fmt::Display for Error {
Error::UncompressedPubkey => write!(f, Error::UncompressedPubkey => write!(f,
"an uncompressed pubkey was used where it is not allowed", "an uncompressed pubkey was used where it is not allowed",
), ),
Error::ExcessiveScriptSize => write!(f,
"Script size exceed 520 bytes")
} }
} }
} }
@ -408,11 +412,14 @@ impl Address {
/// Creates a pay to script hash P2SH address from a script /// Creates a pay to script hash P2SH address from a script
/// This address type was introduced with BIP16 and is the popular type to implement multi-sig these days. /// This address type was introduced with BIP16 and is the popular type to implement multi-sig these days.
#[inline] #[inline]
pub fn p2sh(script: &script::Script, network: Network) -> Address { pub fn p2sh(script: &script::Script, network: Network) -> Result<Address, Error> {
Address { if script.len() > MAX_SCRIPT_ELEMENT_SIZE{
return Err(Error::ExcessiveScriptSize);
}
Ok(Address {
network: network, network: network,
payload: Payload::ScriptHash(ScriptHash::hash(&script[..])), payload: Payload::ScriptHash(ScriptHash::hash(&script[..])),
} })
} }
/// Create a witness pay to public key address from a public key /// Create a witness pay to public key address from a public key
@ -820,13 +827,18 @@ mod tests {
#[test] #[test]
fn test_p2sh_parse() { fn test_p2sh_parse() {
let script = hex_script!("552103a765fc35b3f210b95223846b36ef62a4e53e34e2925270c2c7906b92c9f718eb2103c327511374246759ec8d0b89fa6c6b23b33e11f92c5bc155409d86de0c79180121038cae7406af1f12f4786d820a1466eec7bc5785a1b5e4a387eca6d797753ef6db2103252bfb9dcaab0cd00353f2ac328954d791270203d66c2be8b430f115f451b8a12103e79412d42372c55dd336f2eb6eb639ef9d74a22041ba79382c74da2338fe58ad21035049459a4ebc00e876a9eef02e72a3e70202d3d1f591fc0dd542f93f642021f82102016f682920d9723c61b27f562eb530c926c00106004798b6471e8c52c60ee02057ae"); let script = hex_script!("552103a765fc35b3f210b95223846b36ef62a4e53e34e2925270c2c7906b92c9f718eb2103c327511374246759ec8d0b89fa6c6b23b33e11f92c5bc155409d86de0c79180121038cae7406af1f12f4786d820a1466eec7bc5785a1b5e4a387eca6d797753ef6db2103252bfb9dcaab0cd00353f2ac328954d791270203d66c2be8b430f115f451b8a12103e79412d42372c55dd336f2eb6eb639ef9d74a22041ba79382c74da2338fe58ad21035049459a4ebc00e876a9eef02e72a3e70202d3d1f591fc0dd542f93f642021f82102016f682920d9723c61b27f562eb530c926c00106004798b6471e8c52c60ee02057ae");
let addr = Address::p2sh(&script, Testnet); let addr = Address::p2sh(&script, Testnet).unwrap();
assert_eq!(&addr.to_string(), "2N3zXjbwdTcPsJiy8sUK9FhWJhqQCxA8Jjr"); assert_eq!(&addr.to_string(), "2N3zXjbwdTcPsJiy8sUK9FhWJhqQCxA8Jjr");
assert_eq!(addr.address_type(), Some(AddressType::P2sh)); assert_eq!(addr.address_type(), Some(AddressType::P2sh));
roundtrips(&addr); roundtrips(&addr);
} }
#[test]
fn test_p2sh_parse_for_large_script(){
let script = hex_script!("552103a765fc35b3f210b95223846b36ef62a4e53e34e2925270c2c7906b92c9f718eb2103c327511374246759ec8d0b89fa6c6b23b33e11f92c5bc155409d86de0c79180121038cae7406af1f12f4786d820a1466eec7bc5785a1b5e4a387eca6d797753ef6db2103252bfb9dcaab0cd00353f2ac328954d791270203d66c2be8b430f115f451b8a12103e79412d42372c55dd336f2eb6eb639ef9d74a22041ba79382c74da2338fe58ad21035049459a4ebc00e876a9eef02e72a3e70202d3d1f591fc0dd542f93f642021f82102016f682920d9723c61b27f562eb530c926c00106004798b6471e8c52c60ee02057ae12123122313123123ac1231231231231313123131231231231313212313213123123552103a765fc35b3f210b95223846b36ef62a4e53e34e2925270c2c7906b92c9f718eb2103c327511374246759ec8d0b89fa6c6b23b33e11f92c5bc155409d86de0c79180121038cae7406af1f12f4786d820a1466eec7bc5785a1b5e4a387eca6d797753ef6db2103252bfb9dcaab0cd00353f2ac328954d791270203d66c2be8b430f115f451b8a12103e79412d42372c55dd336f2eb6eb639ef9d74a22041ba79382c74da2338fe58ad21035049459a4ebc00e876a9eef02e72a3e70202d3d1f591fc0dd542f93f642021f82102016f682920d9723c61b27f562eb530c926c00106004798b6471e8c52c60ee02057ae12123122313123123ac1231231231231313123131231231231313212313213123123552103a765fc35b3f210b95223846b36ef62a4e53e34e2925270c2c7906b92c9f718eb2103c327511374246759ec8d0b89fa6c6b23b33e11f92c5bc155409d86de0c79180121038cae7406af1f12f4786d820a1466eec7bc5785a1b5e4a387eca6d797753ef6db2103252bfb9dcaab0cd00353f2ac328954d791270203d66c2be8b430f115f451b8a12103e79412d42372c55dd336f2eb6eb639ef9d74a22041ba79382c74da2338fe58ad21035049459a4ebc00e876a9eef02e72a3e70202d3d1f591fc0dd542f93f642021f82102016f682920d9723c61b27f562eb530c926c00106004798b6471e8c52c60ee02057ae12123122313123123ac1231231231231313123131231231231313212313213123123");
assert_eq!(Address::p2sh(&script, Testnet), Err(Error::ExcessiveScriptSize));
}
#[test] #[test]
fn test_p2wpkh() { fn test_p2wpkh() {
// stolen from Bitcoin transaction: b3c8c2b6cfc335abbcb2c7823a8453f55d64b2b5125a9a61e8737230cdb8ce20 // stolen from Bitcoin transaction: b3c8c2b6cfc335abbcb2c7823a8453f55d64b2b5125a9a61e8737230cdb8ce20