Last active
August 11, 2018 13:16
-
-
Save sorpaas/27b8026c40e4777ede889c40e3824a04 to your computer and use it in GitHub Desktop.
Brute Force Approach to EIP-1087/EIP-1283 Equivalence "Proof"
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#[derive(Debug)] | |
struct Consumption { | |
used: usize, | |
refund: usize, | |
} | |
impl Consumption { | |
pub fn absolute(&self) -> isize { | |
self.used as isize - self.refund as isize | |
} | |
} | |
fn eip1283(chain: &[usize]) -> Consumption { | |
let mut consumption = Consumption { | |
used: 0, | |
refund: 0, | |
}; | |
let original = chain[0]; | |
for i in 0..(chain.len()-1) { | |
let current = chain[i]; | |
let new = chain[i+1]; | |
if current == new { | |
consumption.used += 200; | |
} else { | |
if original == current { | |
if original == 0 { | |
consumption.used += 20000; | |
} else { | |
consumption.used += 5000; | |
if new == 0 { | |
consumption.refund += 15000; | |
} | |
} | |
} else { | |
consumption.used += 200; | |
if original != 0 { | |
if current == 0 { | |
consumption.refund -= 15000; | |
} else if new == 0 { | |
consumption.refund += 15000; | |
} | |
} | |
if original == new { | |
if original == 0 { | |
consumption.refund += 19800; | |
} else { | |
consumption.refund += 4800; | |
} | |
} | |
} | |
} | |
} | |
consumption | |
} | |
fn eip1087(chain: &[usize]) -> Consumption { | |
let mut consumption = Consumption { | |
used: 0, | |
refund: 0, | |
}; | |
let original = chain[0]; | |
let mut dirty = false; | |
for i in 0..(chain.len()-1) { | |
let current = chain[i]; | |
let new = chain[i+1]; | |
if current == new { | |
consumption.used += 200; | |
continue; | |
} | |
if dirty { | |
consumption.used += 200; | |
} else { | |
dirty = true; | |
if original == 0 { | |
consumption.used += 20000; | |
} else { | |
consumption.used += 5000; | |
} | |
} | |
} | |
let last = chain[chain.len()-1]; | |
if dirty { | |
if original == 0 && last == 0 { | |
consumption.refund += 19800; | |
} else if original != 0 && original == last { | |
consumption.refund += 4800; | |
} else if original != 0 && last == 0 { | |
consumption.refund += 15000; | |
} | |
} | |
consumption | |
} | |
fn current(chain: &[usize]) -> Consumption { | |
let mut consumption = Consumption { | |
used: 0, | |
refund: 0, | |
}; | |
for i in 0..(chain.len()-1) { | |
let current = chain[i]; | |
let new = chain[i+1]; | |
consumption.used += if new != 0 && current == 0 { | |
20000 | |
} else { | |
5000 | |
}; | |
consumption.refund += if new == 0 && current != 0 { | |
15000 | |
} else { | |
0 | |
}; | |
} | |
consumption | |
} | |
fn build_chain(mut index: usize) -> [usize; 10] { | |
let mut chain = [0; 10]; | |
let mut chain_index = 0; | |
while index > 0 { | |
chain[chain_index] = index % 4; | |
index = index / 4; | |
chain_index += 1; | |
} | |
chain | |
} | |
fn main() { | |
println!("eip1283: {:?}", eip1283(&[0, 1, 0, 1, 0])); | |
println!("eip1087: {:?}", eip1087(&[0, 1, 0, 1, 0])); | |
println!("current: {:?}", current(&[0, 1, 0, 1, 0])); | |
for i in 0..(4usize.pow(10)-1) { | |
let chain = build_chain(i); | |
// println!("{:?}, eip1283: {:?}, eip1087: {:?}", chain, eip1283(&chain), eip1087(&chain)); | |
assert_eq!(eip1283(&chain).absolute(), eip1087(&chain).absolute()); | |
// Check that in all cases, we never cost most gases compared | |
// to what we have right now. | |
assert!(eip1283(&chain).used <= current(&chain).used); | |
if i % 1000 == 0 { | |
println!("Tested {} cases to be matching!", i); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment